前言
今天的30天挑战,我决定学习怎样用Java实现人脸识别。人脸识别有助于识别任意(数字)图像中的人脸。搜索调查一番后,我发现OpenCV库可以有助于在图像中检测人脸。但是我没找到给Java开发者使用OpenCV库的入门指导,这篇博客也许对要找相关介绍的人有用。
什么是OpenCV?
OpenCV(Open Source Computer Vision)是一个开源的计算机视觉算法库,用C/C++编写,设计为发挥多核心优势,提供C++, C, Python和Java接口,支持所有主流系统如Windows, Linux, Mac OS, iOS 和Android.
Github 仓库
今天的domo放在github: day12-face-detection.
开始OpenCV
要开始OpenCV, 先要从官网下载最新的OpenCV包到本地,这里我用版本2.4.7.
下载好后,用以下方式解压。
$ tar xvf opencv-2.4.7.tar.gz
路径换到Opencv-2.4.7
$ cd opencv-2.4.7
构建OpenCV jar
我花了好多时间来理解怎样得到OpenCV jar文件。Java介绍文档里说OpenCV jar在build文件夹里,对于Windows用户来说是的,但是Linux和Mac OS不是,要构建OpenCV jar,执行以下命令。
$ cd opencv-2.4.7 $ mkdir build $ cd build/ $ cmake -G "Unix Makefiles" -D CMAKE_CXX_COMPILER=/usr/bin/g++ -D CMAKE_C_COMPILER=/usr/bin/gcc -D WITH_CUDA=ON .. $make -j4 $ make install
以上命令会在opencv-2.4.7/build/bin路径下创建opencv-247.jar文件,是Java绑定到原生安装的OpenCV.
下载Eclipse
如果你还没安装Eclipse,到官网下载最新版本,目前最新版本叫Kepler.
安装Eclipse很简单,只需解压下载的安装包。在linux或者mac上,打开命令管理器输入以下命令。
$ tar -xzvf eclipse-jee-kepler-R-*.tar.gz
Windows上可以用7-zip或者其他解压工具解压,解压后,在你解压的路径会有一个eclipse的文件夹,可以给可执行文件创建快捷键。
添加用户库
打开Eclipse IDE导航到项目区,从Windows > Preferences > Java > Build Path > User Libraries, 选择添加新库。
命名openCV-2.4.7点OK.
点击Add External Jars,选择opencv-247.jar.
选择Native library location点击Edit.
点击External Folder
指定opencv-2.4.7/build/lib下的lib路径。
最后点击OK, 现在就成功添加OpenCV 用户库了。
新建Java项目
通过File > New > Other > Java新建Java项目,创建后,右击项目配置build路径。
到Libraries页,点击Add Library.
选择User Library.
选择上一步添加的OpenCV-2.4.7用户库,点击Finish.
最后,Java项目会包括OpenCV-2.4.7用户库。
写人脸识别
在上一步添加的项目里添加新类,加入以下代码。
package com.shekhar.facedetection; import org.opencv.core.Core; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; import org.opencv.core.Point; import org.opencv.core.Rect; import org.opencv.core.Scalar; import org.opencv.highgui.Highgui; import org.opencv.objdetect.CascadeClassifier; public class FaceDetector { public static void main(String[] args) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); System.out.println(" Running FaceDetector"); CascadeClassifier faceDetector = new CascadeClassifier(FaceDetector.class.getResource("haarcascade_frontalface_alt.xml").getPath()); Mat image = Highgui .imread(FaceDetector.class.getResource("shekhar.JPG").getPath()); 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 = "ouput.png"; System.out.println(String.format("Writing %s", filename)); Highgui.imwrite(filename, image); } }
以上代码做了以下动作:
- 加载原生OpenCV库以便引用Java API.
- 创建一个CascadeClassifier实例传递加载的分类器的文件名。
- 然后把图片转换成Java API用Highui类能接受的格式,Mat是OpenCV C++的N维密集数组。
- 然后在分类器上调用detectMultiScale方法传递图片和MatOfRect对象,之后,MatOfRect就会有认识检测功能。
- 递归所有的人脸检测并把图片标识成矩形。
- 最后生成output.png图片文件。
显示如下,这是我的检测前后的图片。
这是今天的内容,继续给反馈吧。
原文:https://www.openshift.com/blogs/day-12-opencv-face-detection-for-java-developers