First time play with JavaCV/OpenCV to detect faces

本文介绍了如何在Windows环境下安装JavaCV及其依赖OpenCV,并通过一个面部检测示例程序演示了如何使用JavaCV进行基本的图像处理任务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 requires OpenCV 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.



以下是一个Java程序,它可以使用OpenCV库来测量右下颌角的角度。 ```java import org.opencv.core.*; import org.opencv.imgcodecs.Imgcodecs; import org.opencv.imgproc.Imgproc; import org.opencv.objdetect.CascadeClassifier; public class JawAngleMeasurement { public static void main(String[] args) { // Load the OpenCV library System.loadLibrary(Core.NATIVE_LIBRARY_NAME); // Load the image Mat image = Imgcodecs.imread("path/to/image.jpg"); // Convert the image to grayscale Mat grayImage = new Mat(); Imgproc.cvtColor(image, grayImage, Imgproc.COLOR_BGR2GRAY); // Load the cascade classifier for detecting faces CascadeClassifier faceDetector = new CascadeClassifier("path/to/haarcascade_frontalface_default.xml"); // Detect faces in the image MatOfRect faceDetections = new MatOfRect(); faceDetector.detectMultiScale(grayImage, faceDetections); // Get the first face detection (assuming there is only one face in the image) Rect face = faceDetections.toArray()[0]; // Extract the region of interest (ROI) corresponding to the lower part of the face int x = face.x; int y = (int) (face.y + face.height * 0.6); int width = face.width; int height = (int) (face.height * 0.4); Rect jawROI = new Rect(x, y, width, height); Mat jawImage = new Mat(grayImage, jawROI); // Threshold the jaw image to obtain a binary image Mat binaryImage = new Mat(); Imgproc.threshold(jawImage, binaryImage, 0, 255, Imgproc.THRESH_BINARY_INV | Imgproc.THRESH_OTSU); // Find the contours in the binary image Mat contoursImage = new Mat(); binaryImage.copyTo(contoursImage); Mat hierarchy = new Mat(); MatOfPoint2f maxContour = new MatOfPoint2f(); Imgproc.findContours(contoursImage, new ArrayList<>(), hierarchy, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); double maxArea = 0; for (MatOfPoint contour : contours) { MatOfPoint2f contour2f = new MatOfPoint2f(contour.toArray()); double area = Imgproc.contourArea(contour2f); if (area > maxArea) { maxArea = area; contour2f.convertTo(maxContour, CvType.CV_32FC2); } } // Fit an ellipse to the max contour RotatedRect ellipse = Imgproc.fitEllipse(maxContour); // Get the angle of the major axis of the ellipse double angle = ellipse.angle; if (angle < -45) { angle += 90; } // Print the angle System.out.println("Right jaw angle: " + angle); } } ``` 请注意,此程序假定图像中只有一个人脸,并且只测量右下颌角的角度。如果需要在多个人脸中测量右下颌角的角度,您需要修改程序以在每个人脸上运行相同的算法。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值