大家好,欢迎收听小木的第六讲,第六讲我们主要讲的内容是轮廓检测。说道轮廓检测。轮廓怎么检测呢,那么我们就要引入一个轮廓检测算法:

这个算法是日本的铃木桑发明的。这位日本人写了一篇论文,叫做:

Topological structural analysis of digitized binary images by border following,

百度文库上面有下载地址:

https://wenku.baidu.com/view/6cb52ede360cba1aa811dad5.html

说道百度文库,我要吐槽一下,我觉得CNKI上面的文章都不如百度文库上面网友写的好。今天吐槽的话题太多了,首先说一下天朝不合理的科研评优制度。现在考一个博士,比如哈工大、同济,大连理工等学校竟然要一篇SCI,同济甚至是2篇。我就想请问你们是在TMD考老师呢还是在考学生?你们同济可能有设备,有经费。但是其它普通学校有吗?你以为学生是巧妇?巧妇都难做无米之炊,你们要求真是无理。我就请问你们985学校的筛选制度,真的能筛选出NB的学生吗?这个升学坑爹。还有坑爹的是大家喜欢到知网去灌水,结果知网上面全是垃圾文,而且瞎乱引用,引用次数高的还不一定是好的。所以大家找一篇好文实在是太TMD难了。我就想请问,什么国家奖学金那几万块钱,真的这么重要么,就不能发几篇好文章上去吗?

说完这个,还得吐槽一下这个日本人铃木先生,铃木先生这篇文章是1985年写的,也就是说我们现在是2018年,我们足足落后了小日本20多年。美帝就更不用说了。所以我想对现在的年轻人说,我们历史必须铭记,但是不是无脑黑,也不能无脑当HJ。这点应该学习罗永浩老师,把小日本的好东西都学到手,这个才是最重要的。不能学洁洁良,更不能学那些水军。如果认为我说的对,你们必须得转发我的文章!

好了,废话说完了,进入正题。这个日本人发明了一种能够检测轮廓的算法,这个轮廓检测是在一张只有1和只有0的二值图片中执行的,而这个算法定义了几个概念:

(1)框架:框架就是指图片的第一列、最后一列、第一行、最后一行像素,这四个长条组成的一个矩形框框,我们这些点是黑点,也就是0。

(2)背景:除了框架之外,和框架属于同一层级的像素点,这些点也是黑点,也就是0。

(3)外轮廓:外轮廓就是指包裹了一堆白点的最外围的白点。

(4)内轮廓:内轮廓是指在包裹了一堆白点的最内部的白点。

用一张图片表示会很清晰:

在这张图片中,S1是背景,也是框架层。S2是包裹的一堆白点,这堆白点的最外层和框架层紧密相连,B1就是S2的外轮廓,B2就是S2的内轮廓。

那么我们怎么用计算机判断一张图片上的点是外轮廓还是内轮廓呢?

那么就得进行如下的步骤:

(1)首先,我们设定外部框架的边界值NBD为1。

(2)接着忽略最外层的框架,然后从图片的第二行的最左侧开始,判断:

如果这个数字是1,并且它的左侧的像素是0,那么我们令(i,j)为这个像素,然后令(i2,j2)=(i,j-1)为它左侧的像素(如果是第一次运算,那么坐标就是(2,2),它要是1,(2,1)是0,那么(i,j)=(2,2)、(i2,j2)=(i,j-1)=(2,1))。然后我们令NBD=NBD+1,并且认为这个点是外轮廓点。

如果这个数字是大于等于1的,并且它的右侧像素是0,那么我们令(i,j)为这个像素,然后令(i2,j2)=(i,j+1)为它右侧的像素。(如果是第一次运算,那么坐标就是(2,2),它要是1,(2,3)是0,那么那么(i,j)=(2,2)、(i2,j2)=(i,j+1)=(2,3)),并且认为这个点是内轮廓点。

如果是其它的情况,那么,令直接跳到最后一步。

(3)下一步是判断这个点到底是内轮廓还是外轮廓,我们用这个表格来判断:

这里面B’表示的是上一个按照我们这个步骤走的点是什么轮廓。B表示我们当前的点是什么轮廓。如果这是第一次,没有上一次的点,那么直接认为是外轮廓就好了。

