• 3.3 距离变换


    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

    应用:

    https://blog.csdn.net/dan1900/article/details/16989023

    https://blog.csdn.net/augusdi/article/details/9022077

    https://blog.csdn.net/u014751607/article/details/61919706

    https://blog.csdn.net/qq_34784753/article/details/68951918?locationNum=8&fps=1

    https://blog.csdn.net/guoruijiushiwo/article/details/72841482

    3.3.5 距离变换-distanceTransform

    Opencv中distanceTransform方法用于计算图像中每一个非零点距离离自己最近的零点的距离,distanceTransform的第二个Mat矩阵参数dst保存了每一个点与最近的零点的距离信息,图像上越亮的点,代表了离零点的距离越远。

     1 ////////https://blog.csdn.net/gone_huilin/article/details/53223066
     2 #include <opencv2/imgproc/imgproc.hpp>  
     3 #include <opencv2/core/core.hpp>        
     4 #include <opencv2/highgui/highgui.hpp> 
     5 #include <iostream> 
     6 int main()
     7 {
     8     cv::Mat srcImage = cv::imread("D:\六角星.jpg");
     9     if (!srcImage.data)
    10         return -1;
    11     // 转换为灰度图像
    12     cv::Mat srcGray;
    13     cvtColor(srcImage, srcGray, CV_BGR2GRAY);
    14     // 转换为二值图像
    15     cv::Mat srcBinary;
    16     threshold(srcGray, srcBinary, 160, 255, cv::THRESH_BINARY);
    17     // 距离变换
    18     cv::Mat dstImage;
    19     cv::distanceTransform(srcBinary, dstImage, CV_DIST_L2,
    20         CV_DIST_MASK_PRECISE);
    21     // 归一化矩阵
    22     cv::normalize(dstImage, dstImage, 0, 1., cv::NORM_MINMAX);
    23     cv::imshow("srcBinary", srcBinary);
    24     cv::imshow("dstImage", dstImage);
    25     cv::waitKey(0);
    26     return 0;
    27 }
    View Code

     1 #include "core/core.hpp"
     2 #include "imgproc/imgproc.hpp"
     3 #include "highgui/highgui.hpp"
     4 
     5 using namespace cv;
     6 
     7 int main(int argc, char *argv[])
     8 {
     9     float maxValue = 0;  //定义距离变换矩阵中的最大值
    10     //Mat image = imread(argv[1]);
    11     Mat image = imread("D:\字母ABCD.jpg");
    12     Mat imageGray;
    13     cvtColor(image, imageGray, CV_RGB2GRAY);
    14     imageGray = ~imageGray;  //取反
    15     GaussianBlur(imageGray, imageGray, Size(5, 5), 2); //滤波
    16     threshold(imageGray, imageGray, 20, 200, CV_THRESH_BINARY); //阈值
    17     imshow("s", imageGray);
    18     Mat imageThin(imageGray.size(), CV_32FC1); //定义保存距离变换结果的Mat矩阵
    19     distanceTransform(imageGray, imageThin, CV_DIST_L2, 3);  //距离变换
    20     Mat distShow;
    21     distShow = Mat::zeros(imageGray.size(), CV_8UC1); //定义细化后的字符轮廓
    22     for (int i = 0; i<imageThin.rows; i++)
    23     {
    24         for (int j = 0; j<imageThin.cols; j++)
    25         {
    26             if (imageThin.at<float>(i, j)>maxValue)
    27             {
    28                 maxValue = imageThin.at<float>(i, j);  //获取距离变换的极大值
    29             }
    30         }
    31     }
    32     for (int i = 0; i<imageThin.rows; i++)
    33     {
    34         for (int j = 0; j<imageThin.cols; j++)
    35         {
    36             if (imageThin.at<float>(i, j)>maxValue / 1.9)
    37             {
    38                 distShow.at<uchar>(i, j) = 255;   //符合距离大于最大值一定比例条件的点设为255
    39             }
    40         }
    41     }
    42     imshow("Source Image", image);
    43     imshow("Thin Image", distShow);
    44     waitKey();
    45     return 0;
    46 }
    View Code

     1 ////////distanceTransform应用:查找物体质心
     2 ////////https://blog.csdn.net/dcrmg/article/details/52517991
     3 #include "core/core.hpp"
     4 #include "imgproc/imgproc.hpp"
     5 #include "highgui/highgui.hpp"
     6 
     7 using namespace cv;
     8 
     9 int main(int argc, char *argv[])
    10 {
    11     float maxValue = 0;  //定义距离变换矩阵中的最大值
    12     Point Pt(0, 0);
    13     Mat image = imread("D:\六角星.jpg");
    14     Mat imageGray;
    15     cvtColor(image, imageGray, CV_RGB2GRAY);
    16     imageGray = ~imageGray;  //取反
    17     GaussianBlur(imageGray, imageGray, Size(5, 5), 2); //滤波
    18     threshold(imageGray, imageGray, 20, 200, CV_THRESH_BINARY); //阈值化    
    19     Mat imageThin(imageGray.size(), CV_32FC1); //定义保存距离变换结果的Mat矩阵
    20     distanceTransform(imageGray, imageThin, CV_DIST_L2, 3);  //距离变换
    21     Mat distShow;
    22     distShow = Mat::zeros(imageGray.size(), CV_8UC1); //定义细化后的字符轮廓
    23     for (int i = 0; i<imageThin.rows; i++)
    24     {
    25         for (int j = 0; j<imageThin.cols; j++)
    26         {
    27             distShow.at<uchar>(i, j) = imageThin.at<float>(i, j);
    28             if (imageThin.at<float>(i, j)>maxValue)
    29             {
    30                 maxValue = imageThin.at<float>(i, j);  //获取距离变换的极大值
    31                 Pt = Point(j, i);  //坐标
    32             }
    33         }
    34     }
    35     normalize(distShow, distShow, 0, 255, CV_MINMAX); //为了显示清晰,做了0~255归一化
    36     circle(image, Pt, maxValue, Scalar(0, 0, 255), 3);
    37     circle(image, Pt, 3, Scalar(0, 255, 0), 3);
    38     imshow("Source Image", image);
    39     imshow("Thin Image", distShow);
    40     waitKey();
    41     return 0;
    42 }
    View Code

     1 ////////https://blog.csdn.net/wuhaibing_cver/article/details/8602461
     2 #include <opencv2/imgproc/imgproc.hpp>  
     3 #include <opencv2/core/core.hpp>        
     4 #include <opencv2/highgui/highgui.hpp> 
     5 #include <cv.h>
     6 #include <highgui.h>
     7 
     8 int main()
     9 {
    10     char* filename = "D:\二值化手.jpg";
    11     IplImage* src_image = cvLoadImage(filename, 1);
    12     if (!src_image)
    13         return -1;
    14     cvNamedWindow("src");
    15 
    16     CvSize size = cvGetSize(src_image);
    17     IplImage* gray_image = cvCreateImage(size, 8, 1);
    18     cvCvtColor(src_image, gray_image, CV_BGR2GRAY);
    19 
    20     IplImage* dist_image = cvCreateImage(size, 32, 1);
    21     IplImage* bi_src = cvCreateImage(size, 8, 1);
    22     IplImage* dist8u_image = cvCreateImage(size, 8, 1);
    23     IplImage* bi_dist = cvCreateImage(size, 8, 1);
    24     //原图像二值化
    25     cvThreshold(gray_image, bi_src, 100, 255, CV_THRESH_BINARY);
    26     //距离变换
    27     cvDistTransform(bi_src, dist_image, CV_DIST_L2, 3, 0, 0);
    28     //找最大值
    29     double max;
    30     cvMinMaxLoc(dist_image, 0, &max, 0, 0);
    31     cvCvtScale(dist_image, dist8u_image, 255. / max);
    32     //对距离图像二值化,去除手指部分
    33     cvThreshold(dist8u_image, bi_dist, 80, 255, CV_THRESH_BINARY);
    34     //求重心
    35     float s = 0.0, x = 0.0, y = 0.0;
    36     uchar* data = (uchar*)bi_dist->imageData;
    37     int step = bi_dist->widthStep;
    38     for (int h = 0; h<bi_dist->height; h++)
    39         for (int w = 0; w<bi_dist->width; w++)
    40             if (255 == data[step*h + w])
    41             {
    42                 x += w;
    43                 y += h;
    44                 s++;
    45             }
    46     if (s>0)
    47     {
    48         x = x / s;
    49         y = y / s;
    50     }
    51     CvPoint pos = cvPoint((int)x, (int)y);
    52 
    53     cvCircle(src_image, pos, 3, CV_RGB(255, 0, 0), 1, CV_AA);
    54     cvShowImage("src", src_image);
    55     cvWaitKey(-1);
    56 
    57     cvDestroyWindow("src");
    58     cvReleaseImage(&src_image);
    59     cvReleaseImage(&gray_image);
    60     cvReleaseImage(&bi_src);
    61     cvReleaseImage(&dist8u_image);
    62     cvReleaseImage(&bi_dist);
    63 
    64     return 0;
    65 }
    View Code

    参考:

    https://blog.csdn.net/dcrmg/article/details/52517991

    https://blog.csdn.net/wuhaibing_cver/article/details/8602461

    原理参考:https://blog.csdn.net/liubing8609/article/details/78483667

    其他参考:

    https://blog.csdn.net/abcjennifer/article/details/7617883

    https://blog.csdn.net/haoji007/article/details/52063389

    http://www.linuxkiss.com/287.html

  • 相关阅读:
    敏捷开发-各个原则的理解
    DWH中增量数据的抽取
    SSIS的部署和配置
    Checkpoint 和Breakpoint
    两种动态SQL
    SQLServer查询计划
    程序员接项目的经验1
    Date.prototype.format
    前端颜色选择器
    Idea快捷键和使用技巧【未完】
  • 原文地址:https://www.cnblogs.com/thebreakofdawn/p/9484458.html
Copyright © 2020-2023  润新知