レベルエンター山本大のブログ

面白いプログラミング教育を若い人たちに

BLOCKVROCKリファレンス目次はこちら

簡単、OpenCV+Javaで「顔認識プログラム」を作ってみよう!

OpenCVで顔認識をするのが、いろんな言語で流行ってるけど、Javaでやってるのはあんまり見かけません。
と言うことで顔の部分を認識して四角で囲むってのをやってみます。


出来上がりはこんな感じ。


ハマったところはあったけど、出来上がってみると簡単。

OpenCVとは

まずOpenCVをしらない人のために簡単に説明。

OpenCV(おーぷんしーぶい)とはインテルが開発・公開しているオープンソースのコンピュータビジョン向けライブラリ。

http://ja.wikipedia.org/wiki/OpenCV

ただし、提供されているのはC++のライブラリなのでJavaなどから利用するのはちょっと手間です。


以下のサイトで、Javaから利用できるOpenCVのブリッジライブラリが提供されているのでここを参考にしてサンプルを作ってみます。
ただし、現時点ではまだOpenCVのすべての機能を、このライブラリで提供できていないそうです。
対応中とのことなので、見守りたいですね。


具体的に何ができるかというと

  • リアルタイムキャプチャー(real-time capture)
  • ビデオファイルのインポート(video file import)
  • 基本的な画像処理(basic image treatment (brightness, contrast, threshold, …))
  • 物体認識 「顔とか体とか」(object detection (face, body, …))
  • 音声や画像などのバイナリデータ定義(blob(Binary Large OBject) detection)

だそうです。


とりあえず、Windows環境で説明します。

OPENCV Processing and Java Library
http://ubaa.net/shared/processing/opencv/

まずはソース配置のディレクトリを作成

ソースなどを配置するディレクトリを作成します。
個人的なポリシーに基き*1コマンドラインテキストエディターで作ります。


C:直下にjavaさらにその下に、OpenCVJavaというディレクトリを作成します。
こんな感じになります。

c:
└─java
  └─OpenCVJava

OpenCV本体のインストール

まずは、以下のサイトからOpenCV本体であるOpenCV_x.x.exeをダウンロードします。(今回は、OpenCV_1.0.exeを利用)
http://sourceforge.net/project/showfiles.php?group_id=22870&package_id=16937

MacLinuxの人もここにインストール方法が書いてるので参考にしてください。)

インストーラーを実行する

インストーラーはウィザード形式です。次へ次へと進んでいってください。

参考にしたWebサイトには以下のように「'Add <...>\OpenCV\bin to system PATH' 」にチェックをつけろとあります。


このチェックをつけたら、当然環境変数のPATHにライブラリのパスが書きこまれると思ってたんですが、
しかし、実際には書きこまれておらず、ちょっとハマりました。


そこで、手動でPATHの設定をすることにします。
ただし、他にもPATHを設定する箇所があるので、この時点では一旦保留。
ちなみに、デフォルトのインストールディレクトリは以下のような場所です。このパスを後ほど環境変数のPATHに設定します。

C:\Program Files\OpenCV\bin

OpenCV Processing Libraryのインストール

JavaからOpenCVを使うためには、「OpenCV Processing Library」が必要です。*2
以下のURLで入手できます。
http://ubaa.net/shared/processing/opencv/download/opencv_01.zip

Zipを解凍したディレクトリ直下の「library」の内容だけを使います。
さっき作ったJavaのプロジェクトディレクトリOpenCVJavaにlibraryディレクトリごとコピーしましょう。
こんな風になりますね。

C:
└─java
  └─OpenCVJava
    └─library

この「libraryディレクトリ」にもパスを通す必要があります。
先ほど保留にしたパス設定とあわせて、次のステップで環境変数の設定をしましょう。

環境変数PATHの設定

さて、環境変数PATHに追記するのは、
「C:\Program Files\OpenCV\bin」と
「C:\java\OpenCVJava\library\」の2つとなります。

設定方法は、おなじみでしょうけれど、一応以下です。
マイコンピュータ右クリック
 →プロパティー
  →詳細設定タブ
   →環境変数(N)ボタン
