首页 > 其他分享 >30.图像距离变换

30.图像距离变换

时间:2023-04-11 14:25:08浏览次数:37  
标签:函数 变换 30 距离 像素 像素点 图像 CV

  图像中两个像素之间的距离有多种定义方式,图像处理中常用的距离有欧式距离、街区距离和棋盘距离,本节中将重点介绍这三种距离的定义方式,以及如何利用两个像素间的距离来描述一幅图像。

1、欧式距离,两个像素点之间的直线距离。与直角坐标系中两点之间的直线距离求取方式相同,分别计算两个像素在X方向和Y方向上的距离,之后利用勾股定理得到两个像素之间的距离,数学表示形式如式(6.1)所示。

2、街区距离,两个像素点X方向和Y方向的距离之和。欧式距离表示的是从一个像素点到另一个像素点的最短距离,然而有时我们并不能以两个点之间连线的方向前进,例如在一个城市内两点之间的连线可能存在障碍物的阻碍,因此从一个点到另一个点需要沿着街道行走,因此这种距离的度量方式被称为街区距离。街区距离就是由一个像素点到另一个像素点需要沿着X方向和Y方向一共行走的距离,数学表示形式如式所示。

 

3、棋盘距离,两个像素点X方向距离和Y方向距离的最大值。与街区距离相似,棋盘距离也是假定两个像素点之间不能够沿着连线方向靠近,像素点只能沿着X方向和Y方向移动,但是棋盘距离并不是表示由一个像素点移动到另一个像素点之间的距离,而是表示两个像素点移动到同一行或者同一列时需要移动的最大距离,数学表示形式如式所示。

代码清单6-1 distanceTransform()函数原型1
void cv::distanceTransform(InputArray  src,
                              OutputArray  dst,
                              OutputArray  labels,
                              int  distanceType,
                              int  maskSize,
                              int  labelType = DIST_LABEL_CCOMP 
                              )
  • src:输入图像,数据类型为CV_8U的单通道图像
  • dst:输出图像,与输入图像具有相同的尺寸,数据类型为CV_8U或者CV_32F的单通道图像。
  • labels:二维的标签数组(离散Voronoi图),与输入图像具有相同的尺寸,数据类型为CV_32S的单通道数据。
  • distanceType:选择计算两个像素之间距离方法的标志,其常用的距离度量方法在表6-1给出。
  • maskSize:距离变换掩码矩阵的大小,参数可以选择的尺寸为DIST_MASK_3(3×3)和DIST_MASK_5(5×5).
  • labelType:要构建的标签数组的类型,可以选择的参数在表6-2给出。

  该函数用于实现图像的距离变换,即统计图像中所有像素距离0像素的最小距离。函数的第一个参数为待距离变换的输入图像,输入图像要求必须是CV_8U的单通道图像。函数第二个参数是原图像距离变换后的输出图像,与输入图像具有相同的尺寸,图像中每个像素值表示该像素在原图像中距离0像素的最小距离。由于图像的尺寸可能大于256,因此图像中某个像素距离0像素的最近距离有可能会大于255,为了能够正确的统计出每一个像素距离0像素的最小距离,输出图像的数据类型可以选择CV_8U或者CV_32F。函数第三个参数是原图像的Voronoi图,输出图像是数据类型为CV_32S单通道图像,图像尺寸与输入图像相同。图像第四个参数是距离变换过程中使用的距离种类,常用的距离为欧式距离(DIST_L2)、街区距离(DIST_L1)和棋盘距离(DIST_C)。函数第五个参数是求取路径时候的掩码尺寸,该尺寸与选择的距离种类有着密切的关系,当选择使用街区距离时,掩码尺寸选择3×3还是5×5对计算结果都没有影响,因此为了加快函数运算速度,默认选择掩码尺寸为3×3;当选择欧式距离时,掩码尺寸为3×3时是粗略的计算两个像素之间的距离,而当掩码尺寸为5×5时是精确的计算两个像素之间的距离,精确计算与粗略计算两者之间存在着较大的差异,因此在使用欧式距离时推荐使用5×5掩码;当选择棋盘距离时,掩码的尺寸对计算结果也没有影响,因此可以随意选择。函数的最后一个参数为构建标签数组的类型,当labelType==DIST_LABEL_CCOMP时,该函数会自动在输入图像中找到0像素的连通分量,并用不同的标签标记它们。当labelType==DIST_LABEL_CCOMP时,该函数扫描输入图像并用不同的标签标记所有0像素。

  该函数原型在对图像进行距离变换的同时会生成Voronoi图,但是有时只是为了实现对图像的距离变换,并不需要使用Voronoi图,而使用该函数必须要求创建一个Mat类变量用于存放Voronoi图,占用了内存资源,因此distanceTransform()函数的第二种函数原型中取消了生成Voronoi图,只输出距离变换后的图像,该种函数原型在代码清单6-2中给出。

