This semester, I want to get more comfortable with functional programming languages, so I'll be recording my progress through the course I'm taking this semester, Computer Vision. I know some Haskell and F# and I am opportunistic with functional aspects in Python, but there is still much I do not know about FP. I run Arch Linux on a Thinkpad for these projects.
Why Use Scala: Scala is a strongly typed functional and object-oriented programming language that utilizes the JVM. Scala allows writing powerful functional code while having access to all the tools in Java such as Apache Software. Overall, Scala has the potential to be powerful for data processing and engineering.
Unfortunately, Scala tutorials are much more sparse than languages like Python. Thus, I want to record my progress with this language.
First: Scala and SBT
SBT is the tool that allows us to manage Scala projects:
sudo pacman -S scala sbt
If you're running Arch Linux, install scrot so we can take screenshots:
sudo pacman -S scrot
For this assignment, we will install OpenCV, take a selfie, and record a video using Scala.
Recording Video With JavaCV
Create a folder and initialize your SBT project. Download the hello world template and name your project whatever you like:
sbt new scala/helloworld.g8
Run SBT and type ~run. You should see:
[info] Compilation completed in 11.595s.
[info] running Main
Hello, World!
[success] Total time: 76 s (01:16), completed Sep 1, 2020, 3:09:58 PM
[info] 1. Monitoring source files for computervisionhw1/run...
[info] Press to interrupt or '?' for more options.
Configure build.sbt
Since OpenCV is written in C++, we need a Java wrapper: JavaCV.
scalaVersion := "2.13.1"
name := "hello-world"
organization := "ch.epfl.scala"
version := "1.0"
libraryDependencies += "org.typelevel" %% "cats-core" % "2.0.0"
libraryDependencies += "org.bytedeco" % "javacv-platform" % "1.5.3"
If versions are correct, you should get no errors.
Take a Selfie and Record Video
import org.bytedeco.opencv.opencv_core._
import org.bytedeco.opencv.opencv_videoio.VideoCapture
import org.bytedeco.opencv.opencv_videoio.VideoWriter
import org.bytedeco.opencv.opencv_core.Size
import org.bytedeco.opencv.global.opencv_imgcodecs._
import org.bytedeco.opencv.global.opencv_highgui._
object Main extends App {
var imageArray = new Mat();
var videoDevice = new VideoCapture();
videoDevice.open(0);
if (videoDevice.isOpened()) {
// Take Selfie
videoDevice.read(imageArray);
imwrite("myselfie.jpg", imageArray);
// Video Writer
var videowriter = new VideoWriter(
"myvideooutput.avi",
VideoWriter.fourcc('M','J','P','G'),
10,
new Size(imageArray.arrayWidth, imageArray.arrayHeight)
);
for(i <- 1 to 100){
videoDevice.read(imageArray);
imshow("frame", imageArray);
videowriter.write(imageArray);
waitKey(1);
}
videowriter.release();
videoDevice.release();
destroyAllWindows();
} else {
println("Error, no camera found.");
}
}
Execute sbt run to test your results — it works!
I know this code isn't very in the spirit of functional programming. However, OpenCV is written in C++, so procedural code is necessary. This is actually a benefit of Scala: we can combine OOP from Java with functional syntax.