在OpenCV中,可以很方便的计算一个像素点到轮廓的距离,计算距离的函数为:

double pointPolygonTest(InputArray contour, Point2f pt, bool measureDist)

Parameters:

  • contour – 输入参数轮廓。
  • pt – 测试的点。
  • measureDist – 如果为false的话,则函数计算符号,在轮廓外部在为-1,在轮廓内为1,在轮廓上,则为0。如果为ture,则计算实际的像素符号距离,在轮廓外的点像素距离为负值,在内的点,像素距离为正值。

下面的是计算一副图像中各个像素到轮廓距离的代码:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std; using namespace cv;
using namespace std; int main( int argc, char** argv )
{
//创建一副图像
const int r = 100;
Mat src = Mat::zeros( Size( 4*r, 4*r ), CV_8UC1 ); //创建一个轮廓序列
vector<Point2f> vert(6); vert[0] = Point( 1.5*r, 1.34*r );
vert[1] = Point( 1*r, 2*r );
vert[2] = Point( 1.5*r, 2.866*r );
vert[3] = Point( 2.5*r, 2.866*r );
vert[4] = Point( 3*r, 2*r );
vert[5] = Point( 2.5*r, 1.34*r ); //画轮廓
for( int j = 0; j < 6; j++ )
{ line( src, vert[j], vert[(j+1)%6], Scalar( 255 ), 3, 8 ); } //得到轮廓
vector<vector<Point> > contours; vector<Vec4i> hierarchy;
Mat src_copy = src.clone(); findContours( src_copy, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE); //计算顶点到轮廓的距离
Mat raw_dist( src.size(), CV_32FC1 ); for( int j = 0; j < src.rows; j++ )
{
for( int i = 0; i < src.cols; i++ )
{
raw_dist.at<float>(j,i) = pointPolygonTest( contours[0], Point2f(i,j), true ); }
} double minVal; double maxVal;
minMaxLoc( raw_dist, &minVal, &maxVal, 0, 0, Mat() );
minVal = abs(minVal); maxVal = abs(maxVal); //用户型化的方式显示距离
Mat drawing = Mat::zeros( src.size(), CV_8UC3 ); for( int j = 0; j < src.rows; j++ )
{ for( int i = 0; i < src.cols; i++ )
{
//在外部
if( raw_dist.at<float>(j,i) < 0 )
{ drawing.at<Vec3b>(j,i)[0] = 255 - (int) abs(raw_dist.at<float>(j,i))*255/minVal; }
//在内部
else if( raw_dist.at<float>(j,i) > 0 )
{ drawing.at<Vec3b>(j,i)[2] = 255 - (int) raw_dist.at<float>(j,i)*255/maxVal; }
else
// 在边上
{ drawing.at<Vec3b>(j,i)[0] = 255; drawing.at<Vec3b>(j,i)[1] = 255; drawing.at<Vec3b>(j,i)[2] = 255; }
}
} namedWindow( "image", CV_WINDOW_AUTOSIZE );
imshow( "image", src );
namedWindow( "Distance", CV_WINDOW_AUTOSIZE );
imshow( "Distance", drawing ); waitKey(0);
return(0);
}

对于轮廓外的点,越是蓝色,则距离轮廓越近,轮廓内的点,越是红色距离轮廓越近,轮廓上点距离为0,用白色表示。

程序执行后效果:

程序代码:工程FirstOpenCV30

