connected components in OpenCV

前端 未结 6 2043
既然无缘
既然无缘 2020-11-27 04:58

I am looking for an OpenCV function that can find connected components and perform a few tasks on them ( like getting the number of pixels, contour, list of pixels in the ob

6条回答
  •  死守一世寂寞
    2020-11-27 05:32

    Following DXM's code above which assumes 4-connected components, here is a version for 'findCC' that detects 8-connected components.

    void findCC(const cv::Mat& src, std::vector& cc) {
    if (src.empty()) return;
    CV_Assert(src.type() == CV_8U);
    cc.clear();
    int total_pix = int(src.total());
    int *frame_label = new int[total_pix];
    DisjointSet labels(total_pix);
    int *root_map = new int[total_pix];
    int x, y;
    const uchar* cur_p;
    const uchar* prev_p = src.ptr(0);
    int left_val, up_val, up_left_val, up_right_val;
    int cur_idx, left_idx, up_idx, up_left_idx, up_right_idx;
    cur_idx = 0;
    //first logic loop
    for (y = 0; y < src.rows; y++) {
        cur_p = src.ptr(y);
        for (x = 0; x < src.cols; x++, cur_idx++) {
            left_idx = cur_idx - 1;
            up_idx = cur_idx - src.size().width;
            up_left_idx = up_idx - 1;
            up_right_idx = up_idx + 1;
    
            if (x == 0)
            {
                left_val = 0;
            }
            else
            {
                left_val = cur_p[x - 1];
            }
            if (y == 0)
            {
                up_val = 0;
            }
            else
            {
                up_val = prev_p[x];
            }
            if (x == 0 || y == 0)
            {
                up_left_val = 0;
            }
            else
            {
                up_left_val = prev_p[x-1];
            }
            if (x == src.cols - 1 || y == 0)
            {
                up_right_val = 0;
            }
            else
            {
                up_right_val = prev_p[x+1];
            }
    
            if (cur_p[x] > 0) {
                //current pixel is foreground and has no connected neighbors
                if (left_val == 0 && up_val == 0 && up_left_val == 0 && up_right_val == 0) {
                    frame_label[cur_idx] = (int)labels.add();
                    root_map[frame_label[cur_idx]] = -1;
                }
    
                //Current pixel is foreground and has at least one neighbor
                else
                {
                    vector frame_lbl;
                    frame_lbl.reserve(4);
                    //Find minimal label
                    int min_frame_lbl = INT_MAX;
                    int valid_entries_num = 0;
    
                    if (left_val != 0)
                    {
                        frame_lbl.push_back(frame_label[left_idx]);
                        min_frame_lbl = min(min_frame_lbl, frame_label[left_idx]);
                        valid_entries_num++;
                    }
                    if (up_val != 0)
                    {
                        frame_lbl.push_back(frame_label[up_idx]);
                        min_frame_lbl = min(min_frame_lbl, frame_label[up_idx]);
                        valid_entries_num++;
                    }
                    if (up_left_val != 0)
                    {
                        frame_lbl.push_back(frame_label[up_left_idx]);
                        min_frame_lbl = min(min_frame_lbl, frame_label[up_left_idx]);
                        valid_entries_num++;
                    }
                    if (up_right_val != 0)
                    {
                        frame_lbl.push_back(frame_label[up_right_idx]);
                        min_frame_lbl = min(min_frame_lbl, frame_label[up_right_idx]);
                        valid_entries_num++;
                    }
    
                    CV_Assert(valid_entries_num > 0);
                    frame_label[cur_idx] = min_frame_lbl;
    
                    //Unite if necessary
                    if (valid_entries_num > 1)
                    {
                        for (size_t i = 0; i < frame_lbl.size(); i++)
                        {
                            labels.unite(frame_lbl[i], min_frame_lbl);
                        }
                    }
                }
    
            }//endif
            else {
                frame_label[cur_idx] = -1;
            }
        } //end for x
        prev_p = cur_p;
    }//end for y
    //second loop logic
    cur_idx = 0;
    int curLabel;
    int connCompIdx = 0;
    for (y = 0; y < src.size().height; y++) {
        for (x = 0; x < src.size().width; x++, cur_idx++) {
            curLabel = frame_label[cur_idx];
            if (curLabel != -1) {
                curLabel = labels.find(curLabel);
                if (root_map[curLabel] != -1) {
                    cc[root_map[curLabel]].addPixel(x, y);
                }
                else {
                    cc.push_back(ConnectedComponent(x, y));
                    root_map[curLabel] = connCompIdx;
                    connCompIdx++;
                }
            }
        }//end for x
    }//end for y
    
    //Free up allocated memory
    delete[] frame_label;
    delete[] root_map;
    

    }

提交回复
热议问题