OPENCV之寻找并绘制轮廓以及提取轮廓重心坐标
OPENCV之寻找并绘制轮廓以及提取轮廓重心坐标
1、寻找轮廓
声明:在寻找图像轮廓之前需要对图像进行阈值分割或者Canny、拉普拉斯等边缘检测算子处理。
寻找轮廓的算子:
findContours(InputOutputArray image, OutputArrayOfArrays contours,OutputArray hierarchy, int mode, int method, Point offset = Point());
(1)单通道图像,可以是灰度图,常用的是二值图像;
(2)contours是一个双重向量(向量内每个元素保存了一组由连续的Point构成的点的集合的向量),每一组点集就是一个轮廓,有多少轮廓,contours就有多少元素。其定义为“vector<vector<Point>> contours”;
(3)hierarchy也是一个向量,向量内每个元素保存了一个包含4个int整型的数组。其定义为“vector<Vec4i> hierarchy”,其中<Vec4i>是Vec<int,4>的别名,定义了一个“向量内每一个元素包含了4个int型变量”的向量。
hierarchy向量内每一个元素的4个int型变量——hierarchy[i][0] ~hierarchy[i][3],分别表示第 i个轮廓的后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号。如果当前轮廓没有对应的后一个轮廓、前一个轮廓、父轮廓或内嵌轮廓的话,则hierarchy[i][0] ~hierarchy[i][3]的相应位被设置为 默认值-1。
(4)轮廓的检索方式,opencv提供了四种方法,解释如下:
CV_RETR_EXTERNAL:只检测最外围轮廓,包含在外围轮廓内的内围轮廓被忽略;
CV_RETR_LIST:检测所有的轮廓,包括内围、外围轮廓,但是检测到的轮廓不建立等级关系,彼此之间独立,没有等级关系,这就意味着这个检索模式下不存在父轮廓或内嵌轮廓,所 以hierarchy向量内所有元素的第3、第4个分量都会被置为-1,具体下文会讲到;
CV_RETR_CCOMP: 检测所有的轮廓,但所有轮廓只建立两个等级关系,外围为顶层,若外围内的内围轮廓还包含了其他的轮廓信息,则内围内的所有轮廓均归属于顶层;
CV_RETR_TREE: 检测所有轮廓,所有轮廓建立一个等级树结构。外层轮廓包含内层轮廓,内层轮廓还可以继续包含内嵌轮廓。
(5)轮廓的近似方法,opencv提供了四种方法,解释如下:
CV_CHAIN_APPROX_NONE:保存物体边界上所有连续的轮廓点到contours向量内;
CV_CHAIN_APPROX_SIMPLE:仅保存轮廓的拐点信息,把所有轮廓拐点处的点保存入contours向量内,拐点与拐点之间直线段上的信息点不予保留;
CV_CHAIN_APPROX_TC89_L1:使用teh-Chinl chain 近似算法;
CV_CHAIN_APPROX_TC89_KCOS:使用teh-Chinl chain 近似算法。
(6)Point偏移量,所有的轮廓信息相对于原始图像对应点的偏移量,相当于在每一个检测出的轮廓点上加上该偏移量,并且Point还可以是负值!
详细解释可参考: findContours函数参数详解
2、绘制轮廓
绘制轮廓的算子:
drawContours( InputOutputArray image, InputArrayOfArrays contours,int contourIdx, const Scalar& color, int thickness = 1, int lineType = LINE_8, InputArray hierarchy = noArray(), int maxLevel = INT_MAX, Point offset = Point() );
(1)目标图像;
(2)所有的输入轮廓。每个轮廓都被存储为一个点向量,其定义与findContours的参数2相同;
(3)指示要绘制哪条轮廓的索引数。如果它是负的,就画出所有的轮廓线;
(4)指定绘制轮廓的颜色;
(5)指定轮廓线的粗细。如果它是负的,则绘制轮廓内部(经测试,为负值情况下轮廓内部完全被涂成设定的轮廓线颜色);
(6)指定轮廓线的类型,参考LineTypes,一般设定为8,即LINE_8;
(7)层次结构的可选信息。只在你想画某些指定的轮廓的时候才需要进行设置;
(8)绘制轮廓的最大数量。如果它是0,则只绘制指定的轮廓线。如果为1,则绘制轮廓线和所有嵌套轮廓线。如果它是2,则绘制轮廓线、所有嵌套轮廓线、所有嵌套到嵌套轮廓线等。该参数只有在存在层次结构时才被考虑在内。(与轮廓检索方式即findContours的参数4有关)
(9)轮廓点的偏移量。
3、提取轮廓重心坐标
说明:形状轮廓重心坐标的提取主要是利用图像的矩来计算。
什么是图像的矩?把图像的像素看做密度函数f(x,y),对该像素点求期望E,即是图像的矩(原点矩)。公式如下:
原点矩:
图像的矩主要表征了图像区域的几何特征,又称几何矩,由于具有旋转、平移、尺度等不变的特兴奋,所以又称为不变矩。一般来说,一阶矩和零阶矩可以计算某个形状的重心,二阶矩可以计算形状的方向。
关于矩以及图像矩的详细解释可以参考:矩、中心矩、质心、patch方向
提取重心坐标方法:
//声明一个图像的矩Moments M;//计算要绘制轮廓的矩M = moments(contours[i]);//求取轮廓重心的X坐标double cX = double(M.m10 / M.m00);//求取轮廓重心的Y坐标double cY = double(M.m01 / M.m00);
关于m10、m01、m00的解释:
关于重心坐标的求解过程的详细解释可以参考: 中心距求解
4、示例
示例代码:
Mat img = imread("C:\\Users\\SUNSONG\\Desktop\\图片\\Image_02.PNG");Mat gray_img, thresh_img;//灰度cvtColor(img, gray_img, COLOR_BGR2GRAY);threshold(gray_img, thresh_img, 0, 255, THRESH_TRIANGLE);//开运算Mat ellipse = getStructuringElement(MORPH_ELLIPSE, Size(13, 13));morphologyEx(thresh_img, thresh_img, MORPH_OPEN, ellipse, Point(-1, -1), 2);************以上为图像处理过程****************************************//寻找轮廓vector<vector<Point>> contours;vector<Vec4i> hierarchy1;findContours(thresh_img, contours, hierarchy1, RETR_LIST, CHAIN_APPROX_NONE, Point());//获取某一轮廓重心点Moments M;M = moments(contours[0]);double cX = double(M.m10 / M.m00);double cY = double(M.m01 / M.m00);//绘制轮廓drawContours(img, contours, 0, Scalar(0, 255, 0), 2, 8, hierarchy1);//显示轮廓重心并提取坐标点circle(img, Point2d(cX, cY), 1, Scalar(0, 255, 0), 2, 8);putText(img, "center", Point2d(cX - 20, cY - 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 255, 0), 1, 8);cout << "重心坐标:" << cX << " " << cY << endl << endl;
运行结果:
遇到的问题:
在寻找边界过程中,findContours算子寻找的轮廓中总是包含图像的整体轮廓(如下图所示),给寻找边界带来了很大干扰,目前还不知如何解决这个问题?????
OPENCV之寻找并绘制轮廓以及提取轮廓重心坐标相关推荐
- pythonopencv提取轮廓区域_Python + Opencv 实现轮廓提取,轮廓区域面积计算
Python + Opencv2 实现轮廓提取,轮廓区域面积计算: 对图像处理时,会遇到这样一个场景:找到图像主体轮廓,这是其一,可能为了凸显轮廓,需要用指定的颜色进行标记:轮廓标记完可能任务还没有结 ...
- OpenCV(25)轮廓检测(轮廓提取、属性、近似轮廓、外接矩形和外接圆)
目录 一.轮廓检测基础理论 1.轮廓概述 2.API介绍 1.cv.findContours函数(查找轮廓) 2.cv.drawContours函数(画出轮廓) 检测轮廓并画出:(用二值图检测轮廓) ...
- 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形
FindContours 在二值图像中寻找轮廓 int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_cont ...
- opencv 图像 抠图 算法_opencv提取轮廓与抠图
自然图像抠图/视频抠像技术梳理(image matting, video matting)-计算机视视觉专题1 图像抠图算法学习 - Shared Sampling for Real-Time Alp ...
- Python,OpenCV轮廓属性、轮廓检测及绘制
Python,OpenCV轮廓属性.轮廓检测及绘制 1. 效果图 2. 源码 2.1 轮廓属性 2.2 轮廓特征 参考 这篇博客将介绍OpenCV中的轮廓,轮廓的特征及属性(质心,面积,轮廓,近似轮廓 ...
- 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)
使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...
- 图像轮廓的提取和绘制
转自:http://blog.csdn.net/gnuhpc/archive/2009/06/18/4278105.aspx <>var ultimaFecha = ' '; <&g ...
- OpenCV成长之路:直线、轮廓的提取与描述
http://ronny.blog.51cto.com/8801997/1394139 OpenCV成长之路:直线.轮廓的提取与描述 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...
- 【OpenCV】直线、轮廓的提取与描述
基于内容的图像分析的重点是提取出图像中具有代表性的特征,而线条.轮廓.块往往是最能体现特征的几个元素,这篇文章就针对于这几个重要的图像特征,研究它们在OpenCV中的用法,以及做一些简单的基础应用. ...
最新文章
- GitHub开源城市结构公交路线数据可视化
- 硅谷人眼中的2018年十大前沿科技预测
- MVC 区域内默认控制器不能访问(Multiple types were found that match the controller named ‘Index')...
- ios+openflow 问题
- leetcode 1143. 最长公共子序列
- DL之DeepLabv1:DeepLabv1算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
- 10万奖金!探索图像盲降噪新方式,旷视2022 MegCup炼丹大赛等你来战
- oracle数据库swap占用率高,Oracle数据库所在服务器swap严重
- MyBatis mapper 注解过程中通过 LanguageDriver 实现动态 SQL
- [渝粤教育] 中国地质大学 自动控制原理 复习题
- Dubbo服务启动时Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to bind NettyServer on /19
- 联合国超10万名员工记录遭泄露
- Ubuntu Fcitx 乱码教训
- 【一天一个C++小知识】006. 浮点数在计算机内部的表示与转换
- 2022年Google开发者大会纪录
- mysql atlas 文档_Atlas首页、文档和下载
- CentOS 7设置NTP、SSH服务
- 关于outlook签名图片大小的说明
- excel提取文字、字母、符号
- [生存志] 第60节 论语章节概览
热门文章
- javascript Wscript.Shell
- 不眠的硅谷——Just For Fun
- google、bing、baidu、shodan、censys、ZoomEye 搜索引擎 高级用法
- 2022年上半年亚太区金融科技投资总额较2021年下半年增长一倍以上,达到破纪录的418亿美元 | 美通社头条...
- 【C语言】字符串和内存函数介绍及模拟实现
- 代码坏味道与重构之冗赘的元素和夸夸其谈的通用性
- PCBA加工锡膏溶焊工艺简介
- 哪款微信编辑器排版最简单?
- 数据从业者的一次“典型”面试
- 浅谈目标检测中的特征冲突与不对齐问题