距离变换:

Distance transform :

本文关键字:变换 距离      更新时间:2023-10-16

请帮助我进行距离变换并纠正错误。我尝试过博尔赫福斯的方法,该方法定义了欧几里得测度的值。我得到所有零作为输出。

以下是我尝试过的代码。

int _tmain(int argc, _TCHAR* argv[])
{
    Mat v = imread("ref.png", 0);
    imshow("input", v);
    Mat forward = (Mat_<uchar>(5, 5) << 0, 11, 0, 11, 0, 11, 7, 5, 7, 11, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
    Mat backward = (Mat_<uchar>(5, 5) << 0,0,0,0,0, 0,0,0,0,0, 0, 0, 0, 5, 0,  11, 7, 5, 7, 11,  0, 11, 0, 11, 0);
    Mat op = cv::Mat::zeros(v.size(), CV_32FC1);
    cout << forward;
    cout << backward;
    int r = v.rows; 
    int c = v.cols;
    float min=100, x = 0;
    int size = 3;
    int lim = size / 2;
    int a, b;
    for (int i = lim; i <= r-1-lim; i++)
    {
        for (int j = lim; j <= c-1-lim; j++)
        {
            for (int k = -lim; k <= lim; k++)
            {
                for (int l = -lim; l <= lim; l++)
                {
                    a = (v.at<uchar>(i + k, j + l));
                    b=(forward.at<uchar>(k + lim, l + lim));
                    x = a + b;
                    if (x>0 && min> x) 
                        min = x;
                }
            }
            op.at<float>(i, j) = min;
        }
    }
cout << min;
for (int i = (r-1-lim); i >lim; i--)
{
    for (int j = (c-1-lim); j >lim; j--)
    {
        for (int k = -lim; k <= lim; k++)
        {
            for (int l = -lim; l <= lim; l++)
            {
                a = (v.at<uchar>(i + k, j + l));
                b = (forward.at<uchar>(k + lim, l + lim));
                x = a + b;
                if (x >0 && min> x) min = x;
            }
        }
        op.at<float>(i, j) = min;
    }
}
cout << op;

Mat res = cv::Mat::ones(v.size(), CV_8UC1);
normalize(op, res, 0, 255, NORM_MINMAX);
imshow("output",res);
waitKey(0);
return 0;

}

哪种方法最好,为什么它是实现距离变换的最佳方法?

以下是修复代码的方法:

    在向后循环中应用
  1. 向后蒙版,您将在那里应用与在向前循环中相同的蒙版。

  2. 仅使用定义的权重,掩码中写入 0 的值不是掩码的一部分。这些像素的距离不是 0!

至于你的第二个问题,它可能超出了SO的范围。但最好的方法是什么很大程度上取决于目标。您这里有一种快速且相对准确的方法,还有其他精确但更昂贵的方法。