Watershed problems.

Hello everyone. I would very much appreciate if you take a look at my code and point me what I am doing wrong :(

The story is this. There is an image of some coins. I take the background and the foreground. Paint the background in grey and the foreground in white. Then apply watershed. As a result I got the border of the coins. (I know that is not the final objective but allow me)

Then I modify the code to change the foreground. I get borders of this and get a new foreground *that seems to be exactly the same as * the previous foreground. However when I apply the watershed the results are totally different.

WHY??

In the image you can see the first result in the middle and the second result to the left.

Now here is my code

    #include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
char* filename = argc >= 2 ? argv[1] : (char*)"water_coins.jpg";

if(!image.data) {
return 0;
}
//Display the image
imshow("Original Image", image);

//Get the binary map
Mat gray,binary;
cvtColor(image,gray,COLOR_BGR2GRAY);
//  threshold(gray,binary,60,255,THRESH_BINARY_INV);
threshold(gray,binary,0,255,THRESH_BINARY_INV+THRESH_OTSU);

//Display the binary image
imshow("Binary Image",binary);

//Identify Image pixels without objects and asign it grey (128) (sure background)
Mat bg;
dilate(binary,bg,Mat(),Point(-1,-1),6);
threshold(bg,bg,1,128,THRESH_BINARY_INV);

imshow("Background Image",bg);

//Now we have to find sure foreground
//First we erode the image

Mat fg;
erode(binary,fg,Mat(),Point(-1,-1),10);
imshow("Foreground Image",fg);

//then find the contours (We use a clone because findContours modifies the original image passed to it
Mat fg_clone=fg.clone();

vector<vector<Point> > contours;
vector<Vec4i> hierarchy;

findContours(fg_clone, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

Mat cnt_img = Mat::zeros(image.rows, image.cols, CV_8UC1);

drawContours(cnt_img, contours, -1, Scalar(255,255,255),
-1, CV_AA, hierarchy);
//   drawContours(cnt_img, contours, -1, Scalar(128,255,255),
//                 3, CV_AA, hierarchy);

//   for(int idx = 0; idx < contours.size(); idx++)
//      drawContours(cnt_img, contours, idx, Scalar::all(idx + 1), -1, CV_AA);

imshow("contours", cnt_img);

cout << "Extracted " << contours.size() << " contours" << endl;

//Try and erase later

//Combine the images
Mat markers(binary.size(),CV_8U,Scalar(0));
markers= fg+bg;         //THIS produces result #1
//markers= cnt_img+bg;  //THIS produces result #2

imshow("Markers",markers);

int count=contours.size();
//watershed

Mat markerIm;
markers.convertTo(markerIm,CV_32SC1);

watershed(image,markerIm);

vector<Vec3b> colorTab;
for(int i = 0; i < (contours.size()+1); i++) {
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);

colorTab.push_back(Vec3b((uchar)b, (uchar)g, (uchar)r));
}

// watershed output image
Mat wshed(markerIm.size(), CV_8UC3);

// paint the watershed output image
for(int i = 0; i < markerIm.rows; i++)
for(int j = 0; j < markerIm.cols; j ...
edit retag close merge delete