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();
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2020-10-27 qt--调色板QPalette