【问题标题】:OpenCV: Computing superpixel centroidsOpenCV:计算超像素质心
【发布时间】:2015-12-27 15:47:12
【问题描述】:

背景:

我使用gSLICr 计算了图像的 SLIC 超像素,它给出了图像超像素的“每像素图”作为索引(0 到超像素的数量-1)。

此映射是指向包含索引的整数 const 数组 (const int*) 的指针。

我现在想使用 OpenCV 计算每个超像素的质心。

来自 Matlab 背景,我会使用regionprops

segments = vl_slic(myImage, regionSize, regularizer);
stats = regionprops(segments, 'Centroid');
centroids = cat(1, stats.Centroid);

我不知道这是如何使用 OpenCV 完成的。

问题:

(i) 如何将 const int* 数组转换为 cv::Mat

(ii) 如何从 (i) 中的矩阵计算超像素质心?

【问题讨论】:

  • 看看this。应该回答你的第一个问题
  • cv::Mat supercell = ppixelMap == spIndex;将为您提供包含该单个超像素的所有像素的蒙版。
  • 你的第二个问题:一旦你有了标签的图像,你可以使用connectedComponentsWithStats 来获取质心(你在 OpenCV 3.0 上使用,对吧?)。

标签: c++ opencv centroid superpixels


【解决方案1】:

由于第一个问题似乎已经回答,我将重点关注您的第二个问题。我使用以下代码计算每个超像素的平均坐标(即空间质心):

/** \brief Compute the mean coordinates of each superpixel (i.e. spatial centroids).
 * \param[in] labels a matrix of type CV_32SC1 holding the labels for each pixel
 * \param[out] means the spatial centroids (or means in y and x axes) of the superpixels
 */
void getMeans(const cv::Mat &labels, std::vector<cv::Vec2f> &means) {

    // Count superpixels or get highest superpixel index:
    int superpixels = 0;
    for (int i = 0; i < labels.rows; ++i) {
        for (int j = 0; j < labels.cols; ++j) {
            if (labels.at<int>(i, j) > superpixels) {
                superpixels = labels.at<int>(i, j);
            }
        }
    }

    superpixels++;

    // Setup means as zero vectors.
    means.clear();
    means.resize(superpixels);
    for (int k = 0; k < superpixels; k++)
    {
        means[k] = cv::Vec2f(0, 0);
    }

    std::vector<int> counts(superpixels, 0);

    // Sum y and x coordinates for each superpixel:
    for (int i = 0; i < labels.rows; ++i) {
        for (int j = 0; j < labels.cols; ++j) {
            means[labels.at<int>(i, j)][0] += i; // for computing mean i (i.e. row or y axis)
            means[labels.at<int>(i, j)][1] += j; // for computing the mean j (i.e. column or x axis)

            counts[labels.at<int>(i, j)]++;
        }
    }

    // Obtain averages by dividing by the size (=number of pixels) of the superpixels.
    for (int k = 0; k < superpixels; ++k) {
        means[k] /= counts[k];
    }
}

// Do something with the means ...

如果您还需要平均颜色,该方法将需要图像作为参数,但剩下的代码可以很容易地用于计算平均颜色。

【讨论】:

    猜你喜欢
    • 2019-05-12
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2022-11-21
    • 2018-03-02
    • 2012-02-22
    相关资源
    最近更新 更多