什么是图像轮廓?
图像轮廓是具有相同颜色或强度的连续点的曲线。轮廓的作用:
1、用于图形分析
2、物体的识别与检测
注意点:
1、为了检测的准确性,需要先对图像进行二值化或Canny操作
2、画轮廓时会修改输入的图像
轮廓查找api:findContours(img,mode,ApproximationMode)
两个返回值,contours和hierarchy
mode的值:
1、RETR_EXTERNAL=0,表示只检测外轮廓
2、RETR_LIST=1,检测的轮廓不建立等级关系
3、RETR_CCOMP=2,每层最多两级
4、RETR_TREE=3,按树形存储轮廓
ApproximationMode的值:
1、CHAIN_APPROX_NONE,保存所有轮廓上的点
2、CHAIN_APPROX_SIMPLE,只保存角点
如何绘制轮廓
绘制轮廓api:drawContours(img,contours,contourIdx,color,thickness,...)img:需要绘制的图片
contours:这些轮廓的坐标点
contourIdx:所有的轮廓是有顺序的,可以设置顺序号将我们想要的展示的轮廓展示出来,-1表示绘制所有轮廓
color:轮廓的颜色
thickness:线宽,-1是全部填充
轮廓的面积与周长
计算轮廓面积与周长在日常生活中是经常遇到的,比如查找的轮廓有部分小轮廓不是我们想要的,这时我们就可以通过轮廓面积去过滤掉小的轮廓。轮廓面积的api:contourArea(contour)
轮廓周长的api:arcLength(curve,closed)
curve:一个轮廓
closed:轮廓是否闭合,闭合设置为True,不闭合设置为False
多边形逼近与凸包
什么是多边形逼近?什么是凸包呢?它们之间有什么联系呢?下图中左边效果是多边形逼近,右边的效果是凸包。对于不规则的图像,我们查找轮廓的时候如果把它画出来,那么它是严格按照轮廓来画的,这样就导致数量非常大,有些情况下我们只需要存一些特征点即可,这就是多边形逼近的作用,减少了数据存储量,同时保存轮廓的特征点。凸包就是把轮廓描述出来,而且是凸出的,不会往下凹。

curve:曲线
epsilon:精度
closed:是否闭合
凸包api:convexHull(points,clockwise,...)
closed:轮廓
clockwise:顺时针还是逆时针
外接矩形
Opnecv外接矩形包括2种类型:最小外接矩形和最大外接矩形。下图中红色矩形是白色图像的最小外接矩形,绿色矩形是白色图像的最大外接矩阵。
最小外接矩形api:minAreaRect(points)
points:轮廓点
最小外接矩形的返回值是RotatedRect,RotatedRect共包含3个重要组成部分:
- x,y:起始点
- width,height:宽度和高度
- angle:角度
array:轮廓点
最大外接矩形的返回值是Rect,Rect共包含2个部分,起始点,宽度和高度。
import cv2 import numpy as np # 画线函数 def drawLine(img,points,line_color): index=0 while index=2000: # 绘制轮廓线 cv2.drawContours(img,contour,-1,(0,0,255),1) # 获取多边形逼近的点 approx=cv2.approxPolyDP(contour,20,True) # 获取凸包的点 hull=cv2.convexHull(contour) print(approx,len(approx)) # 使用多边形逼近的点绘制最小外接矩形 r=cv2.minAreaRect(approx) box=cv2.boxPoints(r) box=np.int0(box) # 绘制最小外接矩形 cv2.drawContours(img,[box],-1,(255,0,0),1) # 使用多边形逼近的点获得最大外接矩形起始点,宽度和高度 x,y,w,h=cv2.boundingRect(approx) # 绘制最大外接矩形 cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),1) # 在图片上画多边形逼近和凸包 drawLine(img,approx,line_color=(0,255,0)) drawLine(img,hull,line_color=(255,0,0)) # 显示图片 cv2.imshow('img',img) cv2.imshow('gray',gray) cv2.imshow('binary',binary) cv2.waitKey(0)
代码执行效果图:
