8

流域画像から領域隣接行列を計算するために、以下で行った方法よりも高速な方法があるかどうかを知りたいです。

入力: 1 から N までのラベルが付いた N 領域を含む流域画像。

出力: これらの N 領域の隣接行列。

1. 各領域について、対応するマスクを計算し、すべてのマスクをベクトルに入れます。

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. 2 つの領域が隣接しているかどうかをチェックする関数を定義します。

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. 隣接行列 M を計算します。i 番目の領域と j 番目の領域が隣接している場合、M[i][j] = M[j][i] =1、そうでない場合は 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;    
4

1 に答える 1

3

以下は単純ですが、非常に高速です。

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;
}
于 2016-01-13T14:53:24.510 に答える