(4)从点(i,j)开始,它的邻近地方有8个点(3*3)的格子之内,然后我们以(i2,j2)点为起始点,然后顺时针的沿着这8个点移动,一直走走走走,唉,发现了一个不为0的像素点,并且令这个点为(i1,j1)。如果这8个点都为0的话,令中心点(i,j)为-NBD,然后直接跳到最后一步。

(5)如果(i1,j1)存在的话,那么我们令(i2,j2)=(i1,j1),(i3,j3)=(i,j)。

(6)然后我们从点(i3,j3)开始,以(i2,j2)为起始点,然后逆时针移动遍历(i,j)邻近地方的8个点。找到第一个不为0的点((i2,j2)这个点不算)。然后令它为(i4,j4)。注意这里肯定不会存在没有不为0点的情况,因为(i3,j3)=(i,j),上一次循环都循环一次了,没有早退出了。

(7)然后我们判断:如果(i3,j3)前面的点(i3,j3+1)为0的话,那么我们把(i3,j3)这个点的像素值赋予-NBD。

如果(i3,j3)点前面的点不为0,且(i3,j3)这个点的像素为1的话,那么把(i3,j3)的像素值赋予NBD。

如果是其它情况的话,这个值保持不变。

(8)判断,如果(i4,j4)=(i,j)也就是我们最开始的那个值,且(i3,j3)=(i1,j1),那么我们跳到最后一步。如果要不符合条件,我们返回到(6)继续计算直到满足条件。

(9)我们回到我们最开始选择的那个点,也就是(i,j)然后我们往右边移动一格,如果已经到达末尾了,换到下一行的左边。如果我们于(i,j)那点的像素不为1的话,我们令LNBD等于(i,j)那点的像素的绝对值。

这九步,我们就把轮廓计算完毕了。在铃木桑的论文中,它举了一个例子来说明这个算法,如下所示:

这个是它最后得到的结果,但是我有点不信,下面我按照它同样的算法,自己手算了一遍:

我的最后结果是分为4部分,4个外轮廓,没有内轮廓,而铃木的是5部分,有一个内轮廓。我认为我的里面那个-3不是内轮廓,因为内轮廓应该是八方向都封闭起来的,而这两个-3只有2个方向是封闭,两个方向直接和背景连接。所以我认为是外轮廓。

谁对谁错我不好说,你们自己分析,然后对这两个人的案例对错评论一下,告诉我哈!

这样,我们的轮廓就检测完毕了。我们用OPENCV检测也非常的简单:

(1)首先我们导入一张图片。

(2)将图片二值化变成黑白图像

(3)运用轮廓搜索算法找出轮廓

(4)显示轮廓。

代码如下:

import cv2import numpy as np#导入图片img = cv2.imread("D:/xiaomu/opencv6-1.jpg")#显示图片cv2.imshow("orgin",img)#定义一个卷积核的尺寸kernel = np.ones((3,3))  #导入图片,进行开闭运算去噪声img=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)img=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)#将图像进行二值化处理,小于10的为0,大于的255ret, thresh = cv2.threshold(cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), 10, 255, cv2.THRESH_BINARY)#找出图片的轮廓image, contours, hier = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)#绘制轮廓cv2.drawContours(img, contours, -1, (255, 0, 0), 3)#显示带轮廓的图片cv2.imshow("contours", img)#等待按键退出cv2.waitKey()cv2.destroyAllWindows()

结果:

下节课讲什么还没决定好,到时候再说哦!

———————————————

如果对我的课程感兴趣的话,欢迎关注小木希望学园-微信公众号:

mutianwei521

也可以扫描二维码哦!

