2013-06-19 8 views
6

Ich würde gerne wissen, ob es einen schnelleren Weg gibt, als was ich unten getan habe, um die Region Adjazenz Matrix aus einem Wasserscheide Bild zu berechnen.(OpenCV) Schnelle Adjazenz Matrix Berechnung von Wasserscheide

Input: Wendebild mit N Bereichen von 1 bis N gekennzeichnet

Output: Adjazenzmatrix dieser N Regionen.

1. Für jede Region berechnen die entsprechende Maske und legen alle Masken in einen Vektor:

vector<Mat> masks;  
for(int i = 0; i < N; i++) 
{  
// Create the corresponding mask 
Mat mask;  
compare(wshed, i+1, mask, CMP_EQ); 

// Dilate to overlap the watershed line (border) 
dilate(mask, mask, Mat()); 

// Add to the list of masks 
masks.push_back(mask);  
} 

2. eine Funktion definieren, zu prüfen, ob zwei Regionen angrenzen:

bool areAdjacent(const Mat& mask1, const Mat& mask2) 
{ 
    // Get the overlapping area of the two masks 
    Mat m; 
    bitwise_and(mask1, mask2, m); 

    // Compute the size of the overlapping area 
    int size = countNonZero(m); 

    // If there are more than 10 (for example) overlapping pixels, then the two regions are adjacent 
    return (size > 10); 
} 

3. Berechne die Adjazenzmatrix M:, wenn die i-te Region und die j-te Region benachbart sind, dann ist M [i] [j] = M [j] [i] = 1, andererseits ise sind sie auf 0.

Mat M = Mat::zeros(N, N, CV_8U); 
for(int i = 0; i < N-1; i++) 
    { 
     for(int j = i+1; j < N; j++) 
     { 
      if(areAdjacent(masks[i], masks[j])) 
      { 
       M.at<uchar>(i,j) = 1; 
       M.at<uchar>(j,i) = 1; 
      } 
     } 
    } 
    return M;  

Antwort

1

Die gleich folgenden einfachen, aber sehr schnell:

Mat getAdjacencyMatrix(const int* klabels, int width, int height, int K) 
/////* Input: 
////  - int* klabels: the labeled watershed image (the intensity of the watershed lines is -1) 
////  - int K: the number of superpixels (= kmax + 1) 
//// * Output: 
////  - Mat M: the adjacency matrix (M[i][j] = M[i][j] = 1 if the superpixels i and j are adjacent, and = 0 otherwise) 
////*/ 

{ 
    /// Create a KxK matrix and initialize to 0 
    Mat M(K, K, CV_32S, Scalar(0)); 

    /// Scan the labeled image 
    for(int y=1; y < height-1; y++) 
    { 
     for(int x=1; x < width-1; x++) 
     { 
      // Get the label of the current pixel and the ones of its neighbors 
      int k = klabels[y*width + x]; 
      int kleft = klabels[y*width + x - 1]; 
      int kright = klabels[y*width + x + 1]; 
      int kup = klabels[(y-1)*width + x]; 
      int kdown = klabels[(y+1)*width + x]; 
      if(k != kleft) 
      { 
       M.at<int>(k,kleft) =1; 
       M.at<int>(kleft,k) =1; 
      } 
      if(k != kright) 
      { 
       M.at<int>(k,kright) =1; 
       M.at<int>(kright,k) =1; 
      } 
      if(k != kup) 
      { 
       M.at<int>(k,kup) =1; 
       M.at<int>(kup,k) =1; 
      } 
      if(k != kdown) 
      { 
       M.at<int>(k,kdown) =1; 
       M.at<int>(kdown,k) =1; 
      } 
     } 
    } 

    return M; 
}