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之寻找并绘制轮廓以及提取轮廓重心坐标相关推荐

  1. pythonopencv提取轮廓区域_Python + Opencv 实现轮廓提取,轮廓区域面积计算

    Python + Opencv2 实现轮廓提取,轮廓区域面积计算: 对图像处理时,会遇到这样一个场景:找到图像主体轮廓,这是其一,可能为了凸显轮廓,需要用指定的颜色进行标记:轮廓标记完可能任务还没有结 ...

  2. OpenCV(25)轮廓检测(轮廓提取、属性、近似轮廓、外接矩形和外接圆)

    目录 一.轮廓检测基础理论 1.轮廓概述 2.API介绍 1.cv.findContours函数(查找轮廓) 2.cv.drawContours函数(画出轮廓) 检测轮廓并画出:(用二值图检测轮廓) ...

  3. 【OpenCV函数】轮廓提取;轮廓绘制;轮廓面积;外接矩形

    FindContours 在二值图像中寻找轮廓  int cvFindContours( CvArr* image, CvMemStorage* storage, CvSeq** first_cont ...

  4. opencv 图像 抠图 算法_opencv提取轮廓与抠图

    自然图像抠图/视频抠像技术梳理(image matting, video matting)-计算机视视觉专题1 图像抠图算法学习 - Shared Sampling for Real-Time Alp ...

  5. Python,OpenCV轮廓属性、轮廓检测及绘制

    Python,OpenCV轮廓属性.轮廓检测及绘制 1. 效果图 2. 源码 2.1 轮廓属性 2.2 轮廓特征 参考 这篇博客将介绍OpenCV中的轮廓,轮廓的特征及属性(质心,面积,轮廓,近似轮廓 ...

  6. 使用Python,OpenCV进行涂鸦(绘制文字、线、圆、矩形、椭圆、多边形轮廓、多边形填充、箭头~)

    使用Python,OpenCV进行涂鸦(绘制文字.线.圆.矩形.椭圆.多边形轮廓.多边形填充.箭头) 1. 效果图 2. 原理 2.1 绘制线:cv2.line(canvas, (300, 0), ( ...

  7. 图像轮廓的提取和绘制

    转自:http://blog.csdn.net/gnuhpc/archive/2009/06/18/4278105.aspx <>var ultimaFecha = ' '; <&g ...

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

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

  9. 【OpenCV】直线、轮廓的提取与描述

    基于内容的图像分析的重点是提取出图像中具有代表性的特征,而线条.轮廓.块往往是最能体现特征的几个元素,这篇文章就针对于这几个重要的图像特征,研究它们在OpenCV中的用法,以及做一些简单的基础应用. ...

最新文章

  1. GitHub开源城市结构公交路线数据可视化
  2. 硅谷人眼中的2018年十大前沿科技预测
  3. MVC 区域内默认控制器不能访问(Multiple types were found that match the controller named ‘Index')...
  4. ios+openflow 问题
  5. leetcode 1143. 最长公共子序列
  6. DL之DeepLabv1:DeepLabv1算法的简介(论文介绍)、架构详解、案例应用等配图集合之详细攻略
  7. 10万奖金!探索图像盲降噪新方式,旷视2022 MegCup炼丹大赛等你来战
  8. oracle数据库swap占用率高,Oracle数据库所在服务器swap严重
  9. MyBatis mapper 注解过程中通过 LanguageDriver 实现动态 SQL
  10. [渝粤教育] 中国地质大学 自动控制原理 复习题
  11. Dubbo服务启动时Caused by: com.alibaba.dubbo.remoting.RemotingException: Failed to bind NettyServer on /19
  12. 联合国超10万名员工记录遭泄露
  13. Ubuntu Fcitx 乱码教训
  14. 【一天一个C++小知识】006. 浮点数在计算机内部的表示与转换
  15. 2022年Google开发者大会纪录
  16. mysql atlas 文档_Atlas首页、文档和下载
  17. CentOS 7设置NTP、SSH服务
  18. 关于outlook签名图片大小的说明
  19. excel提取文字、字母、符号
  20. [生存志] 第60节 论语章节概览

热门文章

  1. javascript Wscript.Shell
  2. 不眠的硅谷——Just For Fun
  3. google、bing、baidu、shodan、censys、ZoomEye 搜索引擎 高级用法
  4. 2022年上半年亚太区金融科技投资总额较2021年下半年增长一倍以上,达到破纪录的418亿美元 | 美通社头条...
  5. 【C语言】字符串和内存函数介绍及模拟实现
  6. 代码坏味道与重构之冗赘的元素和夸夸其谈的通用性
  7. PCBA加工锡膏溶焊工艺简介
  8. 哪款微信编辑器排版最简单?
  9. 数据从业者的一次“典型”面试
  10. 浅谈目标检测中的特征冲突与不对齐问题