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. 【hdu 4289】Control

    [Link]:http://acm.hdu.edu.cn/showproblem.php?pid=4289 [Description] 给出一个又n个点,m条边组成的无向图.给出两个点s,t.对于图中 ...

  2. C# WPF开源控件库MaterialDesign介绍

    介绍 1.由于前端时间萌发开发一个基础架构得WPF框架得想法, 然后考虑到一些界面层元素统一, 然后就无意间在GitHub上发现一个开源WPF UI, 于是下载下来了感觉不错. 官网地址:http:/ ...

  3. 洛谷 P1400 塔

    P1400 塔 题目描述 有N(2<=N<=600000)块砖,要搭一个N层的塔,要求:如果砖A在砖B上面,那么A不能比B的长度+D要长.问有几种方法,输出 答案 mod 10000000 ...

  4. 玩转阿里云server——安装WebserverTomcat7

    1. 以root用户身份登录阿里云server 2. 使用apt-get install安装Tomcat7 sudo apt-get install tomcat7 3.安装后.Tomcat在启动时报 ...

  5. JMS基础知识

    JMS规范: jms的基本构件:  连接工厂(connectionFactory):客户用来创建连接的对象.比如:activeMQ提供的ActiveMQConnectionFactory. 连接(co ...

  6. 【基础练习】【线性DP】codevs2622 数字序列(最大连续子序列和)题解

    版权信息 转载请注明出处 [ametake版权全部]http://blog.csdn.net/ametake欢迎来看 这道题目本质就是朴素的最大连续子序列和 直接上题目和代码 题目描写叙述 Descr ...

  7. js14--原型2

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  8. [ Eclipse ] [ Problem ] Eclipse 無法開啟問題

    因為 Eclipse 在設定環境的過程掛掉太多次,擷取一些網路上優秀的文章當作備份 http://www.ewdna.com/2013/12/Eclipse-Loading-Workbench.htm ...

  9. 关于Webpack详述系列文章 (第三篇)

    1. 类图 1. 模块 Module是webpack中最核心的类,要加载定的一切和依赖都是Module. 它有很多子类 RawModule NormalModule MultiModule Conte ...

  10. 3.字符设备驱动------Poll机制

    1.poll情景描述 以之前的按键驱动为例进行说明,用阻塞的方式打开按键驱动文件/dev/buttons,应用程序使用read()函数来读取按键的键值. ) { read(fd, &key_v ...