# Marker based watershed not working as expected

I am trying to apply watershed segmentation of a given input image which can be seen below.

I first start by applying a filling function, so that the small inner black dots get removed. This result can be seen below.

Based on an object detector ( which I trained seperately, and of which the centers coincide with a given blob) I plot a marker set, as seen below. For this is use simple circles.

Do note that there is a very small marker at the top left corner, which is placed there to ensure that the background is also a blob that is being created. Now I use the following functionality.

watershed(color_watershed, markers);
// Show the watershed result
// Generate random colors
std::vector<cv::Vec3b> colors;
for (int i = 0; i < centers.size(); i++)
{
int b = theRNG().uniform(0, 255);
int g = theRNG().uniform(0, 255);
int r = theRNG().uniform(0, 255);

colors.push_back(cv::Vec3b((uchar)b, (uchar)g, (uchar)r));
}
// Create the result image
Mat dst = cv::Mat::zeros(markers.size(), CV_8UC3);

// Fill labeled objects with random colors
for (int i = 0; i < markers.rows; i++)
{
for (int j = 0; j < markers.cols; j++)
{
int index = markers.at<int>(i,j);
if (index > 0 && index <= centers.size())
dst.at<Vec3b>(i,j) = colors[index-1];
else
dst.at<Vec3b>(i,j) = Vec3b(0,0,0);
}
}


But for some reason the output stays completely black, instead of colored blobs as I would have been expecting from the many tutorials out there ... which I did not expect. Anyone has an idea on what is going wrong?

edit retag close merge delete

Also let me note that you can ignore the fact that blobs are split and stuff like that, I just want the result of the given watershed...

( 2015-09-15 06:42:23 -0500 )edit

Sort by » oldest newest most voted

Solution found myself ... It seems that you need to place a different value for each marker, if all markers have the same value, then it will try to create one big region, in which it fails. So it comes down to when creating the markers, which I did by

Mat markers  = Mat::zeros(threshold_BW.rows, threshold_BW.cols, CV_8UC1);
for(int i = 0; i < centers.size(); i++){
circle(markers, centers[i], 5, 255, CV_FILLED);
}


Which should be

Mat markers  = Mat::zeros(threshold_BW.rows, threshold_BW.cols, CV_8UC1);
for(int i = 0; i < centers.size(); i++){
circle(markers, centers[i], 5, i+1, CV_FILLED);
}


Then the result looks like

more

Official site

GitHub

Wiki

Documentation