2015年12月8日 星期二

Opencv 學習筆記 ─ 找封閉區域

找封閉區域 ─ findContours 函式應用

   
void findContours(InputOutputArray image, OutputArrayOfArrays contours, 
                  int mode, int method, Point offset=Point());
   /*
    mode:
     CV_RETR_EXTERNAL:只取最外層的輪廓。
     CV_RETR_LIST:取得所有輪廓,不建立階層(hierarchy)。
     CV_RETR_CCOMP:取得所有輪廓,儲存成兩層的階層,首階層為物件外圍,
     第二階層為內部空心部分的輪廓,如果更內部有其餘物件,包含於首階層。
     //若要找封閉區域,需要用此mode來做contour間的階層
     CV_RETR_TREE:取得所有輪廓,以全階層的方式儲存。

    method:
     CV_CHAIN_APPROX_NONE:儲存所有輪廓點。
    CV_CHAIN_APPROX_SIMPLE:對水平、垂直、對角線留下頭尾點,所以假如輪廓為一
                            矩形,只儲存對角的四個頂點。
  */
使用範例://部分取自opencv doc 範例
stackoverflow Recognize open and closed shapes opencv

void contour( Mat image, Mat closeArea )
{
 
   vector[int] contours;
   vector[vec4i] hierarchy;
   findContours( image, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE , Point(0, 0));
   Mat drawing = Mat::zeros( image.size(), CV_8UC3 );
       
   for( int i = 0; i< contours.size(); i++ )
   {
     Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
     drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() );
   }
   for( int i = 0; i< contours.size(); i=hierarchy[i][0] ) // iterate through each contour.
   {
     Rect r= boundingRect(contours[i]);
     if( hierarchy[i][2] >= 0)
     {
       rectangle( closeArea,Point(r.x-10,r.y-10), Point(r.x+r.width+10,r.y+r.height+10),
                Scalar(0,255,0),2,8,0); //closed contour
    } 
    imshow( "Contours", closeArea );
    imshow( "drawing", drawing );
      
}
int main( int argc, char** argv )
{
   // Load source image and convert it to gray
   Mat src = imread( argv[1], 0 );
   Mat thr = imread( argv[1], 1 );
   imshow("src", src); 
   threshold(src,src, 200, 255, THRESH_BINARY);
   imshow("binary", src);
   contour(src,thr);
   cvWaitKey(0);
   return(0);
}

原圖






找到封閉區域






畫出輪廓







心得:

 雖然用在這個例子上很好用, 但用在複雜的圖上,結果就有點糟糕了
findContours在這張圖上,變得像是在找connected component的感覺了
思考了一陣子,發現其實是因為物件的邊緣並無完全封閉
所以造成無法用封閉區域來找到物件位置



原圖








找封閉區域








畫出輪廓


沒有留言:

張貼留言