代码清单6-2 distanceTransform()函数原型2
void distanceTransform(InputArray  src, 
                          OutputArray  dst,
                          int  distanceType, 
                          int  maskSize, 
                          int  dstType = CV_32F
                          )
  • src:输入图像,数据类型为CV_8U的单通道图像
  • dst:输出图像,与输入图像具有相同的尺寸,数据类型为CV_8U或者CV_32F的单通道图像。
  • distanceType:选择计算两个像素之间距离方法的标志,其常用的距离度量方法在表6-1给出。
  • maskSize:距离变换掩码矩阵的大小,参数可以选择的尺寸为DIST_MASK_3(3×3)和DIST_MASK_5(5×5)。
  • dstType:输出图像的数据类型,可以是CV_8U或者CV_32F。

  该函数原型中的主要参数含义与前一种函数原型相同,前两个参数为输入图像和输出图像,第三个参数和为距离变换过程中使用的距离种类。函数中第四个参数是距离变换掩码矩阵的大小,由于街区距离(Dist_L1)和棋盘距离(Dist_C)对掩模尺寸没有要求,因此该参数在选择街区距离和棋盘距离时被强制设置为3,同样掩模尺寸的大小对欧式距离(Dist_L2)计算的精度有影响,为了获取较为精确的时,一般使用5×5的掩模矩阵。函数最后一个参数是输出图像的数据类型,虽然可以在CV_8U和CV_32F两个类型中任意选择,但是图像输出时实际的数据类型与距离变换时选择的距离种类有着密切的联系,CV_8U只能使用在计算街区距离的条件下,当计算欧式距离和棋盘距离时,即使该参数设置为CV_8U,实际的输出图像的数据类型也是CV_32F。

  由于distanceTransform()函数是计算图像中非0像素距离0像素的最小距离,而图像中0像素表示黑色,因此为了保证能够清楚的观察到距离变换的结果,不建议使用尺寸过小或者黑色区域较多的图像,否则distanceTransform()函数处理后的图像中几乎全为黑色,不利于观察。

代码清单6-3 myDistanceTransform.cpp图像距离变换
#include <opencv2\opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main()
{
    //构建建议矩阵,用于求取像素之间的距离
    Mat a = (Mat_<uchar>(5, 5) << 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1,
        1, 1, 0, 1, 1,
        1, 1, 1, 1, 1,
        1, 1, 1, 1, 1);
    Mat dist_L1, dist_L2, dist_C, dist_L12;

    //计算街区距离
    distanceTransform(a, dist_L1, 1, 3, CV_8U);
    cout << "街区距离:" << endl << dist_L1 << endl;

    //计算欧式距离
    distanceTransform(a, dist_L2, 2, 5, CV_8U);
    cout << "欧式距离:" << endl << dist_L2 << endl;

    //计算棋盘距离
    distanceTransform(a, dist_C, 3, 5, CV_8U);
    cout << "棋盘距离:" << endl << dist_C << endl;

    //对图像进行距离变换
    Mat rice = imread("rice.png", IMREAD_GRAYSCALE);
    if (rice.empty())
    {
        cout << "请确认图像文件名称是否正确" << endl;
        return -1;
    }
    Mat riceBW, riceBW_INV;

    //将图像转成二值图像,同时把黑白区域颜色呼唤
    threshold(rice, riceBW, 50, 255, THRESH_BINARY);
    threshold(rice, riceBW_INV, 50, 255, THRESH_BINARY_INV);

    //距离变换
    Mat dist, dist_INV;
    distanceTransform(riceBW, dist, 1, 3, CV_32F);  //为了显示清晰,将数据类型变成CV_32F
    distanceTransform(riceBW_INV, dist_INV, 1, 3, CV_8U);

    //显示变换结果
    imshow("riceBW", riceBW);
    imshow("dist", dist);
    imshow("riceBW_INV", riceBW_INV);
    imshow("dist_INV", dist_INV);

    waitKey(0);
    return 0;
}

 

