Ask Your Question

Revision history [back]

click to hide/show revision 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:

  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.
  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)
        {
            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);
            }
        }
    }
}

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.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)
        {
            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);
            }
        }
    }
}