OpenCV学习(34) 点到轮廓的距离的更多相关文章

  1. OpenCV学习代码记录——轮廓(contour)检测

    很久之前学习过一段时间的OpenCV,当时没有做什么笔记,但是代码都还在,这里把它贴出来做个记录. 代码放在码云上,地址在这里https://gitee.com/solym/OpenCVTest/tr ...

  2. OpenCV学习(32) 求轮廓的包围盒

    在OpenCV中,能够很方便的求轮廓包围盒.包括矩形,圆形,椭圆形以及倾斜的矩形(包围面积最小)集中包围盒.用到的四个函数是: Rect boundingRect(InputArray points) ...

  3. OpenCV学习笔记(14)——轮廓的性质

    提取一些经常使用的对象特征 1.长宽比 边界矩形的宽高比                                       x,y,w,h = cv2.boundingRect(cnt) a ...

  4. opencv学习之路(28)、轮廓查找与绘制(七)——位置关系及轮廓匹配

    一.点与轮廓的距离及位置关系 #include "opencv2/opencv.hpp" #include <iostream> using namespace std ...

  5. 【OpenCV学习笔记】三十、轮廓特征属性及应用(七)—位置关系及轮廓匹配

    http://blog.csdn.net/abc8730866/article/details/69219992 轮廓特征属性及应用(七)—位置关系及轮廓匹配 1.计算点与轮廓的距离及位置关系——po ...

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

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

  7. OpenCV学习(30) 轮廓defects

    上一篇教程中,我们学习了如何计算轮廓的凸包,其实对一个轮廓而言,可能它的凸包和它本身是重合的,也有可能不是重合的.比如下面左边图像的轮廓本身就是凸包,而右边图像的轮廓则不是.我们可以通过函数bool ...

  8. OpenCV 学习笔记03 边界框、最小矩形区域和最小闭圆的轮廓

    本节代码使用的opencv-python 4.0.1,numpy 1.15.4 + mkl 使用图片为 Mjolnir_Round_Car_Magnet_300x300.jpg 代码如下: impor ...

  9. OpenCV学习笔记(12)——OpenCV中的轮廓

    什么是轮廓 找轮廓.绘制轮廓等 1.什么是轮廓 轮廓可看做将连续的点(连着边界)连在一起的曲线,具有相同的颜色和灰度.轮廓在形态分析和物体的检测和识别中很有用. 为了更加准确,要使用二值化图像.在寻找 ...

随机推荐

  1. 002 Ajax中传输格式为HTML

    一: 1.介绍 返回的数据可以直接插入到需要的地方. 2.优缺点 二:程序大纲 1.结构 三:程序 1.css body { background: #ffb url("logo.png&q ...

  2. hdoj2191 珍惜现在,感恩生活(01背包 || 多重背包)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2191 思路 由于每种大米可能不止一袋,所以是多重背包问题,可以直接使用解决多重背包问题的方法,也可以将 ...

  3. Xiaoguang Tu's Home Page

    Xiaoguang Tu (涂晓光): CV: Ph.D. Candidate of School of Communication and Information Engineering, Univ ...

  4. 关于ueditor的使用心得

    http://blog.csdn.net/baronyang/article/details/45640181 1.取编辑器内的内容: <span style="font-size:1 ...

  5. 2017-2018-1 20179202《Linux内核原理与分析》第十二周作业

    C语言实现Linux网络嗅探器 一.知识准备 1.一般情况下,网络上所有的机器都可以"听"到通过的流量,但对不属于自己的数据包则不予响应.如果某个工作站的网络接口处于混杂模式,那么 ...

  6. COCO 数据集使用说明书

    下面的代码改写自 COCO 官方 API,改写后的代码 cocoz.py 被我放置在 Xinering/cocoapi.我的主要改进有: 增加对 Windows 系统的支持: 替换 defaultdi ...

  7. 装饰模式和Java IO

    装饰模式 修饰模式(装饰模式),是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式.就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能. 装饰模式的UM ...

  8. mongodb cmd 常用命令

    如题,命令如下: 1.连接远程数据库命令 mongo -u admin -p admin 192.168.0.197:27017/test 2.查看当前版本 db.version(); 3.mongo ...

  9. python 全排列

    itertools模块现成的全排列: for i in itertools.permutations('abcd',4): print ''.join(i) 相关全排列算法: def perm(l): ...

  10. Java设计模式GOF之工厂模式

    一.工厂模式(Factory) 1.实现了创建者和调用者的分离 2.应用场景 ①JDK中 Calendar 的 getInstance(): ②JDBC 的 Connection 对象的获取: ③Hi ...