@图像处理_距离变换_c++代码实现
距离变换:
分为:欧式距离,城区距离,棋盘距离。
算法步骤:
- 输入:二值图像。
- 从图像左上角第二行开始,从左向右、从上到下移动窗口扫描每个像素,类似滤波过程,检测在中心像素P的周围四个像素与中心像素的距离,若中心像素为0,则跳过。保存最小距离与位置作为结果。
- 从右下角倒数第二行开始,从右向左,从下到上扫描图像。其它同2。
- 输出图像。
代码如下:
/*created at 2019/4/11*/
#include <iostream>
#include <algorithm>
#include <opencv2/opencv.hpp>
void distance_transform_3x3(cv::Mat& src)
{
int rows = src.rows;
int cols = src.cols;
float sum[5];
/*第一次扫描*/
for(int r = 1; r < rows - 1; ++r)
{
for(int c = 1; c < cols - 1; ++c)
{
if(src.at<uchar>(r,c))
{
sum[0] = 1.4142 + src.at<uchar>(r-1,c-1);
sum[1] = 1 + src.at<uchar>(r-1, c);
sum[2] = 1.4142 + src.at<uchar>(r-1,c+1);
sum[3] = 1 + src.at<uchar>(r, c-1);
sum[4] = src.at<uchar>(r, c);
std::sort(sum, sum+5);
src.at<uchar>(r,c) = sum[0];
}
}
}
/*第二次扫描*/
for(int r = rows - 1; r > 0; --r)
{
for(int c = cols - 1; c > 0; --c)
{
if(src.at<uchar>(r,c))
{
sum[0] = src.at<uchar>(r, c);
sum[1] = 1 + src.at<uchar>(r, c+1);
sum[2] = 1.4142 + src.at<uchar>(r+1,c-1);
sum[3] = 1 + src.at<uchar>(r+1, c);
sum[4] = 1.4142 + src.at<uchar>(r+1,c+1);
std::sort(sum, sum+5);
src.at<uchar>(r,c) = sum[0];
}
}
}
}
int main(int argc, char* argv[])
{
cv::Mat src = cv::imread("test.jpg");
distance_transform_3x3(src );
cv::imshow("out.jpg", src );
cv::waitKey(0);
return 0;
}
原图:
输出: