連通域提取

fname  爲要分析圖片的路徑
IplImage* src = cvLoadImage(fname, CV_LOAD_IMAGE_GRAYSCALE);
 IplImage* dst = cvCreateImage(cvGetSize(src), 8, 3);
 IplImage *contoursImage = cvCreateImage(cvGetSize(src), 8, 1);
 cvZero(contoursImage);
 CvMemStorage* storage = cvCreateMemStorage(0);
 CvSeq* contour = 0;
 cvThreshold(src, src, 120, 255, CV_THRESH_BINARY);   // 二值化 
 // 提取輪廓 
 int contour_num = cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
 cvZero(dst);        // 清空數組 
 CvSeq *_contour = contour;
 double maxarea = 0;
 double minarea = 100;
 int m = 0;
 for (; contour != 0; contour = contour->h_next)
 {
         double tmparea = fabs(cvContourArea(contour));
         if (tmparea < minarea)
        {
               cvSeqRemove(contour, 0); // 刪除面積小於設定值的輪廓 
               continue;
        }
       CvRect aRect = cvBoundingRect(contour, 0);
       if ((aRect.width / aRect.height)<1)
      {
           cvSeqRemove(contour, 0); //刪除寬高比例小於設定值的輪廓 
           continue;
      }
      if (tmparea > maxarea)
      {
           maxarea = tmparea;
      }
      m++;
      // 創建一個色彩值 
      CvScalar color = CV_RGB(0, 255, 255);
      //max_level 繪製輪廓的最大等級。如果等級爲0,繪製單獨的輪廓。如果爲1,繪製輪廓及在其後的相同的級別下輪廓 
      //如果值爲2,所有的輪廓。如果等級爲2,繪製所有同級輪廓及所有低一級輪廓,諸此種種 
      //如果值爲負數,函數不繪製同級輪廓,但會升序繪製直到級別爲abs(max_level)-1的子輪廓 
      cvDrawContours(dst, contour, color, color, -1, 1, 8);   //繪製外部和內部的輪廓 
 }
 contour = _contour;
 int count = 0, i = 0;
 for (; contour != 0; contour = contour->h_next)//橫向連通域的個數
 {
      int  x = 1000, y = 0;
      for (i = 0; i < contour->total; i++)    // 提取一個輪廓的所有座標點 
      {
           CvPoint *pt = (CvPoint*)cvGetSeqElem(contour, i);   // 得到一個輪廓中一個點的函數cvGetSeqElem 
           cvSetReal2D(contoursImage, pt->y, pt->x, 255.0);
           cvSet2D(dst, pt->y, pt->x, cvScalar(0, 0, 255, 0));
           if (x > pt->x)//取連通域最左邊的點
           {
                x = pt->x;
           }
           if (y < pt->x)//取連通域最右邊的點
           {
                y = pt->x;
           }
      }
      if (x == 1000 || x == y)//去掉錯誤值
      {
           continue;
      }
  //m_view->m_point[count].x = x;
  //m_view->m_point[count].y = y;
      count++;
 }
 cvNamedWindow("dst");
 cvShowImage("dst", dst);//顯示分離出來的連通域邊緣
 char m_count[10];
 sprintf(m_count,"count is %d",count);
 AfxMessageBox(m_count);
 cvWaitKey(0);
 //cvDestroyWindow("Source");
 //cvReleaseImage(&src);
 //cvDestroyWindow("Components");
 //cvReleaseImage(&dst);
 //cvDestroyWindow("contoursImage");
 //cvReleaseImage(&contoursImage);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章