歡迎您光臨本站 註冊首頁

opencv 查詢連通區域 最大面積例項

←手機掃碼閱讀     niceskyabc @ 2020-06-12 , reply:0

今天在弄一個查詢連通的最大面積的問題。

要把影象弄成黑底,白字,這樣才可以正確找到。

然後呼叫下邊的方法:

RETR_CCOMP:提取所有輪廓,並將輪廓組織成雙層結構(two-level hierarchy),頂層為連通域的外圍邊界,次層位內層邊界

  #include#includeusing namespace cv;  using namespace std;     int main( int argc, char** argv )  {    Mat src = imread( argv[1] );       int largest_area=0;    int largest_contour_index=0;    Rect bounding_rect;       Mat thr;    cvtColor( src, thr, COLOR_BGR2GRAY ); //Convert to gray    threshold( thr, thr, 125, 255, THRESH_BINARY ); //Threshold the gray    bitwise_not(thr,thr); //這裡先變反轉顏色       vector contours; // Vector for storing contours       findContours( thr, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image       for( size_t i = 0; i< contours.size(); i++ ) // iterate through each contour.    {      double area = contourArea( contours[i] ); // Find the area of contour         if( area > largest_area )      {        largest_area = area;        largest_contour_index = i;        //Store the index of largest contour        bounding_rect = boundingRect( contours[i] ); // Find the bounding rectangle for biggest contour      }    }       drawContours( src, contours,largest_contour_index, Scalar( 0, 255, 0 ), 2 ); // Draw the largest contour using previously stored index.       imshow( "result", src );    waitKey();    return 0;  }

 

方法二: connectedComponentsWithStats

   std::pair< int , int > MaxAreaFromSource(Mat srcImage, Mat &dstImage, int index)  {    /*    vector contours; // Vector for storing contours        int largest_area=0;    size_t largest_contour_index=0;    Rect bounding_rect;        findContours( srcImage, contours, RETR_CCOMP, CHAIN_APPROX_SIMPLE ); // Find the contours in the image        for( size_t i = 0; i< contours.size(); i++ ) // iterate through each contour.    {      double area = contourArea( contours[i] ); // Find the area of contour            if( area > largest_area )      {        largest_area = area;        largest_contour_index = i;        //Store the index of largest contour        bounding_rect = boundingRect( contours[i] ); // Find the bounding rectangle for biggest contour      }    }        Mat dst;    cvtColor(srcImage, dst, CV_GRAY2RGB);    drawContours( dst, contours,largest_contour_index, Scalar( 0, 255, 0 ), 2 ); // Draw the largest contour using previously stored index.    imshow( "result", dst );    waitKey();        printf("%%%%%%%%%%%max area:%d ", largest_area);    return make_pair( largest_area, index);    */        cv::Mat img_bool, labels, stats, centroids, img_color, img_gray;        //連通域計算    int nccomps = cv::connectedComponentsWithStats (                            srcImage, //二值影象                            labels,   //和原圖一樣大的標記圖                            stats, //nccomps×5的矩陣 表示每個連通區域的外接矩形和麵積(pixel)                            centroids //nccomps×2的矩陣 表示每個連通區域的質心                            );    //cv::imshow("labels", labels);    //cv::waitKey();        vectorcolors(nccomps);    colors[0] = cv::Vec3b(0,0,0); // background pixels remain black.         printf( "index:%d================== ",index );        vector< int >vec_width,vec_area,vec_height;        for(int label = 1; label < nccomps; ++label)    {      colors[label] = cv::Vec3b( (std::rand()&255), (std::rand()&255), (std::rand()&255) );      std::cout << "Component "<< label << std::endl;      std::cout << "CC_STAT_LEFT  = " << stats.at(label,cv::CC_STAT_LEFT) << std::endl;      std::cout << "CC_STAT_TOP  = " << stats.at(label,cv::CC_STAT_TOP) << std::endl;      std::cout << "CC_STAT_WIDTH = " << stats.at(label,cv::CC_STAT_WIDTH) << std::endl;      std::cout << "CC_STAT_HEIGHT = " << stats.at(label,cv::CC_STAT_HEIGHT) << std::endl;      std::cout << "CC_STAT_AREA  = " << stats.at(label,cv::CC_STAT_AREA) << std::endl;      std::cout << "CENTER  = (" << centroids.at(label, 0) <<","<< centroids.at(label, 1) << ")"<< std::endl << std::endl;            int area = stats.at(label,cv::CC_STAT_AREA);      int left = stats.at(label,cv::CC_STAT_LEFT);      int top = stats.at(label,cv::CC_STAT_TOP);      int width = stats.at(label,cv::CC_STAT_WIDTH);      int height = stats.at(label,cv::CC_STAT_HEIGHT);            vec_area.push_back(area);      vec_width.push_back(width);      vec_height.push_back(height);    }        vector::iterator bigwidth = std::max_element(std::begin(vec_width), std::end(vec_width));    vector::iterator bigheight = std::max_element(std::begin(vec_height), std::end(vec_height));    vector::iterator bigarea = std::max_element(std::begin(vec_area), std::end(vec_area));        //printf( "area:%d------------width:%d height:%d  ", *bigarea, *bigwidth, *bigheight );        //按照label值,對不同的連通域進行著色    img_color = cv::Mat::zeros(srcImage.size(), CV_8UC3);    for( int y = 0; y < img_color.rows; y++ )      for( int x = 0; x < img_color.cols; x++ )      {        int label = labels.at(y, x);        CV_Assert(0 <= label && label <= nccomps);        img_color.at(y, x) = colors[label];      }        cv::imshow("color", img_color);    cv::waitKey();         return make_pair( *bigarea , index );  }

 

我先用這個函式實現了一下,效果正確,還是opencv demo 是正確的,網上找了個例子,害死我了。

說明一下:方法一 比 第二種方法 執行速度快很多哦! 這一點很重要。

 


[niceskyabc ] opencv 查詢連通區域 最大面積例項已經有232次圍觀

http://coctec.com/docs/program/show-post-238227.html