白话文讲计算机视觉-第六讲-轮廓检测算法相关推荐

  1. slam十四讲之第六讲带你看懂g2o

    slam十四讲之第六讲g2oCurveFitting代码 #include <iostream> #include <g2o/core/g2o_core_api.h> #inc ...

  2. 计算机视觉知识表征,计算机视觉基础 - 边缘和轮廓检测

    深度学习以外的视觉算法 尽管深度学习为基础的计算机视觉技术攻克了很多传统算法的难题,但了解这些传统的视觉算法依然是有必要的,因为它们提供了很多不同的理解计算机视觉的视角.并且相比于深度神经网络来说,计 ...

  3. 白话文讲计算机视觉-第十讲-灰度阈值分割

    灰度阈值是啥意思呢?我们慢慢说. 1.灰度图 我们现在有一张彩色图,我们给它用黑白的方式变现,就形成灰度图,如图所示. 图1 那究竟怎么转换的呢?很简单,我们根据如下公式,把BGR三个通道换成一个Gr ...

  4. 计算机视觉 特征检测与匹配 轮廓检测

    虽然孤立的边缘可用于各种应用,例如线检测和稀疏立体匹配,但当连接到连续轮廓时,它们变得更加有用. 如果使用某个函数的零交叉检测到边缘,则将它们向上链接起来很简单,因为相邻的边缘共享公共端点.将边缘链接 ...

  5. 3D Vision 八讲:第六讲

    目录 八.结构计算 1.三角测量法 (1)代数(线性)方法 (2)几何方法 (3)重建误差与相机之间角度关系 八.结构计算 1.三角测量法 三角测量法:给定空间三维点在两个或多个图像中的投影点,重建出 ...

  6. 边缘和轮廓检测——计算机视觉的应用

    计算机视觉的重点是从计算机中的视频和图像中提取有意义的信息.在本文中,我们将从初学者开始探索一个使用 OpenCV 的出色计算机视觉项目. 其标题是"使用计算机视觉进行边缘和轮廓检测&quo ...

  7. 【OpenCV入门指南】第五篇 轮廓检测 上

    <[OpenCV入门指南]第三篇Canny边缘检测>中介绍了边缘检测,本篇介绍轮廓检测,轮廓检测的原理通俗的说就是掏空内部点,比如原图中有3*3的矩形点.那么就可以将中间的那一点去掉. 在 ...

  8. OpenCV学习——轮廓检测

    前言 轮廓检测是传统视觉中非常常用的功能,这里简单记录一下opencv中的轮廓检测算法使用方法,至于理论,后续有机会再去细品. 国际惯例: OpenCV官方的轮廓检测教程python版 OpenCV中 ...

  9. opencv 基础(6):基于OpenCV的轮廓检测

    利用轮廓检测,我们可以检测出目标的边界,并容易地定位.它通常是许多有趣应用,如图像前景提取,简单图像分割,检测和识别. 轮廓线在计算机视觉中的应用 一些非常酷的应用程序已经建立,使用轮廓进行运动检测或 ...

最新文章

  1. gradient 渐变
  2. DM8168 TILER(3)
  3. jq之省市区级联插件
  4. 基于顺序存储结构的图书信息表的逆序存储(C++)
  5. Poj 1077 eight(BFS+全序列Hash解八数码问题)
  6. 【理论】RS-232、RS-485、RS-422通信接口标准介绍
  7. Python小白的飞桨之旅
  8. C++中#define宏定义的min与max函数
  9. 《给中国学生的第四封信:大学四年应是这样度过》
  10. 安全狗等级保护建设服务内容有哪些?
  11. 综合架构-高可用服务
  12. 非接触式通信技术之RFID
  13. 实现Web端指纹登录
  14. Android开发之Zip下载解压
  15. 导数与微分总复习——“高等数学”
  16. Atollic TrueSTDIO下修改STM32L475VE的变量分配地址
  17. 无法写入最后一个_U盘无法正常读写,还能识别还能抢救一下
  18. 什么是Cython?让Python有C语言的速度
  19. 虚拟机Linux如何做快照、备份以及快照的使用
  20. 标准日期格式转化为“年月日时分秒”——padStart()补0问题

热门文章

  1. 【英语演讲】Introductory Speech
  2. 嵌入式Linux系统中打印机驱动的移植
  3. C++ std::shared_ptr:为什么使用shared_ptr及其一些问题
  4. LeetCode 24:两两交换链表中的节点、1662. 检查两个字符串数组是否相等
  5. bat运行的时候不弹出黑框框
  6. 基于java软式装修设计网站mp4计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
  7. JS 通过 Promise 实现延时执行,支持链式调用
  8. maven搭建项目报错
  9. 联通内测迷你SIM 将引iPad、iPhone4
  10. 关于HTTP请求出现 405状态码 not allowed的解决办法