jsa
jsa

Reputation: 397

OpenCV 3.0 Connected components, can't get it to work properly

I have the following code, it's just a simple test program to learn how to use the connected components functionality in openCV 3.0

int main(int argc, char** argv) {

char* line = argv[1];

Mat image;

image = imread(line,CV_LOAD_IMAGE_GRAYSCALE);   

cv::Mat label=Mat(image.size(),CV_16U);

int la=connectedComponents(image,label, 8,CV_16U);

    //tried also: label.convertTo(label,CV_8U,255);   
   // and label.convertTo(label,CV_16U,255);

namedWindow( "input", CV_WINDOW_AUTOSIZE );
imshow( "input", image);

    namedWindow( "ouput", CV_WINDOW_AUTOSIZE );
    imshow("output", label);
    cout<<la<<"\n";

    imwrite("output.png", label);
    waitKey(0);
    return 0;
    }

The input image is a color image with two red squares on a white background. The image is correctly loaded and displayed as a grayscale image. program outoput

The thing is no matter what I do, the output is always a blank image, either black or white, depending on the convertTo paremeters.

However, the value returned by connectedComponents is 2.

I tried the full code proposed by Miki, I get this:

enter image description here

I thought the issue could be that connected Components is not working properly.

Tried with a picture I had on my desktop and finally got something:

enter image description here

However, this time the source image is a regular picture with people, buildings, cars...and most of the output is still blank. Does anybody know why?

After adding image = image < 200;

enter image description here

With applyColorMap(seeMyLabels, seeMyLabels, COLORMAP_JET);, the labels image goes from almost black grayscale to blue shades

enter image description here

Upvotes: 4

Views: 6415

Answers (1)

Miki
Miki

Reputation: 41765

Results are there, you just can't see them!


label contains the index of each label. This means that, in this case, in label you have pixel with values:

0 : background
1 : first connected component
2 : second connected component

so your image is quite dark. Just for visualization purposes, you can add this line:

Mat seeMyLabels;
normalize(label, seeMyLabels, 0, 255, NORM_MINMAX, CV_8U);
imshow("Labels", seeMyLabels);

that will scale the values to a visible range.

Note that the image should be a binary image, with black background and white foreground.

Full code:

#include <opencv2\opencv.hpp>
using namespace cv;

int main(int argc, char** argv)
{
    if (argc != 2) return -1;

    Mat image = imread(argv[1], IMREAD_GRAYSCALE);

    if (image.empty()) return -1;

    Mat label;
    int la = connectedComponents(image, label, 8, CV_16U);

    Mat seeMyLabels;
    normalize(label, seeMyLabels, 0, 255, NORM_MINMAX, CV_8U);

    // You can apply a colormap for better visualization
    //applyColorMap(seeMyLabels, seeMyLabels, COLORMAP_JET);

    imshow("Labels", seeMyLabels);
    imshow("input", image);
    imshow("output", label);
    waitKey(0);

    return 0;
}

Upvotes: 8

Related Questions