1 | initial version |
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. So:
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.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)
{
if (mask.at<unsigned char>(r, c))
{
tmp.at<cv::Vec3f>(counter++, 0) = src.at<cv::Vec3b>(r, c);
}
}
}
Mat labels;
kmeans(tmp, k, labels, TermCriteria(), 1, KMEANS_RANDOM_CENTERS);
dst = cv::Mat(mask.size(), CV_32S, k);
counter = 0;
for (int r = 0; r < mask.rows; ++r)
{
for (int c = 0; c < mask.cols; ++c)
{
if (mask.at<unsigned char>(r, c))
{
dst.at<int>(r, c) = labels.at<int>(counter++, 0);
}
}
}
}
2 | No.2 Revision |
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:
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 cv::Mat mask = (labelImage == k)
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)
{
if (mask.at<unsigned char>(r, c))
{
tmp.at<cv::Vec3f>(counter++, 0) = src.at<cv::Vec3b>(r, c);
}
}
}
Mat labels;
kmeans(tmp, k, labels, TermCriteria(), 1, KMEANS_RANDOM_CENTERS);
dst = cv::Mat(mask.size(), CV_32S, k);
counter = 0;
for (int r = 0; r < mask.rows; ++r)
{
for (int c = 0; c < mask.cols; ++c)
{
if (mask.at<unsigned char>(r, c))
{
dst.at<int>(r, c) = labels.at<int>(counter++, 0);
}
}
}
}