# ConnectedComponnents and zero level in binary image

Hi,

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

edit retag close merge delete

Sort by ยป oldest newest most voted

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.

more

3

"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.

( 2015-04-04 08:04:53 -0500 )edit

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)
{

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;
labels1 = labels1 + labels2 - 1;
minMaxIdx(labels1, &ccMin, &ccMax);
cout<<ccMax<<"\n";
labels1.convertTo(cc, CV_8UC1, 32, 0);
applyColorMap(cc, cc, cv::COLORMAP_HSV);
imshow("Labels", cc);
waitKey(0);
}

more