- 轮廓与边缘的区别,轮廓是图像中物体最外层的线条,边缘是图像最外层线条内还包含着其他的线条
轮廓逼近方法,左边是第一种,全部显示轮廓,右边的第二种,把能表示轮廓的点显示出来,其余线条不显示,第二种方式更省内存
上面这个是轮廓检测的方法,在使用这个方法之前我们还需要进行其他的步骤
目录
1 使用二值图像 cv2.cvtColor(cv2.COLOR_BGR2GRAY)
6.1 外接矩形 boundingRect()与rectangle()
6.2 外接圆 minEnclosingCircle()与circle()
1 使用二值图像 cv2.cvtColor(cv2.COLOR_BGR2GRAY)
- 这一步是为了更高的准确率而做的,如果不要准确率可以不做
我们转完灰度图,之后进行阈值处理,阈值处理在 1.图像基本操作 中的14提到过,处理过后我们把图片显示出来
2 轮廓检测 findContours()
之后我们再使用最上面的那个方法
这个方法有三个返回值,我们一个一个看
- binary
这个就是我们的二值图像,我们可以显示过来看一下
- contours
这个里面保存的是轮廓的信息
我们再看一下shape
一共479个
- hierarchy
这个是层级,每一个轮廓保存到不同层级,这个我们放到后面讲
3 绘制轮廓 drawContours()
我们使用drawContours方法,这个方法的参数如下
- draw_img是我们要画的图像
- contours是我们的所有轮廓
- -1是轮廓索引,我们刚才有479个,我们可以把479个的其中一个画出来,也可以使用-1,把所有的轮廓都画出来
- (0,0,255)是用什么颜色的画出来,我现在是用红色画出来
- 2是线条宽度
绘制之后将绘制的结果展示出来
- 注:我们不要在原图上画,在原图上画会覆盖掉原图
这个猫的图轮廓太多了,我们换一个轮廓少的图更能体现出轮廓的意思,我们换成下面这个图
我们在读取图片时更改一下
然后运行
这个是轮廓索引为-1的情况,下面我们看第0条轮廓是什么样的
我们可以看到是这个三角形的外轮廓
我们再看索引为1的轮廓
我们发现是这个三角形的内轮廓,还有其他几个轮廓我就不一一展示了
4 轮廓特征
此时我们已经绘制出来了轮廓,我们可以对轮廓进行特征提取
我们只能对轮廓一个一个进行特征提取而不能提取轮廓整体特征,所以我们先取出第0条轮廓(取第一条,第二条都可以)
我们在这里将计算轮廓面积和周长,还可以提取其他的特征,我就不在这介绍了
- 面积 contourArea()
- 周长 arcLength()
- 当轮廓闭合我们使用True,不闭合使用False
5 轮廓近似
5.1 原理
轮廓近似可以把不规则的轮廓转换为规则的轮廓
如上图所示,我们得到的轮廓是应该是在那五个突出的小棍应该是圆的,我们可以近似为尖的
实际上是使用直线替代曲线,我们比如要近似下面的AB曲线,我们首先会设定一个阈值,我们叫它T,之后我们找到一个近似的点C,C到到AB连接线的垂线段,我们叫它D
- 如果D < T,我们就画两条直线AC,CB,用AC,CB两条线代替弧线AB
- 如果D > T,那么我们就不能只用两条直线来替代弧线AB,而是更多的直线
如果E的对应垂线段F还比阈值大,那就使用更多的直线
5.2 代码实现 approxPolyDP()
我们首先把这个轮廓绘制出来
在绘制的时候我们选择的全部轮廓的第7个轮廓作为我们的新的全部轮廓,之后再把新的全部轮廓都画出来
之后我们对这个轮廓进行近似处理
eposilon是我们设置的阈值,也就是理论部分的T,是0.1的周长
approxPolyDp有三个参数
- cnt 要近似的轮廓
- eposilon 阈值
- True 轮廓是否闭合,闭合为True,不闭合为False
然后我们把近似后的轮廓approx画出来
当我们的阈值越小的时候,和我们实际的轮廓越像,比如我现在搞成0.03
6 轮廓外接其他形状
6.1 外接矩形 boundingRect()与rectangle()
获取轮廓后我们使用boudingRect获取轮廓起始(左上角)的坐标(x,y),然后获取整个轮廓的宽w与高h
之后我们使用绘制矩形框功能rectangle,把轮廓的矩形框绘制出来
rectangle参数
- img 要绘制的图片
- (x,y) 绘制矩形起始点(左上角)
- (x+w,y+h) 绘制矩形框的终止点(右下角)
- (0,255,0)矩形框的颜色,我当前是绿色
- 2 矩形框线条宽度
我们的矩形框面积是w*h,我们也可以使用contourArea获取原始轮廓的面积,我们得到这两个值也可以得出原始轮廓与轮廓矩形的面积比
6.2 外接圆 minEnclosingCircle()与circle()
这次我们用三角形的轮廓演示,获取完轮廓后,使用minEnclosingCir获取外接圆的圆心与半径,然后把圆心改变为整形元组,半径改变为整形
之后使用circle在图片上绘制矩形
circle参数
- img 要绘制的图像
- center 圆心
- radius 半径
- (0,255,0) 颜色
- 2 线条宽度