2015-09-30 1 views
0

Contexte:OpenCV: calcul des centroïdes de superpixel

je l'ai calculé SLIC superpixels d'une image en utilisant gSLICr, ce qui donne une "carte par pixel" de superpixels d'image sous forme d'indices (0 au nombre de superpixels-1).

Cette carte est un pointeur vers un tableau const entier (const int*) contenant les indices.

Je veux maintenant calculer les centroïdes de chaque superpixel en utilisant OpenCV.

Issu d'un milieu Matlab, je ferais cela en utilisant regionprops:

segments = vl_slic(myImage, regionSize, regularizer); 
stats = regionprops(segments, 'Centroid'); 
centroids = cat(1, stats.Centroid); 

Je ne sais pas comment cela se fait en utilisant OpenCV.

Questions:

(i) Comment puis-je convertir un tableau const int* à un cv::Mat? (Ii) Comment calculer les centroïdes du superpixel à partir de la matrice dans (i)?

+0

Jetez un coup d'œil à [this] (http://stackoverflow.com/a/32844661/5008845). Devrait répondre à votre première question – Miki

+0

cv :: Mat supercell = ppixelMap == spIndex; vous donnera un masque avec tous les pixels de ce superpixel unique. – Micka

+0

Votre deuxième question: une fois que vous avez l'image des étiquettes, vous pouvez utiliser [connectedComponentsWithStats] (http://docs.opencv.org/master/d3/dc0/group__imgproc__shape.html#gae57b028a2b2ca327227c2399a9d53241&gsc.tab=0) pour obtenir des centroïdes (vous utilisez sur OpenCV 3.0, n'est-ce pas?). – Miki

Répondre

0

Comme la première question semble être résolue, je vais me concentrer sur votre deuxième question. J'ai utilisé le code suivant pour calculer les coordonnées moyennes (c.-à-centroïdes spatiales) de chaque superpixel:

/** \brief Compute the mean coordinates of each superpixel (i.e. spatial centroids). 
* \param[in] labels a matrix of type CV_32SC1 holding the labels for each pixel 
* \param[out] means the spatial centroids (or means in y and x axes) of the superpixels 
*/ 
void getMeans(const cv::Mat &labels, std::vector<cv::Vec2f> &means) { 

    // Count superpixels or get highest superpixel index: 
    int superpixels = 0; 
    for (int i = 0; i < labels.rows; ++i) { 
     for (int j = 0; j < labels.cols; ++j) { 
      if (labels.at<int>(i, j) > superpixels) { 
       superpixels = labels.at<int>(i, j); 
      } 
     } 
    } 

    superpixels++; 

    // Setup means as zero vectors. 
    means.clear(); 
    means.resize(superpixels); 
    for (int k = 0; k < superpixels; k++) 
    { 
     means[k] = cv::Vec2f(0, 0); 
    } 

    std::vector<int> counts(superpixels, 0); 

    // Sum y and x coordinates for each superpixel: 
    for (int i = 0; i < labels.rows; ++i) { 
     for (int j = 0; j < labels.cols; ++j) { 
      means[labels.at<int>(i, j)][0] += i; // for computing mean i (i.e. row or y axis) 
      means[labels.at<int>(i, j)][1] += j; // for computing the mean j (i.e. column or x axis) 

      counts[labels.at<int>(i, j)]++; 
     } 
    } 

    // Obtain averages by dividing by the size (=number of pixels) of the superpixels. 
    for (int k = 0; k < superpixels; ++k) { 
     means[k] /= counts[k]; 
    } 
} 

// Do something with the means ... 

Si vous avez aussi besoin de la couleur moyenne, la méthode nécessiterait l'image comme argument, mais le reste du code peut facilement être adapté pour calculer les couleurs moyennes.