OpenCVでポリゴンの重心
出典: Wikimura
OpenCVでは、画像だけでなく、点列で表されたポリゴンのモーメントを求めることができる関数cvMomentsがある。 画像にも輪郭にも対応というのは、フラグを見て処理を変えているためかもしれない。
輪郭から重心を求める用途に使う前に、簡単な例で試した。 (画像がストライプに見えるのは、初期化していないため? とりあえず問題ないのでそのまま)
CvSeqを作る際、フラグCV_SEQ_POLYGONなどの輪郭を意味するフラグを使用しないと、cvMomentsでエラーが起こる。 このフラグについてはマニュアルに直接書かれていない。
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#define LINE_COLOR CV_RGB(255,0,0)
#define CIRC_COLOR CV_RGB(0,0,255)
int main( void)
{
CvMemStorage *storage = cvCreateMemStorage(0);
CvSeq *seq = cvCreateSeq( CV_SEQ_POLYGON, sizeof( CvSeq), sizeof( CvPoint), storage);
IplImage *img = cvCreateImage( cvSize( 200, 200), IPL_DEPTH_8U, 3);
CvPoint p1, p2, p3, p4;
CvPoint2D32f pc;
CvMoments moment;
p1 = cvPoint( 100, 100);
p2 = cvPoint( 140, 120);
p3 = cvPoint( 120, 100);
p4 = cvPoint( 140, 80);
cvSeqPush( seq, &p1);
cvSeqPush( seq, &p2);
cvSeqPush( seq, &p3);
cvSeqPush( seq, &p4);
cvMoments( seq, &moment);
pc = cvPoint2D32f( moment.m10 / moment.m00, moment.m01 / moment.m00);
cvDrawLine( img, p1, p2, LINE_COLOR, 2);
cvDrawLine( img, p2, p3, LINE_COLOR, 2);
cvDrawLine( img, p3, p4, LINE_COLOR, 2);
cvDrawLine( img, p4, p1, LINE_COLOR, 2);
cvDrawCircle( img, cvPointFrom32f( pc), 3, CIRC_COLOR, 2);
cvNamedWindow( "img");
cvShowImage( "img", img);
printf("center: %.3f, %.3f\n", pc.x, pc.y);
cvWaitKey( 0);
cvReleaseImage( &img);
cvReleaseMemStorage( &storage);
cvDestroyAllWindows();
return 0;
}

