Ask Your Question

ConnectedComponnents and zero level in binary image

asked 2015-04-03 11:02:46 -0600

LBerger gravatar image


Is it possible using connectedComponnents algorithm (opencv 3.0) to have region 0(b) and 0(c) labelled 4 and 5 instead of 0 ?

image description

thanks for your help

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted

answered 2015-04-03 20:10:04 -0600

rwong gravatar image

Because the OpenCV connected components algorithm is designed for binary input, it will not find the holes which you have labeled 0(b) and 0(c).

My suggestion is to perform Canny edge detection (or any edge detection, since your image is simple enough), followed by bitwise negation, and finally the connected components labeling with connectivity = 4.

Here are some explanations of the detail I gave above.

The bitwise negation causes the "Canny edge pixels" to become background pixels. In other words, they are delimiters - they represent pixels that do not connect, thus segmenting distinctly colored regions into pieces. All remaining pixels become foreground pixels.

The connectivity needs to be 4 because the pixel chains formed by Canny are 8-connected. That is, sometimes the edge pixels go in diagonal directions. If the connected component algorithm had used 8-connectivity, it would leak through the boundary formed by the edge pixel chains. Using 4-connectivity in the connected component algorithm will not have this problem.

edit flag offensive delete link more



"Because the OpenCV connected components algorithm is designed for binary input, it will not find the holes which you have labeled 0(b) and 0(c)." That is not right. findContours can return hierarchies of connected components and 0(b) will be a child of contour 3.

FooBar gravatar imageFooBar ( 2015-04-04 08:04:53 -0600 )edit

answered 2015-09-13 15:24:33 -0600

LBerger gravatar image

updated 2016-12-03 12:14:18 -0600

Do you think that's a good way to solve this problem ?

#include "opencv2/opencv.hpp" #include <iostream>

using namespace cv; 
using namespace std;

int main (int argc,char **argv)

 Mat x = imread("14415468805620458.jpg",CV_LOAD_IMAGE_GRAYSCALE);
imshow("original", x);
Mat y,cc;
double ccMin, ccMax;
threshold(x, y, 50, 255, THRESH_BINARY);
imshow("threshold", y);
Mat labels1, labels2;
connectedComponents(y, labels1, 8, CV_32S);
minMaxIdx(labels1, &ccMin, &ccMax);
bitwise_not(y, y);
connectedComponents(y, labels2, 8, CV_32S);
Mat mask = labels1 == 0;
add(labels2, ccMax, labels2, mask);
labels1 = labels1 + labels2 - 1;
minMaxIdx(labels1, &ccMin, &ccMax);
labels1.convertTo(cc, CV_8UC1, 32, 0);
applyColorMap(cc, cc, cv::COLORMAP_HSV);
imshow("Labels", cc);
edit flag offensive delete link more

Question Tools

1 follower


Asked: 2015-04-03 11:02:46 -0600

Seen: 1,566 times

Last updated: Dec 03 '16