First time play with JavaCV/OpenCV to detect faces

JavaCV(http://code.google.com/p/javacv/) is a java wrapper of OpenCV (http://opencv.willowgarage.com/). Because it is just a java wrapper, it is necessary to install opencv as a prerequisite. As of this writing, javaCV requiresOpenCV 2.3. Here is how to prepare the whole setup before we get to play with javaCV a moment later:

1) download and install OpenCV 2.3, we assume it is installed on C:\OpenCV2.3;

2) copy all files opencv_* on C:\OpenCV2.3\build\x86\vc10\bin to %SYSTEM32%, so JNA or JNI can access the dynamic libraries. These dll libraries are the dependencies of JavaCV;

3) download and install JavaCV file javacv-bin-20110705.zip from http://code.google.com/p/javacv/, we assume it is installed on C:\JavaCV.

Now all libraries and files are in place, we will try to set up a sample java project. Here is how to do it:

In Eclipse, create a java project named "JavaCVApp". Under the project, create a directory named lib, and import the following jars to lib directory: (I use 32-bit Windows, so the above opencv dll files are from x86 directory instead of x64 directory. It is essential to keep opencv and javacv architecture-compatible.)

C:\JavaCV\javacv-bin\javacv.jar; javacv-windows-x86.jar; javacpp.jar 

After that, set the project "JavaCVApp"'s java build path in Eclipse by adding those jars from the directory "lib".

When the setup is complete, we will come to the fun part to test JavaCV, that is, to create a java program called FaceDetection.java and run it. Copy & Paste the following code to the JavaCVApp project: (Note: This following code is got from http://tkgospodinov.com/computer-vision-face-detection-in-java-with-opencv-using-javacv/ with some small changes to make it work with the latest version of JavaCV).

import static com.googlecode.javacv.cpp.opencv_core.CV_AA;
import static com.googlecode.javacv.cpp.opencv_core.IPL_DEPTH_8U;
import static com.googlecode.javacv.cpp.opencv_core.cvGetSeqElem;
import static com.googlecode.javacv.cpp.opencv_core.cvLoad;
import static com.googlecode.javacv.cpp.opencv_core.cvPoint;
import static com.googlecode.javacv.cpp.opencv_core.cvRectangle;
import static com.googlecode.javacv.cpp.opencv_highgui.cvLoadImage;
import static com.googlecode.javacv.cpp.opencv_highgui.cvSaveImage;
import static com.googlecode.javacv.cpp.opencv_imgproc.CV_BGR2GRAY;
import static com.googlecode.javacv.cpp.opencv_imgproc.cvCvtColor;
import static com.googlecode.javacv.cpp.opencv_objdetect.cvHaarDetectObjects;

import com.googlecode.javacv.cpp.opencv_core.CvMemStorage;
import com.googlecode.javacv.cpp.opencv_core.CvRect;
import com.googlecode.javacv.cpp.opencv_core.CvScalar;
import com.googlecode.javacv.cpp.opencv_core.CvSeq;
import com.googlecode.javacv.cpp.opencv_core.IplImage;
import com.googlecode.javacv.cpp.opencv_objdetect.CvHaarClassifierCascade;

public class FaceDetection {

	// The cascade definition to be used for detection.
	private static final String CASCADE_FILE = "C:\\OpenCV2.3\\opencv\\data\\haarcascades\\haarcascade_frontalface_alt.xml";

	public static void main(String arg[]) throws Exception {
		

		// Load the original image.
		IplImage originalImage = cvLoadImage("c:\\tmp\\churchill-roosevelt-stalin-yalta.jpg",1);

		// We need a grayscale image in order to do the recognition, so we
		// create a new image of the same size as the original one.
		IplImage grayImage = IplImage.create(originalImage.width(),
				originalImage.height(), IPL_DEPTH_8U, 1);

		// We convert the original image to grayscale.
		 cvCvtColor(originalImage, grayImage, CV_BGR2GRAY);

		CvMemStorage storage = CvMemStorage.create();

		// We instantiate a classifier cascade to be used for detection, using
		// the cascade definition.
		CvHaarClassifierCascade cascade = new CvHaarClassifierCascade(
				cvLoad(CASCADE_FILE));

		// We detect the faces.
		CvSeq faces = cvHaarDetectObjects(grayImage, cascade, storage, 1.1, 1,
				0);

		// We iterate over the discovered faces and draw yellow rectangles
		// around them.
		for (int i = 0; i < faces.total(); i++) {
			CvRect r = new CvRect(cvGetSeqElem(faces, i));
			cvRectangle(originalImage, cvPoint(r.x(), r.y()),
					cvPoint(r.x() + r.width(), r.y() + r.height()),
					CvScalar.YELLOW, 1, CV_AA, 0);

		}

		// Save the image to a new file.
		cvSaveImage("c:\\tmp\\churchill-roosevelt-stalin-yalta_new.jpg", originalImage);

	}

}

Without much hassle, i've just hard coded the jpg file path in the above code. Now run it, we got the detected faces in the picture. Athough Stalin's face is not recognized (because of his hat?), the overall result is exciting.  To dive into JavaCV or OpenCV deeper, go to http://opencv.willowgarage.com/documentation/cpp/index.html.


posted @ 2011-08-05 18:41  ljsspace  阅读(2488)  评论(1编辑  收藏  举报