今天依然是研究图像特征检测算法的一天,不得不说,前辈的智慧真是无穷无尽,想出了那么多种算法,真是太强了,本小菜鸟只是学习一点皮毛都得研究好久。。。

好了步入正题,今天要整理的笔记内容是获取轮廓的内接圆。

内接圆的定义是:与多边形各边都相切的圆,就称为该多边形的内接圆,每个正多边形都存在一个唯一的内接圆。从定义上来看,内切圆是和多边形的边相切的,但是轮廓大多数都是不规则的,很难找到一个和轮廓各边都相切的圆,甚至说连轮廓的各条边都很难确定下来。可能这也是OpenCV中没有直接通过轮廓来获取轮廓内接圆的API的原因之一吧。

虽然OpenCV中没有直接的API可以使用,但是通过内接圆的定义,我们可以知道,如果能把轮廓看成一个多边形,那么再来求它的内接圆就会方便得多。所以,我们将一个不规则的轮廓看成一个具有许许多多短边的多边形,也就是变成一个不规则多边形。

而且,既然要求轮廓的内接圆,从圆的特点来说,想要唯一的确定一个圆,就是要知道它的圆心和半径。好的,那现在的问题就从求取轮廓的内接圆,巧妙地转变成求取某个点和一个多边形的距离和关系。

很棒的是,在上一篇笔记OpenCV(26)中,记录了一个点多边形检测的APIpointPolygonTest(),这个API能够得到某个点和某个多边形之间的关系,例如这个点是在多边形内部、外部、或者是在多边形上,还能得到该点距离多边形的像素距离。

那么,当我们使用这个API计算轮廓内的所有像素点和该轮廓的距离,然后进行距离统计:找到轮廓内部距离轮廓线最远的一个点。则该点就是这个轮廓内接圆的圆心,这个距离的绝对值就是轮廓内接圆的半径。

也就是说,如果设置pointPolygonTest()返回其像素距离而且这个像素距离是当前点距离轮廓最近的距离,那么当这个点在轮廓内部(与轮廓距离为正数),且其返回的距离是最大值的时候,这个距离就是轮廓的最大内接圆的半径,该点就是最大内接圆的圆心。既然已经知道了圆心和半径,我们就可以唯一地确定一个圆,这就是轮廓的最大内接圆。

下面看一下实现代码:

 Mat src = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\contours.png");Mat src_gray, src_gaus, src_binary;cvtColor(src, src_gray, COLOR_BGR2GRAY);GaussianBlur(src_gray, src_gaus, Size(), 1, 1);threshold(src_gaus, src_binary, 0, 255, THRESH_BINARY | THRESH_OTSU);vector<vector<Point>> contours;vector<Vec4i> hierarchy;findContours(src_binary, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);for (int i = 0; i < contours.size(); i++){Mat  dist = Mat::zeros(src.size(), CV_32F);     //定义一个Mat对象,存放原图中每个点到该轮廓的距离,为浮点型数据//遍历每个点,计算该点到轮廓距离for (int row = 0; row < src.rows; row++){for (int col = 0; col < src.cols; col++){//通过点多边形检测计算获得点到轮廓距离,并存放至dist中dist.at<float>(row, col) = pointPolygonTest(contours[i], Point(col, row), true);}}//计算dist中,最大值和最小值,以及其位置坐标double minVal, maxVal;Point maxloc, minloc;minMaxLoc(dist, &minVal, &maxVal, &minloc, &maxloc);int radio = abs(maxVal);         //对最大值求绝对值,即为内接圆半径Point center;center = maxloc;         //某点与轮廓距离为最大值,则该点为内接圆圆心circle(src, center, radio, Scalar(0, 0, 255), 2, 8, 0);}imshow("src", src);

上述代码中,首先将输入图像经过转灰度图、高斯模糊、二值化来预处理图像,然后进行轮廓检测。将检测到的轮廓进行遍历,然后对图像中的每个点去进行点多边形检测,获得该点到当前轮廓的距离。再把每个点到轮廓的距离存放在一个和原图像尺寸相同的Mat对象中,这个Mat对象的每个元素都是一个距离值。计算完所有像素点的距离值后,获取其中最大的距离值以及对应的点坐标,这个距离值就是最大内接圆的半径,点坐标就是最大内接圆的圆心。然后我们就可以通过圆心和半径将轮廓的最大内接圆绘制出来了。

下面是绘制出来的轮廓最大内接圆的效果图:

由于这里检测出来的轮廓是最外层轮廓,所以获取到的也是外层轮廓的最大内接圆。可以看到,通过这种委婉的方式求得的轮廓最大内接圆,还是能有比较好的效果的。
今天的笔记就记录到这里啦,谢谢阅读~

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

