Video Capture in OpenIMAJ
Video capture from a webcam in Java is one of those things that is supposed to be easy, but isn’t. There are many libraries out there that try to provide support for video capture, but they all fall short. For example, JMF doesn’t support capture on a Mac, QuickTime for Java is deprecated and doesn’t support linux or 64-bit OSX/Windows, lti-civil is rather ancient and uses Quicktime for Java on the Mac (deprecated, no 64-bit), and doesn’t support 64-bit versions of other operating systems.
Our requirements for OpenIMAJ are seemingly rather simple:
- List the available video devices
- Open a device by name or identifier
- Grab images from the device
- Close the device
In addition, we want to be able to support both 64-bit and 32-bit Java Virtual Machines running under Linux, OSX and Windows, and would rather the user didn’t have to install anything (i.e. the video capture support must be self-contained in a jar file).
Unfortunately, we were unable to find any existing library that would allow us to do this, so we set about implementing our own capture support. The OpenIMAJ core-video-capture library is a 250kb jar file that fulfils all our requirements.
We constructed the core-video-capture library by writing a small dynamic native library for each platform and architecture (using c++) that exposes functions for the four requirements above. The native library uses the host operating systems current built in video capture framework (DirectShow on Windows, using the videoInput wrapper here; QTKit on Mac OSX; v4l2 on Linux). On the Java side we used the excellent bridj to bind the native code to a Java class. We packaged the native libraries as resources into the library jar. Finally, we added a small bit of static code in the Java class to determine the architecture and operating system, unpack the relevant native library to a temporary location and add it to the bridj library search path. The native library is set to be automatically removed when the JVM terminates.
Developers using core-video-capture should use the
org.openimaj.video.capture.VideoCapture class. The
org.openimaj.video.capture.OpenIMAJGrabber provides a lower-level interface to the native libraries.
Some tutorials using the VideoCapture class can be found on the wiki. There are also plenty of demos in the demos directory that use live video input.