前言
今天的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("\nRunning 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