3.3.4 距离变换-扫描

  1 //////https://blog.csdn.net/gone_huilin/article/details/53223026
  2 #include <opencv2/imgproc/imgproc.hpp>  
  3 #include <opencv2/core/core.hpp>        
  4 #include <opencv2/highgui/highgui.hpp> 
  5 #include <iostream> 
  6 // 计算欧式距离
  7 float calcEuclideanDistance(int x1, int y1, int x2, int y2)
  8 {
  9     return sqrt(float((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)));
 10 }
 11 // 计算棋盘距离
 12 int calcChessboardDistance(int x1, int y1, int x2, int y2)
 13 {
 14     return cv::max(abs(x1 - x2), abs(y1 - y2));
 15 }
 16 // 计算街区距离
 17 int calcBlockDistance(int x1, int y1, int x2, int y2)
 18 {
 19     return abs(x1 - x2) + abs(y1 - y2);
 20 }
 21 // 距离变换函数实现
 22 void distanceTrans(cv::Mat &srcImage, cv::Mat &resultIamge)
 23 {
 24     CV_Assert(srcImage.data != NULL);
 25     cv::Mat srcGray, srcBinary;
 26     // 转换成灰度图像
 27     cv::cvtColor(srcImage, srcGray, CV_RGB2GRAY);
 28     // 转换成二值图像
 29     threshold(srcGray, srcBinary, 100, 255, cv::THRESH_BINARY);
 30     cv::imshow("srcBinary", srcBinary);
 31     int rows = srcBinary.rows;
 32     int cols = srcBinary.cols;
 33     uchar* pDataOne;
 34     uchar* pDataTwo;
 35     float disPara = 0;
 36     float fDisMin = 0;
 37     // 第一遍遍历图像用左模板更新像素值
 38     for (int i = 1; i < rows - 1; i++)
 39     {
 40         // 图像指针获取
 41         pDataOne = srcBinary.ptr<uchar>(i);
 42         for (int j = 1; j < cols; j++)
 43         {
 44             // 分别计算其左模板掩码相关距离
 45             //   pL  pL
 46             //   pL  p
 47             //   pL
 48             pDataTwo = srcBinary.ptr<uchar>(i - 1);
 49             disPara = calcEuclideanDistance(i, j, i - 1, j - 1);
 50             fDisMin = cv::min((float)pDataOne[j],
 51                 disPara + pDataTwo[j - 1]);
 52             disPara = calcEuclideanDistance(i, j, i - 1, j);
 53             fDisMin = cv::min(fDisMin,
 54                 disPara + pDataTwo[j]);
 55             pDataTwo = srcBinary.ptr<uchar>(i);
 56             disPara = calcEuclideanDistance(i, j, i, j - 1);
 57             fDisMin = cv::min(fDisMin,
 58                 disPara + pDataTwo[j - 1]);
 59             pDataTwo = srcBinary.ptr<uchar>(i + 1);
 60             disPara = calcEuclideanDistance(i, j, i + 1, j - 1);
 61             fDisMin = cv::min(fDisMin,
 62                 disPara + pDataTwo[j - 1]);
 63             pDataOne[j] = (uchar)cvRound(fDisMin);
 64         }
 65     }
 66     // 第二遍遍历图像用右模板更新像素值
 67     for (int i = rows - 2; i > 0; i--)
 68     {
 69         pDataOne = srcBinary.ptr<uchar>(i);
 70         for (int j = cols - 1; j >= 0; j--)
 71         {
 72             // 分别计算其右模板掩码相关距离 
 73             //   pR  pR
 74             //   pR  p
 75             //   pR     
 76             pDataTwo = srcBinary.ptr<uchar>(i + 1);
 77             disPara = calcEuclideanDistance(i, j, i + 1, j);
 78             fDisMin = cv::min((float)pDataOne[j],
 79                 disPara + pDataTwo[j]);
 80             disPara = calcEuclideanDistance(i, j, i + 1, j + 1);
 81             fDisMin = cv::min(fDisMin,
 82                 disPara + pDataTwo[j + 1]);
 83             pDataTwo = srcBinary.ptr<uchar>(i);
 84             disPara = calcEuclideanDistance(i, j, i, j + 1);
 85             fDisMin = cv::min(fDisMin,
 86                 disPara + pDataTwo[j + 1]);
 87             pDataTwo = srcBinary.ptr<uchar>(i - 1);
 88             disPara = calcEuclideanDistance(i, j, i - 1, j + 1);
 89             fDisMin = cv::min(fDisMin,
 90                 disPara + pDataTwo[j + 1]);
 91             pDataOne[j] = (uchar)cvRound(fDisMin);
 92         }
 93     }
 94     resultIamge = srcBinary.clone();
 95 }
 96 int main()
 97 {
 98     cv::Mat srcImage = cv::imread("D:\\沙漠.jpg");
 99     if (!srcImage.data)
100         return -1;
101     cv::Mat resultIamge;
102     distanceTrans(srcImage, resultIamge);
103     cv::imshow("resultIamge", resultIamge);
104     cv::waitKey(0);
105     return 0;
106 }
View Code

相关文章:

  • 2021-12-29
  • 2022-12-23
  • 2022-12-23
  • 2022-01-12
  • 2022-12-23
  • 2021-05-18
  • 2021-05-09
  • 2021-07-14
猜你喜欢
  • 2021-04-09
  • 2022-12-23
  • 2021-08-25
  • 2021-08-20
  • 2021-05-14
  • 2022-12-23
  • 2021-09-07
相关资源
相似解决方案