# 距离变换–扫描

### 一：相关原理

1.将输入图片转换为二值图像，前景设置为1，背景设置为0；

1. 水平集
2. 快速斜切匹配
3. 图像拼接
4. 图像混合的羽化
5. 临近点配准

### 二:示例代码：

#include <iostream>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
using namespace cv;

//计算欧式距离
float calcEuclideanDistance(int x1, int y1, int x2, int y2)
{
return sqrt(float((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)));
}

//计算棋盘距离
int calcChessboardDistance(int x1, int y1, int x2, int y2)
{
return max(abs(x1 - x2), abs(y1 - y2));
}

//计算街区距离
int calcBlockDistance(int x1, int y1, int x2, int y2)
{
return abs(x1 - x2) + abs(y1 - y2);
}

//实现距离变换的函数
void distanceTrans(Mat &srcImage, Mat &resultImage)
{
Mat srcGray, srcBinary;
cvtColor(srcImage, srcGray, CV_BGR2GRAY);
threshold(srcGray, srcBinary, 130, 255, THRESH_BINARY_INV); //视情况选择THRESH_BINARY
imshow("srcBinary", srcBinary);
int rows = srcBinary.rows;
int cols = srcBinary.cols;
uchar *pDataOne;
uchar *pDataTwo;
float disPara = 0.0;
float fDisMin = 0.0;

for (int i = 1; i < rows - 1; i++)
{

pDataOne = srcBinary.ptr<uchar>(i);
for (int j = 1; j < cols; j++)
{

pDataTwo = srcBinary.ptr<uchar>(i - 1);
disPara = calcEuclideanDistance(i, j, i - 1, j - 1);

fDisMin = min((float)pDataOne[j], disPara + pDataTwo[j - 1]);

disPara = calcEuclideanDistance(i, j, i - 1, j);

fDisMin = min(fDisMin, disPara + pDataTwo[j]);

pDataTwo = srcBinary.ptr<uchar>(i);
disPara = calcEuclideanDistance(i, j, i, j - 1);
fDisMin = min(fDisMin, disPara + pDataTwo[j - 1]);

pDataTwo = srcBinary.ptr<uchar>(i+1);
disPara = calcEuclideanDistance(i, j, i + 1, j - 1);
fDisMin = min(fDisMin, disPara + pDataTwo[j - 1]);
pDataOne[j] = (uchar)cvRound(fDisMin);
}
}

for (int i = rows - 2; i > 0; i--)
{

pDataOne = srcBinary.ptr<uchar>(i);
for (int j = cols - 1; j > 0; j--)
{

pDataTwo = srcBinary.ptr<uchar>(i + 1);
disPara = calcEuclideanDistance(i, j, i + 1, j);

fDisMin = min((float)pDataOne[j], disPara + pDataTwo[j]);

disPara = calcEuclideanDistance(i, j, i + 1, j + 1);

fDisMin = min(fDisMin, disPara + pDataTwo[j + 1]);

pDataTwo = srcBinary.ptr<uchar>(i);
disPara = calcEuclideanDistance(i, j, i, j + 1);
fDisMin = min(fDisMin, disPara + pDataTwo[j + 1]);

pDataTwo = srcBinary.ptr<uchar>(i - 1);
disPara = calcEuclideanDistance(i, j, i - 1, j + 1);
fDisMin = min(fDisMin, disPara + pDataTwo[j + 1]);
pDataOne[j] = (uchar)cvRound(fDisMin);
}
}
resultImage = srcBinary.clone();
}
int main()
{
Mat srcImage = imread("test.jpg");
if (!srcImage.data)
{
printf("could not load image...\n");
return -1;
}

Mat resultImage;
distanceTrans(srcImage, resultImage);
imshow("resultImage", resultImage);
waitKey(0);
return 0;
}  

### 三：距离函数

bw = zeros(200,200); bw(50,50) = 1; bw(50,150) = 1;
bw(150,100) = 1;
D1 = bwdist(bw,'euclidean');
D2 = bwdist(bw,'cityblock');
D3 = bwdist(bw,'chessboard');
D4 = bwdist(bw,'quasi-euclidean');
figure
subplot(2,2,1), subimage(mat2gray(D1)), title('Euclidean')
hold on, imcontour(D1)
subplot(2,2,2), subimage(mat2gray(D2)), title('City block')
hold on, imcontour(D2)
subplot(2,2,3), subimage(mat2gray(D3)), title('Chessboard')
hold on, imcontour(D3)
subplot(2,2,4), subimage(mat2gray(D4)), title('Quasi-Euclidean')
hold on, imcontour(D4)  

• 广告
• 抄袭
• 版权
• 政治
• 色情
• 无意义
• 其他

120