OpenCV4学习笔记(27)——轮廓的最大内接圆相关推荐

  1. OpenCV4学习笔记(55)——基于KNN最近邻算法实现鼠标手写数字识别

    在上一篇博客<OpenCV4学习笔记(54)>中,整理了关于KNN最近邻算法的一些相关内容和一个手写体数字识别的例子.但是上次所实现的手写体数字识别,每次只能固定地输入测试图像进行预测,而 ...

  2. OPENCV-4 学习笔记

    OPENCV-4 学习笔记 ROI-设定感兴趣的区域(region of interest) 定义: Mat imageROI; //方法一:通过Rect指定矩形区域 imageROI=image(R ...

  3. OpenCV4学习笔记(57)——基于GrabCut图像分割算法实现背景替换与背景虚化效果

    在上一篇笔记<OpenCV4学习笔记(56)>中,整理了关于在OpenCV中使用GrabCut图像分割算法的相关内容,那么本次笔记就以GrabCut算法为基础来实现对图像的背景替换和背景虚 ...

  4. OpenCV4学习笔记(76)——基于ArUco模块+QT实现增强现实(AR)

    在<OpenCV4学习笔记(75)>中,整理记录了对于一副静态图像如何实现一个简单的增强现实效果,今天我们就结合ArUco模块和QT来实现对于实时视频流的AR效果. 我们需要先创建一个QT ...

  5. OpenCV4学习笔记(41)——ORB特征提取描述算法

    今天要整理记录的笔记内容是特征算法中比较常用的一种--ORB特征提取描述算法,顾名思义,ORB算法包含了对特征点的提取和描述这两个部分.而在上次的博文<OpenCV4学习笔记(39)>中, ...

  6. 英伟达DeepStream学习笔记27——deepstream下载历史版本

    英伟达DeepStream学习笔记27--deepstream下载历史版本 https://docs.nvidia.com/metropolis/deepstream-archive.html htt ...

  7. OpenCV4学习笔记(47)——BRISK特征提取描述算法

    今天要整理记录的是OpenCV中BRISK特征提取描述算法的运用. BRISK特征提取描述算法全称为 Binary Robust Invariant Scalable Keypoints(二进制鲁棒不 ...

  8. OpenCV4学习笔记(23)——几何矩、中心矩、归一化矩和Hu矩的计算,以及基于Hu矩的轮廓匹配

    在上次的笔记中,整理记录了有关轮廓发现及轮廓信息提取的一部分内容,同时还记录了Hu矩的计算方式,今天就来记录一下Hu矩的一个应用--轮廓匹配. 在<OpenCV学习笔记(19)--模板匹配> ...

  9. 影像组学视频学习笔记(27)-SimpleITK包介绍、Li‘s have a solution and plan.

    本笔记来源于B站Up主: 有Li 的影像组学的系列教学视频 本节(27)主要讲解: 功能强大的图像处理工具SimpleITK包 视频中李博士演示了SimpleITK的两个基本功能:图像格式转换以及图像 ...

  10. python面向对象编程72讲_2020-07-22 Python学习笔记27类和面向对象编程

    一些关于自己学习Python的经历的内容,遇到的问题和思考等,方便以后查询和复习. 声明:本人学习是在扇贝编程通过网络学习的,相关的知识.案例来源于扇贝编程.如果使用请说明来源. 第27关 类与面向对 ...

最新文章

  1. 瓶框(bottle)架学习之模版使用
  2. 【题单 - 数学专题】最大公约数
  3. 2012年第一个工作日
  4. 建立apk定时自动打包系统第三篇——代码自动更新、APP自动打包系统
  5. 切换数据库_如何快速切换到其他数据库实例
  6. 邮件 查看html源码,微软 Win10解决邮件显示HTML源代码的问题
  7. mysql某个表被行锁了_MySQL 行锁和表锁的含义及区别详解
  8. C++基础教程之重载运算符和重载函数
  9. 软件测试--缺陷报告常见问题03
  10. maya mentray_mental ray2016中文版下载|
  11. 微软服务器补丁每月几号发布,微软补丁日安全通告 |9 月份
  12. 什么是透明、匿名、高匿代理?详解!
  13. php网页框架模板,用PHP制作静态网站的模板框架(四)
  14. VMware下安装win7教程
  15. python绘制包络线_包络线和包络谱计算程序
  16. 小米四启用虚拟按键以及禁用实体按键
  17. Introduction to Track-To-Track Fusion
  18. Python 爬取 Google Map POI
  19. 基尔霍夫电压定律解析
  20. c调用c++ qt_C#调用C++(QT5.5.1项目)的C++/CLI(CLR项目)项目技术笔记

热门文章

  1. android封装全局调用的toast_安卓全局toast
  2. 计算机密码忘了 开不了机怎么办,开机密码忘了怎么办
  3. 俞扬 新书_哇,太好了...新书
  4. 水晶易表Xcelsius 2008安装指南 支持WIN10 64位 + office2016
  5. mysql数据库输入窗体vbs代码_VBS教程:VBScript 与窗体
  6. python程序画中国围棋棋盘
  7. 使用百度识图 完成图片识别和文字识别
  8. 人工智能之启发式搜索算法
  9. Java解析XML字符串
  10. 【STM32技巧】使用STM32 HAL库的硬件I2C驱动RX8025T实时时钟芯片