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

Posted

技术标签:

【中文标题】如何在 SuperpixelSLIC 中查找段的唯一标签【英文标题】:How to find unique labels for segments in SuperpixelSLIC 【发布时间】:2016-07-01 22:54:16 【问题描述】:

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

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)。这两个段相距甚远。

这是正常现象还是我的代码不正确。请帮我找到每个段的唯一标签。

【问题讨论】:

【参考方案1】:

您本质上需要的是一个连通分量算法。在不知道您使用的确切 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

【讨论】:

谢谢大卫。顺便说一句,我已经写下了我自己的使用 DFS 的连接组件算法来删除这种类型的 SLIC 算法

以上是关于如何在 SuperpixelSLIC 中查找段的唯一标签的主要内容,如果未能解决你的问题,请参考以下文章

查找数据段的地址范围

如何在 iOS 中查找文本段范围

mysql如何删除数据库指定ID段的数据库?

如何在 Matlab 中可视化图像段的边界?

连续盈利18季的唯品会,怎么还在找出路?

如何在 iOS 13 的 UISegmentedControl 中更改段的颜色?