标签:函数,变换,30,距离,像素,像素点,图像,CV
From: https://www.cnblogs.com/okmai77xue/p/17306032.html

相关文章

  • Python程序笔记20230303
    成绩评级程序分数<60,D60<=分数<80,C80<=分数<90,B90<=分数<100,A分数==100,S#输入分数score=int(input("请输入分数:"))#判断评级ifscore<0orscore>100:print("无效的分数")elifscore<60:print("......
  • 28.图像滤波
    1、均值滤波代码清单5-8blur()函数原型voidcv::blur(InputArraysrc,OutputArraydst,Sizeksize,Pointanchor=Point(-1,-1),intborderType=BORDER_DEFAULT)待......
  • Python程序笔记20230302
    Alice、Bob和他们的朋友们问题主体密码学家Rivest、Shamir、Adleman于1977年4月撰写了一篇论文《数字签名与公钥密码学》(OnDigitalSignaturesandPublic-KeyCryptosystems),并投稿至了一个期刊上,不过很遗憾这篇论文被拒稿了。随后他们修改了论文,并将论文重新命名为《一种实......
  • 27、图像中加入噪声
    1、图像中加入椒盐噪声椒盐噪声又被称作脉冲噪声,它会随机改变图像中的像素值,是由相机成像、图像传输、解码处理等过程产生的黑白相间的亮暗点噪声,其样子就像在图像上随机的撒上一些盐粒和黑椒粒,因此被称为椒盐噪声。考虑到椒盐噪声会随机产生在图像中的任何一个位置,因此对于......
  • Python程序笔记20230301
    打印九九乘法表foriinrange(1,10):forjinrange(1,i+1):print(i,"x",j,"=",i*j,end='')print("\n")第三行的print(i,"x",j,"=",i*j,end='')打印出i和j的乘积,并在末尾添......
  • 25.图像直方图
    1、图像直方图绘制图像直方图是图像处理中非常重要的像素统计结果,图像直方图不再表征任何的图像纹理信息,而是对图像像素的统计。由于同一物体无论是旋转还是平移在图像中都具有相同的灰度值,因此直方图具有平移不变性、放缩不变性等优点,因此可以用来查看图像整体的变化形式,例......
  • 每日学习记录20230228_mzR
    20230228:mzR,Norm,RegressionmzR:mzML格式读取是使用proteowizardC++库.常用函数:读入数据的openMSfile,提取数据矩阵的header以及提取峰图谱的peaksNorm范数L0Norm:c(0,0)的L0Norm等于0,c(1,0)的L0Norm等于1,c(1,2)等于2L1Norm:用于ManhattanDistanceorTaxica......
  • 每日学习记录20230221_purr包 GSEA pandas
    20230221:purr包GSEApandaspurr的map_*函数的使用DF=List1%>%names%>%map_dfr(function(x){#把List1转化成DataFrame的格式,map_dfr是把结果都按行合并起来.return(data.frame(x,List1[[x]]$'all'))})clusterProfile::GSEA调用的是DOS......
  • 每日学习记录20230323_Bert视频学习
    20230323:Bert视频学习B站视频RNN这个东西不能并行运算,所以翻译的时候需要用Transformer,这样输出结果是同时被计算出来的.并且Transformer有注意力机制进行并行计算Transformer输入如何编码?输出结果是什么?Attention的目的?怎样组合在一起?Transformer最核心的机制是S......
  • 每日学习记录20230322_Bert安装和使用
    20230322:Bert安装与使用Bert安装与使用安装教程:地址需要python版本大于等于3.5,tensorflow版本大于等于1.10.1,但是我经过测试发现,3.7.6版本不行,报错说缺少glib23,只能是使用这个教程的方法.R的一个function:file.path,用于生成路径的一个function.file.path("","p......