パターンマッチング、グーチョキパーの認識
include <cv.h>
include <highgui.h>
include <ctype.h>
include <stdio.h>
int
main (int argc, char **argv)
{
CvCapture *capture = 0;
IplImage *dst = 0;
double w = 320, h = 240, result1[3], result2[3], result3[3];
int c, i;
char text[16];
CvFont font;
IplImage *mono = 0, *ten = 0;
IplImage *dst_img1, *dst_img2, *ezzi;
IplImage *tmp_img = 0;
IplImage *match1[3], *match2[3], *match3[3], *seed[3];
// 比較画像の読み込み
seed[0] = cvLoadImage ("goo4.jpg", CV_LOAD_IMAGE_GRAYSCALE);
seed[1] = cvLoadImage ("tyoki4.jpg", CV_LOAD_IMAGE_GRAYSCALE);
seed[2] = cvLoadImage ("par4.jpg", CV_LOAD_IMAGE_GRAYSCALE);
// コマンド引数によって指定された番号のカメラに対するキャプチャ構造体を作成する
if (argc == 1
|| (argc == 2 && strlen (argv[1]) == 1 && isdigit (argv[1][0])))
capture = cvCreateCameraCapture (argc == 2 ? argv[1][0] - '0' : 0);
/* この設定は,利用するカメラに依存する */
// キャプチャサイズを設定する.
cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_WIDTH, w);
cvSetCaptureProperty (capture, CV_CAP_PROP_FRAME_HEIGHT, h);
cvNamedWindow ("Capture", CV_WINDOW_AUTOSIZE);
// カメラから画像をキャプチャする
while (1)
{
dst = cvQueryFrame (capture);
c = cvWaitKey (10);
if (c == '\x1b')
break;
cvShowImage ("Capture", dst);
// 画像形状の変更を行う
/* グレースケール画像用にメモリを確保 */
mono = cvCreateImage (cvGetSize (dst), IPL_DEPTH_8U, 1);
ten = cvCreateImage (cvGetSize (dst), IPL_DEPTH_8U, 1);
/* カラー画像をグレースケールに変換 */
cvCvtColor (dst, mono, CV_BGR2GRAY);
/* 水平反転 */
cvFlip (mono, ten, 0);
// 画像の読み込み
tmp_img = cvCreateImage (cvGetSize (ten), IPL_DEPTH_16S, 1);
dst_img1 = cvCreateImage(cvGetSize(ten), IPL_DEPTH_8U, 1);
dst_img2 = cvCreateImage(cvGetSize(ten), IPL_DEPTH_8U, 1);
ezzi = cvCreateImage (cvGetSize (ten), IPL_DEPTH_8U, 1);
for (i = 0; i < 3; i++)
{
match1[i] = cvCreateImage (cvGetSize (seed[i]), IPL_DEPTH_8U, 1);
match2[i] = cvCreateImage (cvGetSize (seed[i]), IPL_DEPTH_8U, 1);
match3[i] = cvCreateImage (cvGetSize (seed[i]), IPL_DEPTH_8U, 1);
}
// Sobelフィルタによる微分画像の作成
cvSobel (ten, tmp_img, 1, 0);
cvConvertScaleAbs (tmp_img, dst_img1);
for (i = 0; i < 3; i++)
{
cvSobel (seed[i], tmp_img, 1, 0);
cvConvertScaleAbs (tmp_img, match1[i]);
}
// 画像のLaplacianの作成
cvLaplace (ten, tmp_img);
cvConvertScaleAbs (tmp_img, dst_img2);
for (i = 0; i < 3; i++)
{
cvLaplace (seed[i], tmp_img);
cvConvertScaleAbs (tmp_img, match2[i]);
}
// Cannyによるエッジ画像の作成
cvCanny (ten, ezzi, 50.0, 200.0);
for (i = 0; i < 3; i++)
cvCanny (seed[i], match3[i], 50.0, 200.0);
// 形状比較
for (i = 0; i < 3; i++)
result1[i] = cvMatchShapes (ezzi, match3[i], CV_CONTOURS_MATCH_I1, 0);
for (i = 0; i < 3; i++)
result2[i] =
cvMatchShapes (dst_img1, match1[i], CV_CONTOURS_MATCH_I1, 0);
for (i = 0; i < 3; i++)
result3[i] =
cvMatchShapes (dst_img2, match2[i], CV_CONTOURS_MATCH_I1, 0);
// 比較結果を画像に描画
//for(i=0;i<3;i++){
//printf("%f\n",result[i]);
/*printf(text,16,"%.5f",result[i]);
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,1.0,1.0,0,4);
cvPutText(match[i],text,cvPoint(10,match[i]->height-10),&font,cvScalarAll(255)); */
//}
// 画像の表示
cvNamedWindow ("Sobel", CV_WINDOW_AUTOSIZE);
cvShowImage ("Sobel", dst_img1);
cvNamedWindow ("Laplace", CV_WINDOW_AUTOSIZE);
cvShowImage ("Laplace", dst_img2);
cvNamedWindow ("Canny", CV_WINDOW_AUTOSIZE);
cvShowImage ("Canny", ezzi);
if (result1[0] < result1[1] && result1[0] < result1[2])
{
cvNamedWindow ("match3", CV_WINDOW_AUTOSIZE);
cvShowImage ("match3", match3[0]);
}
else if (result1[1] < result1[0] && result1[1] < result1[2])
{
cvNamedWindow ("match3", CV_WINDOW_AUTOSIZE);
cvShowImage ("match3", match3[1]);
}
else if (result1[2] < result1[0] && result1[2] < result1[1])
{
cvNamedWindow ("match3", CV_WINDOW_AUTOSIZE);
cvShowImage ("match3", match3[2]);
}
if (result2[0] < result2[1] && result2[0] < result2[2])
{
cvNamedWindow ("match1", CV_WINDOW_AUTOSIZE);
cvShowImage ("match1", match1[0]);
}
else if (result2[1] < result2[0] && result2[1] < result2[2])
{
cvNamedWindow ("match1", CV_WINDOW_AUTOSIZE);
cvShowImage ("match1", match1[1]);
}
else if (result2[2] < result2[0] && result2[2] < result2[1])
{
cvNamedWindow ("match1", CV_WINDOW_AUTOSIZE);
cvShowImage ("match1", match1[2]);
}
if (result3[0] < result3[1] && result3[0] < result3[2])
{
cvNamedWindow ("match2", CV_WINDOW_AUTOSIZE);
cvShowImage ("match2", match2[0]);
}
else if (result3[1] < result3[0] && result3[1] < result3[2])
{
cvNamedWindow ("match2", CV_WINDOW_AUTOSIZE);
cvShowImage ("match2", match2[1]);
}
else if (result3[2] < result3[0] && result3[2] < result3[1])
{
cvNamedWindow ("match2", CV_WINDOW_AUTOSIZE);
cvShowImage ("match2", match2[2]);
}
}
cvDestroyWindow ("Sobel");
cvDestroyWindow ("Laplace");
cvDestroyWindow ("Canny");
cvReleaseImage (&dst_img1);
cvReleaseImage (&dst_img2);
cvReleaseImage (&ezzi);
cvDestroyWindow ("match1");
cvDestroyWindow ("match2");
cvDestroyWindow ("match3");
for (i = 0; i < 3; i++)
{
cvReleaseImage (&match1[i]);
cvReleaseImage (&match2[i]);
cvReleaseImage (&match3[i]);
}
cvReleaseCapture (&capture);
cvDestroyWindow ("Capture");
return 0;
}
- エッジの検出にはまずは2値化が必要 -- (↑様) 2009-08-31 14:26:14
- これらのプログラムはご使用のカメラによっては動作しない場合があります -- (↑様) 2009-08-31 15:11:48
- 私は蟹になりたい -- (㊤様) 2009-08-31 16:09:33
- コノコンピュータシバラク -- (㊤様) 2009-09-07 14:55:07
- パターンマッチングは熟練して人がパターンを作らないといけない。パターンをいかにぼかすか、捕らえる対象の出現状態が変化するならパターンのサイズを変えたり、回転させるような工夫が必要になる。 -- (take) 2009-09-14 14:55:31
最終更新:2009年08月31日 15:12