OpenCV を使ってエッジ抽出

プチロボ事始め | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/2416
プチロボで4軸構成にしてみる | Moonmile Solutions Blog
http://www.moonmile.net/blog/archives/2421

の続き

プチロボを使ってアームを作る前に、OpenCV を使って Web カメラを使ってキャプチャを試してみました。

#include <stdlib.h>
#include "opencv/cv.h"
#include "opencv/highgui.h"

int main( int argc, char **argv )
{
	cvNamedWindow( "Sample03in", CV_WINDOW_AUTOSIZE );
	cvNamedWindow( "Sample03out", CV_WINDOW_AUTOSIZE );

	CvCapture *capture;
	if ( argc == 1 ) {
		capture = cvCreateCameraCapture(0);
	} else {
	 	capture = cvCreateFileCapture( argv[1] );
	}
	IplImage *frame = NULL;
	IplImage *frameGray = NULL;
	IplImage *frameCanny = NULL;
	while ( 1 ) {
		frame = cvQueryFrame( capture );
		if ( !frame ) break;

		if ( frameGray == NULL ) {
			frameGray = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
			frameCanny = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 1);
		}
		cvCvtColor(frame, frameGray, CV_BGR2GRAY);
		cvCanny( frameGray, frameCanny, 10, 100, 3 );

		cvShowImage( "Sample03in", frame );
		cvShowImage( "Sample03out", frameCanny );

		char ch = cvWaitKey(33);
		if ( ch == 27 ) break;
	}
	cvReleaseCapture( &capture );
	cvDestroyWindow( "Sample03in" );
	cvDestroyWindow( "Sample03out" );
	return 0;
}

手順としては、

  1. cvCreateCameraCapture 関数でカメラを開く
  2. cvQueryFrame 関数で1フレーム分取得
  3. その画像に対して、グレースケール化と Canny 変換によりエッジ抽出)
  4. それぞれの画像を cvShowImage 関数で画面に表示

OpenCV は C++ からも使えるのでクラスのほうも試したほうが良いのですが、どうやらサンプルのほうはC言語のほうが多いので、こちらで。

opencv.jp – OpenCV: ビデオ入出力(Video I/O)サンプルコード –
http://opencv.jp/sample/video_io.html#cap_write



単純にアニメキャラの場合は、エッジでも十分取れるのですが、iPhone のゲームの場合は色が取れないのでエッジを抽出しても駒の判別がつかないので、別途色を加える必要がありますね。
キーボードの場合は、視認性が高いのでそのままでも良さそう。

パズルを解かせるには、エッジ抽出をしてからある程度テンプレートマッチングで場所を特定して、それから色や詳細でマッチングということになりそうです。
あと、iPhone や iPad の傾きを調べるにはエッジ抽出が有効そうです。

カテゴリー: C++, プチロボ パーマリンク