でシステム環境変数のリストからPathを見つけ出し、

〜既に登録されてるパスの内容〜;C:\Program Files\OpenCV\bin;C:\java\OpenCVJava\library\

と登録します。

くれぐれもPATHに”追記”です。PATHを消したりすると酷い目にあいますのでバックアップなどとって慎重に。


追記:パスを設定したらマシンの再起動が必要なようです。

オブジェクト検出の設定ファイルを配置。

顔検出のためには、顔検出用の設定ファイルが必要です。
この設定ファイルは、標準で様々なものが用意されています。
OpenCV本体のディレクトリに標準のファイルが含まれていますので、これらをコピーして使います。

OpenCV本体に含まれる以下のディレクトリ(haarcascades)をコピーして
そのままOpenCVJavaディレクトリの下に置きましょう。

このディレクトリごとコピー
C:\Program Files\OpenCV\data\haarcascades

結果としてプログラムを配置するOpenCVJavaが、こんな感じになればOKです。

C:
└─java
  └─OpenCVJava
    ├─haarcascades
    └─library

ソースの作成

いよいよソースコードを作って行きます。
以下のコードをFaceDetection.javaというファイル名でOpenCVJavaディレクトリに保存します。

FaceDetection.java

import java.awt.*;
import java.awt.image.MemoryImageSource;
import hypermedia.video.OpenCV;

public class FaceDetection extends Frame {
	
	OpenCV cv = null;
	
	FaceDetection(String imagePath) {
		super();	// Frameのコンストラクタを呼んでおく。
		
		// OpenCVインスタンスの作成とイメージファイルのロード
		cv = new OpenCV();
		cv.loadImage(imagePath);
		
		// 顔の検出
		cv.cascade( "haarcascades\\" + OpenCV.CASCADE_FRONTALFACE_ALT );
		Rectangle[] squares = cv.detect( 1.2f, 2, OpenCV.HAAR_DO_ROUGH_SEARCH,20, 20 );

		// フレームの表示
		this.setBounds( 0, 0, cv.width, cv.height );
		this.setVisible( true );

		// フレームに写真を書き出す
		// cv.image()は、戻り値がProcessingのPImageなのでここでは使わない。
		MemoryImageSource mis = new MemoryImageSource( cv.width, cv.height, cv.pixels(), 0, cv.width );
		Image frame = createImage( mis );
		Graphics g = this.getGraphics();
		g.drawImage( frame, 0, 0, null );
		
		// 顔の部分を赤四角で囲む。
		g.setColor( Color.RED );
		for( Rectangle rect : squares ){
			g.drawRect( rect.x, rect.y, rect.width, rect.height );
		}
	}
	
	@Override
	public synchronized void dispose(){
		// OpenCVインスタンスの破棄。
		//このサンプルは連続で実行すると写真が表示されないというバグがあります。)
		cv.dispose();
	}

	
	public static void main( String[] args ) {
		new FaceDetection(args[0]);// 引数はイメージファイルのフルパス。
	} 

}

ビルド方法

コマンドラインでビルドしますが、クラスパス指定などが面倒なのでbatファイルを作成しました。
以下のようにbatファイルを記述して、OpenCVディレクトリに配置してください。

build.bat

javac -cp ./library/OpenCV.jar FaceDetection.java
java -cp .;./library/OpenCV.jar FaceDetection C:\java\OpenCVJava\face.jpg
pause

実行時の引数として、画像ファイルのパスを渡しています。

以上で、完了です。

実行と終了および注意点

batファイルを実行すると、ウィンドウが立ち上がります。

終了ボタンなどは作っていないので、
コマンドプロンプト上で、Ctrl+Cを押して終了させてください。
オブジェクトの破棄時に、OpenCVのオブジェクトをdisposeしているので、
しばらく時間を置かないと画像が表示されない場合があります。


■Learning OpenCV: Computer Vision With the Opencv Library (ペーパーバック)



そのうち、内容の解説も書きます。

*1:実際には、ビジュアルな説明が面倒なので

*2:Processingというのは、電子アートとビジュアルデザインのためのJavaベースのプログラミング言語です。ただし、今回は使いません。