Clusterization in OpenCV

I have a two questions about clusterization in OpenCV. I'm using kmeans clustering.

• How to get mask of each post-clusterized layer of image? To understand this question I want to show an example. If I clusterize image on 3 clusters and after clusterisation I have this image:

(white is first cluster, gray is second and black - third).

So after splitting my aim is to get these three masks:

White: , gray: and black: .

• What is the fastest way to clusterize only some part of image (I have two images - original image and mask image)? So, for example, if I clusterize image on n clusters after clusterization with mask I want to have n+1 cluster (+1 because of mask).

I'm looking for the fastest solutions of these problems.

edit retag close merge delete

Sort by ยป oldest newest most voted

I decided to answer my own question. On the first question I found answer by myself, and solution to the second question from my question on StackOverflow. Thanks @remi. So:

1. It seems that inRange with special parameters will help me to achieve this, but the problem is that in this solution I will have call it k times, so simple iterating with check will do the trick. Also I can use check:

cv::Mat mask = (labelImage == k)

2. Here's full code (maybe someone will find it useful):

void kmeansMask(const Mat& src, const Mat& mask, const int k, Mat& dst)
{
Mat tmp = Mat::zeros(countNonZero(mask), 1, CV_8UC3);
int counter = 0;
for (int r = 0; r < mask.rows; ++r)
{
for (int c = 0; c < mask.cols; ++c)
{
{
tmp.at<cv::Vec3f>(counter++, 0) = src.at<cv::Vec3b>(r, c);
}
}
}

Mat labels;
kmeans(tmp, k, labels, TermCriteria(), 1, KMEANS_RANDOM_CENTERS);

counter = 0;
for (int r = 0; r < mask.rows; ++r)
{
for (int c = 0; c < mask.cols; ++c)
{
{
dst.at<int>(r, c) = labels.at<int>(counter++, 0);
}
}
}
}

more