首页 > 代码库 > OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别


[简介]

        我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子。之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,“图像识别”算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望。

        通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置的匹配模式与算法,得到图像中的人脸位置,这与在腾讯空间中流行的图片识别过程类似。


[实例:人脸识别]

英文原版程序可以在这里找到,注意修改版本号和文件路径:opencv.org

项目目录结构如下:


我没有采用原版中直接按照类的包格式进行资源的引用,而是创建了Data与Result两个目录用来存放原与结果,这样输出更方便一些。

lbpcascade_frontalface.xml可以从OpenCV库的解压路径下sources\data\lbpcascades找到。

CVMain.java:

public class CVMain {
	public static void main(String[] args) throws InterruptedException {
		System.loadLibrary("opencv_java249");
		new FaceDetector().run();
	}
}
FaceDetector:

public class FaceDetector {
	public void run(){
		CascadeClassifier faceDetector = new CascadeClassifier("./Data/lbpcascade_frontalface.xml");
		Mat image = Highgui.imread("./Data/haha.jpg");
		MatOfRect faceDetections = new MatOfRect();
		faceDetector.detectMultiScale(image, faceDetections);

		System.out.println(String.format("Detected %s faces",
				faceDetections.toArray().length));
		for (Rect rect : faceDetections.toArray()) {
			Core.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x
					+ rect.width, rect.y + rect.height), new Scalar(0, 255, 0));
		}

		String filename = "./Result/FaceDetect.png";
		System.out.println(String.format("Writing %s", filename));
		Highgui.imwrite(filename, image);
	}
}

我输入的图片:


程序输出结果:


↑对于完整的人脸,识别率非常高,但有时也会出现意外,例如上图中史密斯先生的耳朵被识别为一张脸(放大一看确实有点像人脸),大家有兴趣可以拿自己毕业照之类的合照来测试一下。


[总结]

        这个问题解决的很方便,我们没有触及任何识别算法的事情,只是给出图片、获得结果这样直截了当。我希望以后至少能够掌握匹配模式设定的一些知识,尝试使用这套结构去解决先前数橘子的问题。

        还有一个值得注意到的问题,OpenCV的API似乎直接从文件路径进行的支持,按照Java开发的原则,流封装应该优先于文件,如果直接对文件路径进行封装,那么将项目打包后对jar中资源的引用将会非常麻烦(但从jar包中获得流资源却非常容易)。这个问题以后还要持续关注。

OpenCV学习笔记[3]Java Demo人脸识别