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

可以根据距离变换的这个性质,经过简单的运算,用于细化字符的轮廓和查找物体质心(中心)。

一、细化轮廓

#include "core/core.hpp"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp" using namespace cv; int main(int argc,char *argv[])
{
float maxValue=0; //定义距离变换矩阵中的最大值
Mat image=imread(argv[1]);
Mat imageGray;
cvtColor(image,imageGray,CV_RGB2GRAY);
imageGray=~imageGray; //取反
GaussianBlur(imageGray,imageGray,Size(5,5),2); //滤波
threshold(imageGray,imageGray,20,200,CV_THRESH_BINARY); //阈值
imshow("s",imageGray);
Mat imageThin(imageGray.size(),CV_32FC1); //定义保存距离变换结果的Mat矩阵
distanceTransform(imageGray,imageThin,CV_DIST_L2,3); //距离变换
Mat distShow;
distShow=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
}
}
}
imshow("Source Image",image);
imshow("Thin Image",distShow);
waitKey();
return 0;
}

对字母进行细化,原始图像:

细化效果:

对数字进行细化,原始图像:

细化效果:

二、查找物体质心

#include "core/core.hpp"
#include "imgproc/imgproc.hpp"
#include "highgui/highgui.hpp" using namespace cv; int main(int argc,char *argv[])
{
float maxValue=0; //定义距离变换矩阵中的最大值
Point Pt(0,0);
Mat image=imread(argv[1]);
Mat imageGray;
cvtColor(image,imageGray,CV_RGB2GRAY);
imageGray=~imageGray; //取反
GaussianBlur(imageGray,imageGray,Size(5,5),2); //滤波
threshold(imageGray,imageGray,20,200,CV_THRESH_BINARY); //阈值化
Mat imageThin(imageGray.size(),CV_32FC1); //定义保存距离变换结果的Mat矩阵
distanceTransform(imageGray,imageThin,CV_DIST_L2,3); //距离变换
Mat distShow;
distShow=Mat::zeros(imageGray.size(),CV_8UC1); //定义细化后的字符轮廓
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);
if(imageThin.at<float>(i,j)>maxValue)
{
maxValue=imageThin.at<float>(i,j); //获取距离变换的极大值
Pt=Point(j,i); //坐标
}
}
}
normalize(distShow,distShow,0,255,CV_MINMAX); //为了显示清晰,做了0~255归一化
circle(image,Pt,maxValue,Scalar(0,0,255),3);
circle(image,Pt,3,Scalar(0,255,0),3);
imshow("Source Image",image);
imshow("Thin Image",distShow);
waitKey();
return 0;
}

原始图像:

经过距离变换后距离Mat矩阵dst:

上图为了显示清晰,做了0~255的归一化。可以看到,中心处最亮,说明了中心点距离零点的距离最远,而最远处就可以作为物体的质心。

标记质心(绿色点):

Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心的更多相关文章

  1. OpenCV——距离变换与分水岭算法的(图像分割)

    C++: void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize) 参数详解: I ...

  2. 基于标记的分水岭分割算法/OpenCV中距离变换

    Opencv分水岭算法——watershed自动图像分割用法 OpenCV距离变换distanceTransform应用 图像分割作为图像识别的基础,在图像处理中占有重要地位,通常需要在进行图像分割算 ...

  3. opencv::基于距离变换与分水岭的图像分割

    什么是图像分割 图像分割(Image Segmentation)是图像处理最重要的处理手段之一 图像分割的目标是将图像中像素根据一定的规则分为若干(N)个cluster集合,每个集合包含一类像素. 根 ...

  4. OpenCV成长之路:直线、轮廓的提取与描述

    http://ronny.blog.51cto.com/8801997/1394139 OpenCV成长之路:直线.轮廓的提取与描述 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...

  5. opencv学习笔记(二)寻找轮廓

    opencv学习笔记(二)寻找轮廓 opencv中使用findContours函数来查找轮廓,这个函数的原型为: void findContours(InputOutputArray image, O ...

  6. 距离变换DT

    距离变换:计算区域中的每个点与最接近的区域外的点之间距离,把二值图象变换为灰度图象. 对于目标中一个点,距离变换的定义为改点与目标边界最近的距离. 目标点离边界约近则值越小,转换的点越暗:越远,值越大 ...

  7. opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形

    一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...

  8. opencv学习之路(22)、轮廓查找与绘制(一)

    一.简介 图2 二.代码 #include"opencv2/opencv.hpp" #include<iostream> using namespace std; us ...

  9. Blob分析--粘连颗粒检测 基于距离变换的分水岭区域分割 盆地与原连通域求交集

    文章转自微信公众号:机器视觉那些事 *******************************************************************公众号:机器视觉那些事儿*** ...

随机推荐

  1. 关于指定dll搜索路径

    原文:关于指定dll搜索路径 问题现象 当部分DLL放在子文件夹下,需要指定DLL搜索路径,否则系统将找不到文件 产生原因 系统默认搜索只会在前程序目录并不包括子目录 解决方法 1,使用App.con ...

  2. values-dimen 不同分辨率资源实现引用

    今天遇到了一种情况,就是在不同分辨率下面出现了需要设定不同的距离,当时第一反映就是重新定义一个layout.但是,仅仅为了更改一个数值就复制那么多的代码,明显不合里.后来就想到干脆在不同的分辨率下创建 ...

  3. 新手前端笔记之--初识css

    css样式表是为了容纳与html文档分离出来的样式属性而产生的,所以她理所当然的包含两个部分:1.样式的表示,使用{属性1:属性值:属性2:属性值:...},2.样式与标签的对应(如何找的对应标签), ...

  4. 五、Docker+Sqlserver

    原文:五.Docker+Sqlserver sqlserver现在支持linux了.所以可以运行在docker内 一.下载镜像: docker pull microsoft/mssql-server- ...

  5. ListCtrl添加右键菜单(ListCtrl类里编辑,给ListCtrl 发送NM_RCLICK消息)

    在开发中会用到右键菜单,我们来一起学习一下. 假如,我们现在已经准备好了列表,就差右键处理了. 1.在资源视图中的添加一个MENU,如图 2.给要添加右键菜单的ListCtrl子类,添加消息 按 ct ...

  6. iOS关闭键盘简单实现(objc/swift)

    Objective-C 代码实例方式一 [[[UIApplication sharedApplication] keyWindow] endEditing:YES]; 假设一个view上有很多Text ...

  7. elasticsearch cluster 概述

    在源码概述中我们分析过,elasticsearch源码从功能上可以分为分布式功能和数据功能,接下来这几篇会就分布式功能展开.这里首先会对cluster作简单概述,然后对cluster所涉及的主要功能详 ...

  8. docker第一章

    简介 Docker 是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并遵从Apache2.0协议开源. D ...

  9. js面向对象2--原型

    一.原型和原型对象 函数的原型prototype:函数才有prototype,prototype是一个对象,指向了当前构造函数的引用地址. 所有对象都有__proto__属性, 所有的__proto ...

  10. Ubuntu14.04中踩过的坑

    今天安装Ubuntu 14.0.4,因为需要使用python3,所以就直接配置如下:sudo rm /usr/bin/pythonsudo ln -s /usr/bin/python3.5  /usr ...