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包中获得流资源却非常容易)。这个问题以后还要持续关注。
原文地址:http://blog.csdn.net/shuzhe66/article/details/40787587