2016-07-01 5 views
1

Ich benutze cv :: ximgproc :: SuperpixelSLIC opencv C++, um Segmente des Bildes zu generieren. Ich möchte, dass jedes Segment-Label eindeutig ist. Hier ist mein Code.So finden Sie eindeutige Beschriftungen für Segmente in SuperpixelSLIC

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; 
} 

In label.txt Datei I 0 dieses Label beobachten wurde auf zwei Segmente (dh Segment umfassen Pixel angegeben (0,0) und Pixel (692.442). Diese beiden Segmente sind ziemlich weit weg.

Ist Diese normale Sache oder mein Code ist falsch. Bitte helfen Sie mir, eindeutige Bezeichnung für jedes Segment zu finden.

Antwort

1

Was Sie im Wesentlichen benötigen, ist ein verbundener Komponentenalgorithmus.Trotz der Kenntnis der genauen SLIC-Implementierung, die Sie verwenden, neigt SLIC normalerweise, getrennte Superpixel zu produzieren , dh getrennte Segmente mit dem gleichen Label Eine einfache Lösung, die ich verwendet habe, ist die connec ted Komponenten Algorithmus Formular hier: https://github.com/davidstutz/matlab-multi-label-connected-components (ursprünglich von hier: http://xenia.media.mit.edu/~rahimi/connected/). Beachten Sie, dass dieses Repository einen MatLab-Wrapper enthält. In Ihrem Fall müssen Sie nur connected_components.h zusammen mit dem folgenden Code:

#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; 
} 

Auf den erhaltenen Etiketten, relabelConnectedSuperpixels laufen.

+0

Danke 'David. Übrigens habe ich bereits meinen eigenen Connected-Component-Algorithmus mit DFS aufgeschrieben, um diesen Typ von SLIC-Algorithmus zu entfernen – rajatV