Opencv距离变换distanceTransform应用——细化字符轮廓&&查找物体质心
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应用——细化字符轮廓&&查找物体质心的更多相关文章
- OpenCV——距离变换与分水岭算法的(图像分割)
C++: void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize) 参数详解: I ...
- 基于标记的分水岭分割算法/OpenCV中距离变换
Opencv分水岭算法——watershed自动图像分割用法 OpenCV距离变换distanceTransform应用 图像分割作为图像识别的基础,在图像处理中占有重要地位,通常需要在进行图像分割算 ...
- opencv::基于距离变换与分水岭的图像分割
什么是图像分割 图像分割(Image Segmentation)是图像处理最重要的处理手段之一 图像分割的目标是将图像中像素根据一定的规则分为若干(N)个cluster集合,每个集合包含一类像素. 根 ...
- OpenCV成长之路:直线、轮廓的提取与描述
http://ronny.blog.51cto.com/8801997/1394139 OpenCV成长之路:直线.轮廓的提取与描述 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...
- opencv学习笔记(二)寻找轮廓
opencv学习笔记(二)寻找轮廓 opencv中使用findContours函数来查找轮廓,这个函数的原型为: void findContours(InputOutputArray image, O ...
- 距离变换DT
距离变换:计算区域中的每个点与最接近的区域外的点之间距离,把二值图象变换为灰度图象. 对于目标中一个点,距离变换的定义为改点与目标边界最近的距离. 目标点离边界约近则值越小,转换的点越暗:越远,值越大 ...
- opencv学习之路(26)、轮廓查找与绘制(五)——最小外接矩形
一.简介 二.轮廓最小外接矩形的绘制 #include "opencv2/opencv.hpp" using namespace cv; void main() { //轮廓最小外 ...
- opencv学习之路(22)、轮廓查找与绘制(一)
一.简介 图2 二.代码 #include"opencv2/opencv.hpp" #include<iostream> using namespace std; us ...
- Blob分析--粘连颗粒检测 基于距离变换的分水岭区域分割 盆地与原连通域求交集
文章转自微信公众号:机器视觉那些事 *******************************************************************公众号:机器视觉那些事儿*** ...
随机推荐
- ssh-keygen && ssh-copy-id 生成管理传输秘钥
- 【Pycharm】【HTML】注释问题
学习HTML中,遇到的注释前存在空行的问题: 只要找到Pycharm设置中:勾选去掉即可
- 【Codecraft-18 and Codeforces Round #458 (Div. 1 + Div. 2, combined) B】 Conan and Agasa play a Card Game
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 最大值出现次数是偶数. 那么就取次大值. 次大值也是偶数? =>再次 因为你绝对不能取偶数个的. 取了对方就总是能面对一个奇数 ...
- [Redux-Observable && Unit Testing] Mocking an ajax request when testing epics
Often in unit tests we are focussing on the logic involved in crafting a network request, & how ...
- Catch Me If You ... Can't Do Otherwise--转载
原文地址:https://dzone.com/articles/catch-me-if-you-cant-do-otherwise I don't know whether it's an anti- ...
- Rpm另类用法加固Linux安全
Rpm另类用法加固Linux安全 RPM是Red Hat Package Manager的缩写即Red Hat软件管理器.它是一个开放的包管理软件,由Red Hat公司所开发和维护,可以在Red ...
- Object.prototype.toString.call(value)
使用Object.prototype上的原生toString()方法判断数据类型,使用方法如下: Object.prototype.toString.call(value) 1.判断基本类型: Obj ...
- BZOJ3926: [Zjoi2015]诸神眷顾的幻想乡(广义后缀自动机)
Description 幽香是全幻想乡里最受人欢迎的萌妹子,这天,是幽香的2600岁生日,无数幽香的粉丝到了幽香家门前的太阳花田上来为幽香庆祝生日. 粉丝们非常热情,自发组织表演了一系列节目给幽香看. ...
- PYTHON学习第四天课后总结:
第三天学习课后总结: 今日重点: 流程控制 1,if 条件判断语句 2,while 循环 3,for 循环 一,if +条件判断语句: 1> if+条件判断表达式: 子代码1 子代码2 子代 ...
- html中的瀑布流是什么
html中的瀑布流是什么 一.总结 1.瀑布流: 从左往右排列,哪一列现在的总高度最小,就优先排序把item(单元格)放在这一列.这样排完所有的单元格后,可以保证每一列的总高度都相差不大 2.看效果图 ...