物体認識には、形状の特徴をベースにしたものと、色情報をベースにしたものがあるようで、今回は色情報のものからやってみることにしました。
下準備として、特定の色を抽出するプログラムを作ってみました。
色情報で判断する場合、通常使用しているRGBだとどの色かがわかりにくいため、HSVに変換して処理しています。
HSVは色相、彩度、明度からなっているので、色相(H)だけ調査すればどの色かがわかります。(細かくはWikipediaを参照ください)
下記の動画は、表示する色相を0度から360度まで変化させたものです。
(OpenCVでは0~180で色相が一周していました)
家の中をWebカメラで色々写したところ、我が家では黄色か黄緑成分が少ないので
対象物の色は黄色か黄緑にすることにしました。
逆に、赤と青はそこらじゅうにあったため、このあたりの色は適さない模様です。
(壁、肌は赤成分に反応し、髪の毛や黒は青成分で反応してました)
今回のコードは短いのでこちらに掲載します。
////////////////////////////////////// // // OpenCVで遊ぼう! // http://playwithopencv.blogspot.com/ // //hsv.cpp //カラー画像を読み込み、BGR画像からHSV画像に変換し、 //特定の色相だけ抽出したものを表示します。 //色による物体追跡用のマスクとして使用する予定です。 #include "cv.h" #include "highgui.h" #includeint main(int argc, char** argv) { IplImage * source; source=cvLoadImage("HSV.png",1); if(source==NULL) return -1; IplImage * hsvimage; IplImage * bgrimage; IplImage * hueimage; IplImage * simage; IplImage * vimage; hsvimage=cvCreateImage(cvGetSize(source),IPL_DEPTH_8U,3); bgrimage=cvCreateImage(cvGetSize(source),IPL_DEPTH_8U,3); //H S Vの3つに分けるためのスペースを確保 hueimage=cvCreateImage(cvGetSize(source),IPL_DEPTH_8U,1); simage=cvCreateImage(cvGetSize(source),IPL_DEPTH_8U,1); vimage=cvCreateImage(cvGetSize(source),IPL_DEPTH_8U,1); cvNamedWindow("orig"); cvNamedWindow("result"); int hue=0; //0から180まで int huestep=1; //hueの増加・減少単位。 int huerange=1; //許容する範囲。1以上にしてください。 char pressd; //フォントの設定 CvFont dfont; float hscale = 0.5f; float vscale = 0.5f; float italicscale = 0.0f; int thickness = 1; char text[255] = ""; cvInitFont (&dfont, CV_FONT_HERSHEY_SIMPLEX , hscale, vscale, italicscale, thickness, CV_AA); while(1) { cvCvtColor(source,hsvimage,CV_BGR2HSV); //Hue成分のみ抽出。 cvSplit(hsvimage,hueimage,NULL,NULL,NULL); //現在のHue+許容範囲以上を切り捨てる //CV_THRESH_TOZERO_INVは、閾値以上の値を0にするフラグ。 cvThreshold(hueimage,hueimage,hue+huerange,hue,CV_THRESH_TOZERO_INV); //現在のHue-許容範囲以下を0にする cvThreshold(hueimage,hueimage,hue-huerange,hue,CV_THRESH_BINARY); cvZero(simage); cvZero(vimage); cvOrS(simage,cvScalarAll(255),simage,hueimage); cvOrS(vimage,cvScalarAll(255),vimage,hueimage); //H S Vを合体させる cvMerge(hueimage,simage,vimage,NULL,hsvimage); cvCvtColor(hsvimage,bgrimage,CV_HSV2BGR); //OpenCVは0-180°でHueを扱っているが、本来は0-360°なので2倍しておく sprintf(text,"hue %d",hue*2); cvPutText(bgrimage,text,cvPoint(bgrimage->width/2,bgrimage->height-30),&dfont,CV_RGB(255,255,255)); cvShowImage("orig",source); cvShowImage("result",bgrimage); pressd=cvWaitKey(100); if(pressd==27) break; if(hue>180) hue=0; hue++; } cvReleaseImage (&hsvimage); cvReleaseImage (&bgrimage); cvReleaseImage (&hueimage); cvReleaseImage (&simage); cvReleaseImage (&vimage); cvDestroyWindow("orig"); cvDestroyWindow("result"); }
物体追跡のよい参考書がなかなか見つかりません。。。
Webで調べるしかないのかな~
ではまた。
0 件のコメント:
コメントを投稿