• opencv-distanceTransform 距离计算函数


    用于计算图像中每一个非零点距离离自己最近的零点的距离 

    1.png

        cv::Mat src = cv::imread("D:/bb/tu1/1.png",0);
            
        cv::Mat imageThin(src.size(), CV_32FC1); //定义保存距离变换结果的Mat矩阵
        distanceTransform(src, imageThin, CV_DIST_L2, 3);  //距离计算
        /*
        参数1:8-bit, 单通道输入图片
        参数2:输出结果中包含计算的距离,这是一个32-bit  float 单通道的Mat类型,大小与输入图片相同
        参数3:distanceType计算距离的类型
            distanceType        maskSize         a  b  c     
            CV_DIST_C            3(3X3)         a = 1, b = 1
            CV_DIST_L1            3(3X3)           a = 1, b = 2
            CV_DIST_L2            3(3X3)         a=0.955, b=1.3693
            CV_DIST_L2            5(5X5)         a=1, b=1.4, c=2.1969
        参数4:maskSize – 距离变换掩码矩阵的大小
            3(CV_DIST_L1、 CV_DIST_L2 、CV_DIST_C)
            5(CV_DIST_L2 )
               CV_DIST_MASK_PRECISE (这个只能在4参数的API中使用)
      参数5:目标矩阵的数据类型
          CV_8U
    说明:其中 a b c 含义:在这个函数中计算每个非0像素到黑色像素(0值像素)的最短距离,因此需要通过最短的移动方式找到这个点计算他们之间的值。通常来说移动有水平方向、竖直方向、对角方向、跳跃式几个移动方法。虽然计算距离的方法都是一些很基础的公式,但是这个这个掩码矩阵必须是对阵的,因此掩码矩阵上所有水平和竖直方向的变化量,这里用 a 代表;对角方向的变化量用 b 代表;跳跃移动的变化量用 c 代表。CV_DIST_C、CV_DIST_L1、CV_DIST_L2(maskSize=5)的计算结果是精确的,CV_DIST_L2(maskSize=3)是一个快速计算方法
    */

    应用一:细化轮廓

    2.png

        float maxValue = 0;  //保存距离变换矩阵中的最大值
        cv::Mat src = cv::imread("D:/bb/tu1/2.png",0);
        cv::Mat imageGray=~src;  //取反
        cv::GaussianBlur(imageGray, imageGray, cv::Size(5, 5), 2); //滤波-去除杂点
        cv::threshold(imageGray, imageGray, 10, 200, 0); 
        cv::namedWindow("imageGray");
        cv::imshow("imageGray",imageGray);
        cv::Mat imageThin(imageGray.size(), CV_32FC1);
        cv::distanceTransform(imageGray, imageThin, CV_DIST_L2, 3);  //距离计算
        cv::Mat distShow;
        distShow = cv::Mat::zeros(imageGray.size(), CV_8UC1); 
        for (int i = 0; i < imageThin.rows; i++)
        {
            for (int j = 0; j < imageThin.cols; j++)
            {
                if (imageThin.at<float>(i, j) > maxValue)
                {
                    maxValue = imageThin.at<float>(i, j);  //获取距离变换的最大值
                }
            }
        }
        for (int i = 0; i < imageThin.rows; i++)
        {
            for (int j = 0; j < imageThin.cols; j++)
            {
                if (imageThin.at<float>(i, j) > maxValue / 1.9)
                {
                    distShow.at<uchar>(i, j) = 255;   //符合距离大于最大值一定比例条件的点设为255
                }
            }
        }
        cv::namedWindow("distShow");
        cv::imshow("distShow", distShow);

    应用二:查找物体质心

    3.png

        cv::Mat src = cv::imread("D:/bb/tu1/3.png");
        cv::Mat imageGray;
        cv::cvtColor(src, imageGray, CV_RGB2GRAY);
        imageGray = ~imageGray;
        
        cv::threshold(imageGray, imageGray, 20, 255, 0);
        cv::Mat imageThin(imageGray.size(), CV_32FC1);
        cv::distanceTransform(imageGray, imageThin, CV_DIST_L2, 3);  //距离变换
        cv::Mat distShow;
        distShow = cv::Mat::zeros(imageGray.size(), CV_8UC1);
        float maxValue = 0;
        cv::Point Pt(0, 0);
        for (int i = 0; i < imageThin.rows; i++)
        {
            for (int j = 0; j < imageThin.cols; j++)
            {
                distShow.at<uchar>(i, j) = imageThin.at<float>(i, j);
                //把float转换成uchar之后,距离越远的地方越亮
                if (imageThin.at<float>(i, j) > maxValue)
                {
                    maxValue = imageThin.at<float>(i, j);  //获取距离变换的最大值
                    Pt = cv::Point(j, i);  //最大值的坐标
                }
            }
        }
        cv::normalize(distShow, distShow, 0, 255, CV_MINMAX); //为了显示清晰,做了0~255归一化
        cv::circle(src, Pt, maxValue, cv::Scalar(0, 0, 255), 3);
        cv::circle(src, Pt, 3, cv::Scalar(0, 255, 0), 3);
    
        cv::namedWindow("src1");
        cv::imshow("src1", src);
        
        cv::waitKey();

  • 相关阅读:
    静态方法中访问类的实例成员
    静态初始化块
    Java字段初始化的规律
    java中函数重载
    哈姆雷特观后感 一把辛酸泪
    枚举
    验证码
    四则运算
    JAVA输出中+号的作用以及如何使用
    dev控件ASPxComboBox设置ReadOnly="true"后
  • 原文地址:https://www.cnblogs.com/liming19680104/p/15472690.html
Copyright © 2020-2023  润新知