(OpenCV) Quickly calculate adjacency matrix from a watershed

I would like to know if there is a faster way than what I did below to calculate the adjacency matrix of the area from the watershed image.

Input: image of the watershed with N areas marked from 1 to N.

Output: The adjacency matrix of these N regions.

1. For each area, calculate the corresponding mask and put all the masks in the vector:

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. Define a function to check if two areas are adjacent:

 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. Calculate the adjacency matrix M: if the ith region and the jth region are adjacent, then M [i] [j] = M [j] [i] = 1, otherwise they are 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; 
+6
source share
1 answer

The following are simple but very fast:

 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; } 
+1
source

Source: https://habr.com/ru/post/947632/


All Articles