如何在SuperpixelSLIC中找到分段的唯一标签

How to find unique labels for segments in SuperpixelSLIC

本文关键字:分段 唯一 标签 SuperpixelSLIC      更新时间:2023-10-16

我使用cv::ximgproc::SuperpixelSLIC opencvc++来生成图像段。我希望每个段的标签是唯一的。这是我的代码。

Mat segmentImage() {
    int num_iterations = 4;
    int prior = 2;
    bool double_step = false;
    int num_levels = 10;
    int num_histogram_bins = 5;
    int width, height;
    width = h1.size().width;
    height = h1.size().height;
    seeds = createSuperpixelSLIC(h1);
    Mat mask;
    seeds->iterate(num_iterations);
    Mat labels;
    seeds->getLabels(labels);
    for (int i = 0; i < labels.rows; i++) {
        for (int j = 0; j < labels.cols; j++) {
            if (labels.at<int>(i, j) == 0)
                cout << i << " " << j << " " << labels.at<int>(i, j) << endl;
        }
    }
    ofstream myfile;
    myfile.open("label.txt");
    myfile << labels;
    myfile.close();
    seeds->getLabelContourMask(mask, false);
    h1.setTo(Scalar(0, 0, 255), mask);
    imshow("result", h1);
    imwrite("result.png", h1);
    return labels;
}

在label.txt文件中,我观察到标签0已被赋予两个段(即段包括像素(0,0)和像素(692,442))。这两段距离相当远。

这是正常的事情还是我的代码不正确?请帮我找到每个片段的唯一标签

你本质上需要的是一个连接组件算法。如果不知道您使用的确切SLIC实现,SLIC通常倾向于产生断开连接的超像素,即具有相同标签的断开连接的段。我使用的一个简单的解决方案是连接组件算法形式在这里:https://github.com/davidstutz/matlab-multi-label-connected-components(最初从这里:http://xenia.media.mit.edu/~rahimi/connected/)。注意,这个存储库包含一个MatLab包装器。在您的情况下,您只需要connected_components.h和以下代码:

#include "connected_components.h"
// ...
void relabelSuperpixels(cv::Mat &labels) {
    int max_label = 0;
    for (int i = 0; i < labels.rows; i++) {
        for (int j = 0; j < labels.cols; j++) {
            if (labels.at<int>(i, j) > max_label) {
                max_label = labels.at<int>(i, j);
            }
        }
    }
    int current_label = 0;
    std::vector<int> label_correspondence(max_label + 1, -1);
    for (int i = 0; i < labels.rows; i++) {
        for (int j = 0; j < labels.cols; j++) {
            int label = labels.at<int>(i, j);
            if (label_correspondence[label] < 0) {
                label_correspondence[label] = current_label++;
            }
            labels.at<int>(i, j) = label_correspondence[label];
        }
    }
}
int relabelConnectedSuperpixels(cv::Mat &labels) {
    relabelSuperpixels(labels);
    int max = 0;
    for (int i = 0; i < labels.rows; ++i) {
        for (int j = 0; j < labels.cols; ++j) {
            if (labels.at<int>(i, j) > max) {
                max = labels.at<int>(i, j);
            }
        }
    }
    ConnectedComponents cc(2*max);
    cv::Mat components(labels.rows, labels.cols, CV_32SC1, cv::Scalar(0));
    int component_count = cc.connected<int, int, std::equal_to<int>, bool>((int*) labels.data, (int*) components.data, labels.cols, 
            labels.rows, std::equal_to<int>(), false);
    for (int i = 0; i < labels.rows; i++) {
        for (int j = 0; j < labels.cols; j++) {
            labels.at<int>(i, j) = components.at<int>(i, j);
        }
    }
    // component_count would be the NEXT label index, max is the current highest!
    return component_count - max - 1;
}

在获取到的标签中输入relabelConnectedSuperpixels