1

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 が 2 つのセグメント (ピクセル (0,0) とピクセル (692,442) を含むセグメント) に付与されていることがわかります。これらの 2 つのセグメントはかなり離れています

これは正常なことですか、それとも私のコードが間違っていますか。各セグメントに固有のラベルを見つけるのを手伝ってください。

4

1 に答える 1

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ます。

于 2016-09-02T14:10:41.887 に答える