2016-07-01 1 views
1

J'utilise cv :: ximgproc :: SuperpixelSLIC opencv C++ pour générer des segments d'image. Je veux que chaque étiquette de segment soit unique. Voici mon code.Comment trouver des étiquettes uniques pour des segments dans 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; 
} 

Dans le fichier label.txt je remarque que l'étiquette 0 a été donné à deux segments (c.-à-segment comprennent les pixels (0,0) et pixel (692442). Ces deux segments sont assez loin.

Est S'il vous plaît aidez-moi à trouver une étiquette unique pour chaque segment

Répondre

1

Ce dont vous avez essentiellement besoin est un algorithme de composants connectés.Sans connaître l'implémentation SLIC exacte que vous utilisez, SLIC a tendance à produire des superpixels déconnectés. , c'est-à-dire des segments déconnectés avec la même étiquette, une solution simple forme de l'algorithme des composants ted ici: https://github.com/davidstutz/matlab-multi-label-connected-components (originaire d'ici: http://xenia.media.mit.edu/~rahimi/connected/). Notez que ce référentiel contient un wrapper MatLab. Dans votre cas, vous avez seulement besoin connected_components.h en même temps que le code suivant:

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

Sur les étiquettes obtenues, exécutez relabelConnectedSuperpixels.

+0

Merci David. Btw J'ai déjà écrit mon propre algorithme de composants connectés en utilisant DFS pour supprimer ce type d'algorithme SLIC – rajatV