Thursday, December 26, 2013

Capture a Video from Webcam with JavaCV

Last post I told how crazy I was and why did I wanted put my hands on image processing. If you haven't read it yet try that first Getting Started with Opencv via Javacv. It is time to get start with some advanced stuffs. Don't get too much curious because I'm just getting started with this. Though we have used Webcam to capture a photos, main purpose of that is to get on video chat. So It means that we can record video from that. As I mentioned in my early post I have some experience with JMF to do that. But since now JMF is dead and we are dealing with my crazy idea it is better to try with JavaCV.
It is time that "You are being watched. The government has a secret system: a machine that spies on you every hour of every day" - Person of Interest
So I'm gonna tell you how to capture some videos from Webcam with JavaCV.
Lets get started. In-order to capture videos you must include appropriate ffmpeg...jar file to your class path. This can be found in the JavaCPP bundle that you already downloaded. Make sure you only include the suitable library version. That means if you are using x64 verison then used x64 version otherwise go with x86 version.

So all together we need following 4 libraries (Since I'm experiment using x64 here I mentioned latest x64 versions that I used)

  1. javacv.jar
  2. javacpp.jar
  3. opencv-2.4.6.0-windows-x86_64.jar
  4. ffmpeg-20130915-git-7ac6c63-windows-x86_64.jar

Create a new java class and have following code on that.

 import com.googlecode.javacv.CanvasFrame;  
 import com.googlecode.javacv.FFmpegFrameRecorder;  
 import com.googlecode.javacv.FrameGrabber;  
 import com.googlecode.javacv.FrameRecorder;  
 import com.googlecode.javacv.OpenCVFrameGrabber;  
 import com.googlecode.javacv.cpp.avutil;  
 import com.googlecode.javacv.cpp.opencv_core;  
 import java.util.logging.Level;  
 import java.util.logging.Logger;  

 class VideoTest {  
   public static void main(String[] args) {  
     try {  
       OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);  
       grabber.start();  
       opencv_core.IplImage grabbedImage = grabber.grab();  
       CanvasFrame canvasFrame = new CanvasFrame("Video with JavaCV");  
       canvasFrame.setCanvasSize(grabbedImage.width(), grabbedImage.height());  
       grabber.setFrameRate(grabber.getFrameRate());  

       FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("D:/Video/mytestvideo.mp4", grabber.getImageWidth(), grabber.getImageHeight());  // specify your path
       recorder.setFormat("mp4");  
       recorder.setFrameRate(30);  
       recorder.setVideoBitrate(10 * 1024 * 1024);  

       recorder.start();  
       while (canvasFrame.isVisible() && (grabbedImage = grabber.grab()) != null) {  
         canvasFrame.showImage(grabbedImage);  
         recorder.record(grabbedImage);  
       }  
       recorder.stop();  
       grabber.stop();  
       canvasFrame.dispose();  

     } catch (FrameGrabber.Exception ex) {  
       Logger.getLogger(VideoTest.class.getName()).log(Level.SEVERE, null, ex);  
     } catch (FrameRecorder.Exception ex) {  
       Logger.getLogger(VideoTest.class.getName()).log(Level.SEVERE, null, ex);  
     }  
   }  
 }  
Now compile and run this file. You can see that your camera get open and your beautiful face appearing on a window. Just wait for few seconds and close it. Then go to the file path that you specified. If you did everything as I mentioned you can see a video there. Run that from your favorite player.

you can see that I have set frame rate, bit rate and format as well. Try with different values and check what is get change. There are also some other parameters as well.

 recorder.setVideoQuality(videoQuality);  
 recorder.setVideoCodec(videoCodec);  
 recorder.setPixelFormat(pixelFormat);  

Try them as well. I'm didn't discuss how to detect face in this post. But don't get upset. It will be surely on next post.


Wednesday, December 25, 2013

Getting started with OpenCV via JavaCV

Couple of weeks back when I was watching Person of Interest's (My all time favorite TV show) latest episode I was getting a crazy idea of what if I can build a machine like that. (Of course it so damn crazy but seriously I got that feeling) Then I thought of why don't I give a try on some image processing stuffs that are heavily used in the so called "Machine".


I've never tried on image processing before. Even I didn't follow the course module at uni. So I started as most of us do Google it. But I didn't google it like 'Image processing for beginners'. I knew it is some what advanced stuffs and I didn't want to get touch with advanced stuffs with some languages that I have rarely used. So what I thought of was to try out image processing with Java first. As I mentioned earlier, since I was inspired by the Machine, I wanted to get started with my crazy idea by accessing webcam. I had some previous experience with JMF in 1st year project. But now JMF is almost a dead project. Therefore I had to look for something new. On my way I have found another couple of libraries that are used to access webcam via Java. But what caught my eyes was JavaCVI have heard about OpenCV but never tried that before. But this time it's with Java. So why to wait ;)

As some of you may know OpenCV is stands for Open source computer vision library. (I don't know how they shorten it to OpenCV) It was started my Intel way back in late 1990's
"OpenCV project was initially an Intel Research initiative to advance CPU-intensive applications, part of a series of projects including real-time ray tracing and 3D display walls." - wikipedia
"It has C++, C, Python, Java and MATLAB interfaces and supports Windows, Linux, Android and Mac OS. OpenCV leans mostly towards real-time vision applications and takes advantage of MMX and SSE instructions when available. A full-featured CUDA and OpenCL interfaces are being actively developed right now. There are over 500 algorithms and about 10 times as many functions that compose or support those algorithms. OpenCV is written natively in C++ and has a templated interface that works seamlessly with STL containers." - OpenCV developer team

I think that is enough about background and my nonsense. It is time to get touch with JavaCV.
In order to get start with JavaCV download following things to your machine

  1. JavaCV from https://code.google.com/p/javacv/downloads/list --> javacv-0.6-bin.zip
  2. OpenCV from http://sourceforge.net/projects/opencvlibrary/files/ install this to any place that you like 
  3. JavaCPP from https://code.google.com/p/javacv/downloads/detail?name=javacv-0.6-cppjars.zip

I'm working with Netbeans IDE so if you are not having it download and install it as well. But it is not necessary as long as you are OK with setting up class paths and stuffs when compiling and running.

First I'm going to show you how to capture a photo from your webcam and save it. I'm amusing that all are familiar with Netbeans.
First create a new Java project and add following libraries to your project

  1. javacv.jar
  2. javacpp.jar (These 2 can be found in JavaCV .zip file that you downloaded)
  3. opencv-2.4.6.1-..jar (Use the library that is appropriate to your pc. If you are having x64 machine then use x64 version) This can be found in the JavaCPP .zip file that you download
Then create a new java file and have following code in that
import com.googlecode.javacv.OpenCVFrameGrabber;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage; 
public class JavaCV {
   public static void main(String[] args) {
     OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(0);
     try {
       grabber.start();
       IplImage img = grabber.grab();
       if (img != null) {
         cvSaveImage("D:/Photos/capture.jpg", img); // give a path that you like
       }
       grabber.stop();
     } catch (Exception e) {
       e.printStackTrace();
     }
   }
 }

Now run this out. As you run the application you can see that your webcam get open and get close quickly. Check the path that you specified on the code and you can see a image being save there.