Pascal Bakker

HomeLinksProjectsResume

How To Record a Video in Scala Using OpenCV

2020-09-01

technology, image_processing, scala


This semester, I want to get more comofortable 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 opportunist with functional aspects in Python, but there is still much I do not know about FP. I am run Arch Linux on a Thinkpad for these projects.

Why Use Scala: Scala a strongly typed functional and object oriented programming language that utilizes the JVM. Scala allows the ability to write 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 to manage our 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 then initalize your sbt project. Download the hello world layout and name your project whatever.

sbt new scala/helloworld.g8

Read this documentation to understand how sbt works. Run sbt and then type '~run' You should see the output:

[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.

Now we need to configure our build.sbt. Since OpenCV is written in C++ we will need to get a Java wrapper: JavaCV. [Maven Repo] [Documentation][Github]

build.sbt
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 your versions are correct, you should get no errors.

Now to take a selfie and record a video.

Main.scala
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); // String input for specific video, but since this is the camera, the parameter is 0
  if (videoDevice.isOpened()) {
      // Take Selfie
      videoDevice.read(imageArray);
      imwrite("myselfie.jpg", imageArray); // use imwrite func to write to file
      // To write a video, we will need to use the video writer class in javacv
      var videowriter = new VideoWriter("myvideooutput.avi", // output file name
                                        VideoWriter.fourcc('M','J','P','G') //codec used
                                        ,10 // fps
                                        ,new Size(imageArray.arrayWidth,imageArray.arrayHeight)); // frame size

      // Build video that is 100 frames
      val i = 0;
      for(i <- 1 to 100){
        videoDevice.read(imageArray);
        imshow("frame",imageArray); // display widow of video
        videowriter.write(imageArray);
        waitKey(1); // need to display image on window. 0 to pause after every frame, 1 or greater to play it
      }

      // Release objects
      videowriter.release();
      videoDevice.release();
      destroyAllWindows();
  } else {
      println("Error, no camera found.");
  }
}

execute sbt run. Lets me test my results...

It works!

I know this code isn't very in the spirit of functional programming. However, OpenCV is written in C++, so it is necessary to write procedural code. This is actually a benefit of Scala, that we can take the benifits of OOP in Java and combine it with functional syntax. Thats all for now!