現在地 >> メニュー >> サンプルコード::OpenCV >> OpenCV::チェスボードのコーナー検出

問題


以下のチェスボードの画像を読み込んで、コーナー検出を行え。

画像

その他条件:
 行と列ごとのコーナーの数は(4,4)とする
 検出されたチェスボードのコーナーを表示する

答え


#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace std;

int main( int argc, char **argv)
{
IplImage *imgA = cvLoadImage( "chess.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
if(imgA ==NULL)
{
cout<<"Can't Load Image ." << endl;
std::exit(0);
}



CvSize corner_size = cvSize (4, 4);
CvPoint2D32f *corners = (CvPoint2D32f *) cvAlloc (sizeof (CvPoint2D32f) * 16);
int find_num;

int found;
found = cvFindChessboardCorners(imgA,corner_size,corners,&find_num);
cvDrawChessboardCorners(imgA,corner_size,corners,find_num,found);


printf("%d corners !!\n",find_num);

cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);


cvWaitKey(0); // 0秒待つ => ずっと入力待ち


cvFree(&corners);
cvReleaseImage( &imgA );

cvDestroyWindow("window");

return 0;
}

メモ


チェスボードのコーナー検出から、カメラのキャリブレーションを行うことができる。
※cvFindChessboardCorners
http://opencv.jp/opencv/document/opencvref_cv_cali...


描画に関しては、
完全に検出した場合、各コーナを線分で接続して表示する。


例えば、
CvSize corner_num = cvSize (6, 6);
CvPoint2D32f *corners = (CvPoint2D32f *) cvAlloc (sizeof (CvPoint2D32f) * 36);

にすると、完全に検出できないので、線分はあらわれない。


リファレンスにあるように、検出座標は近似値なので、関数を用いて高精度化することも可能。


検出座標を高精度化する


#include <cv.h>
#include <highgui.h>
#include <iostream>

using namespace std;

int main( int argc, char **argv)
{
IplImage *imgA = cvLoadImage( "chess.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
if(imgA ==NULL)
{
cout<<"Can't Load Image ." << endl;
std::exit(0);
}


CvSize corner_size = cvSize (4, 4);
CvPoint2D32f *corners = (CvPoint2D32f *) cvAlloc (sizeof (CvPoint2D32f) * 16);
int find_num;

int found;
found = cvFindChessboardCorners(imgA,corner_size,corners,&find_num);//コーナー検出


/* 高精度化 */
IplImage *tmp = cvCreateImage (cvGetSize (imgA), IPL_DEPTH_8U, 1);
cvCvtColor (imgA, tmp, CV_BGR2GRAY);

cvFindCornerSubPix (tmp, corners, find_num, cvSize (3, 3), cvSize (-1, -1), cvTermCriteria (CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03));

cvReleaseImage( &tmp );


/* 描画 */
cvDrawChessboardCorners(imgA,corner_size,corners,find_num,found);


printf("%d corners !!\n",find_num);


cvNamedWindow("window",CV_WINDOW_AUTOSIZE);
cvShowImage("window",imgA);


cvWaitKey(0); // 0秒待つ => ずっと入力待ち



cvFree(&corners);
cvReleaseImage( &imgA );

cvDestroyWindow("window");

return 0;
}


メモ


for(int i = 0;i<16;i++)
{
printf("[%d]:(%f,%f)\n",i,corners[i].x,corners[i].y);
}
などで

出力を比較するとわかる。

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます