OpenCV中的新函數connectedComponentsWithStats使用


主要內容:對比新舊函數,用於過濾原始圖像中輪廓分析后較小的區域,留下較大區域。
關鍵字    :connectedComponentsWithStats

在以前,常用的方法是 是先調用  cv::findContours()  函數(傳入 cv::RETR_CCOMP  標志),隨后在得到的連通區域上循環調用  cv::drawContours()
比如,我在GOCVHelper中這樣進行了實現
//尋找最大的輪廓
    VP FindBigestContour(Mat src){    
        int imax = 0; //代表最大輪廓的序號
        int imaxcontour = -1; //代表最大輪廓的大小
        std::vector<std::vector<Point>>contours;    
        findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
        for (int i=0;i<contours.size();i++){
            int itmp =  contourArea(contours[i]);//這里采用的是輪廓大小
            if (imaxcontour < itmp ){
                imax = i;
                imaxcontour = itmp;
            }
        }
        return contours[imax];
    }
    //尋找並繪制出彩色聯通區域
    vector<VPconnection2(Mat src,Matdraw){    
        draw = Mat::zeros(src.rows,src.cols,CV_8UC3);
        vector<VP>contours;    
        findContours(src.clone(),contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
        //由於給大的區域着色會覆蓋小的區域,所以首先進行排序操作
        //冒泡排序,由小到大排序
        VP vptmp;
        for(int i=1;i<contours.size();i++){
            for(int j=contours.size()-1;j>=i;j--){
                if (contourArea(contours[j]) < contourArea(contours[j-1]))
                {
                    vptmp = contours[j-1];
                    contours[j-1] = contours[j];
                    contours[j] = vptmp;
                }
            }
        }
在OpenCV3中有了新的專門的函數  cv::connectedComponents()  和函數  cv::connectedComponentsWithStats()
定義:
int  cv::connectedComponents (
    cv::InputArrayn image,                // input 8-bit single-channel (binary)
    cv::OutputArray labels,               // output label map
    int             connectivity = 8,     // 4- or 8-connected components
    int             ltype        = CV_32S // Output label type (CV_32S or CV_16U)
    );
int  cv::connectedComponentsWithStats (
    cv::InputArrayn image,                // input 8-bit single-channel (binary)
    cv::OutputArray labels,               // output label map
    cv::OutputArray stats,                // Nx5 matrix (CV_32S) of statistics:
                                                                         // [x0, y0, width0, height0, area0;
                                                                        //  ... ; x(N-1), y(N-1), width(N-1),
                                                                          // height(N-1), area(N-1)]
    cv::OutputArray centroids,            // Nx2 CV_64F matrix of centroids:
                                                                          // [ cx0, cy0; ... ; cx(N-1), cy(N-1)]
    int             connectivity = 8,     // 4- or 8-connected components
    int             ltype        = CV_32S // Output label type (CV_32S or CV_16U)
    );
其中,新出現的參數
stats:長這樣
分別對應各個輪廓的x,y,width,height和面積。注意0的區域標識的是background
centroids則對應的是中心點
而label則對應於表示是當前像素是第幾個輪廓
例子:
對於圖像
     Mat img = cv::imread"e:/sandbox/rect.png",0); 
    cv::Mat  img_edgelabelsimg_colorstats,centroids;
    cv::threshold(imgimg_edge, 128, 255, cv::THRESH_BINARY);
    bitwise_not(img_edge,img_edge);
    cv::imshow("Image after threshold"img_edge);
    int inccomps = cv::connectedComponentsWithStats (
        img_edgelabels,
        statscentroids
        );
    cout << "Total Connected Components Detected: " << nccomps << endl;
    vector<cv::Vec3bcolors(nccomps+1);
    colors[0] = Vec3b(0,0,0); // background pixels remain black.
    fori = 1; i < nccompsi++ ) {
        colors[i] = Vec3b(rand()%256, rand()%256, rand()%256);
        ifstats.at<int>(icv::CC_STAT_AREA) < 200 )
            colors[i] = Vec3b(0,0,0); // small regions are painted with black too.
    }
    img_color = Mat::zeros(img.size(), CV_8UC3);
    forint y = 0; y < img_color.rowsy++ )
        forint x = 0; x < img_color.colsx++ )
        {
            int label = labels.at<int>(yx);
            CV_Assert(0 <= label && label <= nccomps);
            img_color.at<cv::Vec3b>(yx) = colors[label];
        }
    cv::imshow("Labeled map"img_color);
    cv::waitKey();
注意:
1、對於OpenCV來說,白色代表有數據,黑色代表沒有數據,所以圖像輸入之前要轉換成”黑底白圖“
2、看 labels  和  stats,其中第1 2 6 個的面積小於200
而labels中
完全對的上號,結果







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM