2013/01/06からのアクセス回数 12939 正月休みに詳解OpenCVを読みました。機械学習とステレオグラフはさっと読飛ばしました。 OpenCVのインストール †MacOSの場合、MacPortsを使って以下のように簡単にインストールすることができました。+python27を追加したのは、OpenCV2.2から含まれたpythonインタフェースを試すためです。 $ sudo port install opencv +python27 詳解OpenCVのサンプルプログラムをコンパイル †以下のサイトから詳解OpenCVのサンプルプログラムをダウンロードしました。 http://examples.oreilly.com/9780596516130/LearningOpenCV_Code.zip サンプルプログラムのMakefileを修正 †サンプルに含まれているMakefile.txtではMacOSではコンパイルできないので、以下のようなMakefileを作成しました。残念ながらch5_ex5_1、ch9_backgroundAVG、ch9_backgroundDiff、ch10_ex10_1b_Horn_Schunckはうまくコンパイルできませんでしたが、他は正常に作成できました。 CXX = g++ LDFLAGS = -lopencv_legacy -lopencv_highgui -lopencv_core -lopencv_ml -lopencv_video -lopencv_imgproc -lopencv_calib3d -lopencv_objdetect -L/opt/local/lib CPPFLAGS = -I/opt/local/include/ -I/opt/local/include/opencv #ch5_ex5_1 \ #ch9_backgroundAVG \ #ch9_backgroundDiff \ #ch10_ex10_1b_Horn_Schunck \ all: ch2_ex2_1 ch2_ex2_2 ch2_ex2_3 ch2_ex2_4 ch2_ex2_5 ch2_ex2_6 ch2_ex2_7 \ ch2_ex2_8 ch2_ex2_9 ch2_ex2_10 ch3_ex3_3 ch3_ex3_4 ch3_ex3_5 ch3_ex3_9 \ ch3_ex3_11 ch3_ex3_12 ch3_ex3_13 ch3_ex3_14 ch3_ex3_15 ch3_ex3_17 ch3_ex3_19 \ ch3_ex3_20 ch4_ex4_1 ch4_ex4_2 ch4_ex4_3 ch5_ex5_2 ch5_ex5_3 ch5_ex5_4 \ ch6_ex6_1 ch6_ex6_2 ch6_ex6_3 ch6_ex6_4 ch6_ex6_5 \ ch7_ex7_1 ch7_ex7_3_expanded ch7_ex7_5_HistBackProj ch7_ex7_5 \ ch8_ex8_2 ch8_ex8_3 ch9_ex9_1 ch9_watershed \ ch10_ex10_1 ch10_motempl ch10_ex10_2 ch11_ex11_1 ch11_ex11_1_fromdisk \ ch12_ex12_1 ch12_ex12_2 ch12_ex12_3 ch12_ex12_4 ch13_ex13_1 \ ch13_ex13_2 ch13_ex13_3 ch13_ex13_4 お決まりの顔認識を試す †OpenCVと言えば、顔認識とイメージがあるので、以下のようなサンプルプルグラムでlena.jpgの顔を 認識させてみました。lena.jpgはネットからダウンロードしたものを使い、カスケードファイルは /opt/local/share/OpenCV/haarcascades/からコピーしてきました。 // http://www.aianet.ne.jp/~asada/prog_doc/opencv/opencv_obj_det_img.htm #include "cv.h" #include "highgui.h" // 顔検出(静止画) int main(int argc, char* argv[]) { // 顔検出対象の画像データ用 IplImage* tarImg; // 検出対象の画像ファイルパス char tarFilePath[] = "lena.jpg"; // 画像データの読み込み tarImg = cvLoadImage(tarFilePath, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); // 正面顔検出器の読み込み CvHaarClassifierCascade* cvHCC = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt.xml"); // 検出に必要なメモリストレージを用意する CvMemStorage* cvMStr = cvCreateMemStorage(0); // 検出情報を受け取るためのシーケンスを用意する CvSeq* face; // 画像中から検出対象の情報を取得する face = cvHaarDetectObjects(tarImg, cvHCC, cvMStr); for (int i = 0; i < face->total; i++) { // 検出情報から顔の位置情報を取得 CvRect* faceRect = (CvRect*)cvGetSeqElem(face, i); // 取得した顔の位置情報に基づき、矩形描画を行う cvRectangle(tarImg, cvPoint(faceRect->x, faceRect->y), cvPoint(faceRect->x + faceRect->width, faceRect->y + faceRect->height), CV_RGB(255, 0 ,0), 3, CV_AA); } // 顔位置に矩形描画を施した画像を表示 cvNamedWindow("face_detect"); cvShowImage("face_detect", tarImg); // キー入力待ち cvWaitKey(0); // ウィンドウの破棄 cvDestroyWindow("face_detect"); // 用意したメモリストレージを解放 cvReleaseMemStorage(&cvMStr); // カスケード識別器の解放 cvReleaseHaarClassifierCascade(&cvHCC); // イメージの解放 cvReleaseImage(&tarImg); return 0; } 実行すると、以下のようにlenaの顔が認識されます。 JavaCVに挑戦 †OpenCVで顔認識ができたので、今度はJavaからOpenCVを使ってみます。 JavaからOpenCVを利用するためのwrapperがJavaCVです。 以下のサイトからjavacv-0.3-bin.zipをダウンロードします。 http://code.google.com/p/javacv/ zipファイルを解凍し、
をEclipseのプロジェクトのBuildPathに追加します。 JavaCVの例として先ほどと同じ顔認識をEclipseで実行してみます。 FaceDetect.javaを以下のように作成します。JavaCVは、かなりOpenCVとの互換性を保っており、 ほとんどC++のソースをコピー&ペーストで作成することができました。 import static com.googlecode.javacv.cpp.opencv_core.*; import static com.googlecode.javacv.cpp.opencv_highgui.*; import static com.googlecode.javacv.cpp.opencv_objdetect.*; import javax.swing.JFrame; import com.googlecode.javacv.CanvasFrame; public class FaceDetect { public static void main(String[] args) { new FaceDetect().loop(); } private void loop() { CanvasFrame canvas = new CanvasFrame("FaceDetect"); canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 顔検出対象の画像データ用 IplImage tarImg = null; // 検出対象の画像ファイルパス String tarFilePath = "lena.jpg"; // 画像データの読み込み tarImg = cvLoadImage(tarFilePath, CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); // 正面顔検出器の読み込み CvHaarClassifierCascade cvHCC = new CvHaarClassifierCascade(cvLoad("haarcascade_frontalface_alt.xml")); // 検出に必要なメモリストレージを用意する CvMemStorage cvMStr = cvCreateMemStorage(0); // 検出情報を受け取るためのシーケンスを用意する CvSeq face = null; // 高速に検出できるように引数を調整 face = cvHaarDetectObjects(tarImg, cvHCC, cvMStr, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING ); for (int i = 0; i < face.total(); i++) { // 検出情報から顔の位置情報を取得 CvRect faceRect = new CvRect(cvGetSeqElem(face, i)); // 取得した顔の位置情報に基づき、矩形描画を行う cvRectangle(tarImg, cvPoint(faceRect.x(), faceRect.y()), cvPoint(faceRect.x() + faceRect.width(), faceRect.y() + faceRect.height()), CV_RGB(255, 0 ,0), 2, CV_AA, 0); } canvas.showImage(tarImg); } } 環境変数のセット †JavaCVを実行するには、opencvのダイナミックライブラリの場所を指定する必要があります。 ターミナルでは、以下のように環境変数をセットします。 export DYLD_FALLBACK_LIBRARY_PATH=/opt/local/lib/ Eclipseでは、実行の環境設定のタブで以下のようにセットします。 実行結果 †また、javaのBufferedImageからIplImageを作成するIplImage#createFromも提供しているので、Javaの親和性も良いです。 結果は、同じですがJavaのCavasFrameの方がお利口でした。 デモのソース †デモとJavaCVのカメラからのキャプチャーのソースを以下に入れておきます。
SageでOpenCVを使う †上記のデモと同じ例題をSageを使って試してみました。 コメント †皆様のご意見、ご希望をお待ちしております。
Tweet |