轮廓识别
相关概念
二值化图像(Threshold)
把灰度图像转换为二值图像(也称作二进制图像,每个像素只有两个可能的取值),将灰度值根据阈值的大小设为0或255(把大于阈值的灰度值设为极大值,小于阈值的灰度值设为极小值),也就是将整个图像呈现出只有黑和白的视觉效果,从而实现二值化
二进制图像中有以下两个定义:
- 前景:用1表示,表示特征区域
- 背景:用0表示,对象之外的区域
根据阈值选取的不同,二值化的算法分为固定阈值和自适应阈值
当把一个RGB图像转化为灰度图像时,采用加权平均的方法来计算灰度值,一种常用的方法是亮度权重:0.299R,0.587G,0.114B,这些加权数值时基于人眼对不同颜色的敏感度而设计,因为人眼对绿色感知更敏感,所以绿色权重高。在opencv中进行转换时,就是应用上述权重
有向轮廓和无向轮廓
两种描述轮廓的方式
有向轮廓:有起点和终点,用于更详细的形状分析,如计算周长,旋转角度
无向轮廓:无方向的封闭曲线,用于简化轮廓处理,如轮廓匹配,逼近
函数介绍
Canny
用于执行边缘检测,更容易理解单通道图像
1 | edges = cv2.Canny(image, threshold1, threshold2, apertureSize, L2gradient) |
- image:单通道灰度图像
- threshold1和threshold2用于控制边缘检测的阈值函数,1设置低阈值,2高阈值。边缘强度高于2的被视为强边缘,介于1和2的被视为弱边缘,其他的被视为非边缘点。通过调整这两个阈值,可以控制检测边缘的数量和质量
- L2gradient:布尔值,指定计算梯度幅度时是否使用L2范数(欧氏距离)False使用L1范数计算
findContours
opencv库的一个函数,用于在二进制图像中查找对象(白色)的边界轮廓,四个参数:
- image:二进制图像
- mode:轮廓的检索模式
- cv2.RETR_EXTERNAL仅提取最外部轮廓
- cv2.RETR_LIST提取所有轮廓,不建立父子关系
- cv2.RETR_CCOMP提取所有轮廓并组织成两层的层次结构
- cv2.RETR_TREE提取所有轮廓,并构建完整的层次结构
- method:表示轮廓的逼近方法,用于压缩轮廓的表示
- cv2.CHAIN_APPROX_NONE存储所有轮廓点,不做压缩
- cv2.CHAIN_APPROX_SIMPLE仅存储水平,垂直和对角线方向的端点,其余的舍弃
- cv2.CHAIN_APPROX_TC89_L1和cv2.CHAIN_APPROX_TC89_KCOS应用Teh-Chin链逼近算法,获得更精确的表示
- offset:可选参数,通常为(0, 0),表示偏移量
两个返回值:
- contours:一个列表,包含检测到的轮廓
inRange
创建二进制掩码,可以设定RGB的范围来选择感兴趣的图像,在颜色范围内的像素设置为1,不在的设置为0(黑色)
1 | cv2.inRange(src, lower_bound, upper_bound) |
bitwise_and
执行位与操作,将原始图像与二进制掩码相乘,以保留蓝色像素。用于图像融合,图像分割等任务
1 | # 定义蓝色的颜色范围(BGR值) |
threshold
将灰度图像二值化
1 | import cv2 |
四个参数:原始灰度化图像,阈值,最大像素值(通常为255,表示前景),阈值类型(THRESH_BIANARY表示像素值大于阈值的被设置为255,小于的被设为0)
两个返回值:使用的阈值(不关心 用_表示)和二值化图像
还有其他的阈值类型:
- cv2.THRESH_BINARY_INV:反向二进制阈值,像素值大于阈值的被设置为0,小于的被设置为225
- cv2.SHRESH_TRUNC:截断阈值。像素值大于阈值的被设为阈值,小于阈值的保持不变
- cv2.THRESH_TOZERO:像素值小于阈值被设为0,大于阈值的保持不变
- cv2.THRESH_TOZERO_INV:小于阈值的保持不变,大于阈值的被设为0
contourArea
用于计算轮廓面积,接受一个轮廓对象(通常是findContours返回的轮廓列表中的一个轮廓)作为参数,返回轮廓面积
1 | contours = np.array([[100, 100], [200, 100], [150, 200]]) |
arcLength
计算轮廓的周长(弧长),两个参数:
- curve:轮廓对象
- closed:布尔值,指定是否封闭
如果轮廓的第一个点和最后一个点不是相同的点,**True会自动添加一条线段来封闭轮廓,False则不会添加额外的线段 **
getStructuringElement
用于创建形态学操作元素,与形态学操作如腐蚀、膨胀、开运算、闭运算一起使用
cv2.MORPH_RECT:矩形结构元素cv2.MORPH_CROSS:十字形结构元素cv2.MORPH_ELLIPSE:椭圆形结构元素ksize:指定结构元素大小,通常为奇数
anchor:可选参数,指定锚点位置,默认为结构元素中心
该函数返回一个矩阵
morphologyEx
执行形态学操作,应用于二值图像,以改变对象的形状,大小和结构
op形态学操作类型:
cv2.MORPH_ERODE:腐蚀操作cv2.MORPH_DILATE:膨胀操作cv2.MORPH_OPEN:开运算(先腐蚀后膨胀)cv2.MORPH_CLOSE:闭运算(先膨胀后腐蚀)cv2.MORPH_GRADIENT:形态学梯度(膨胀图像减去腐蚀图像)cv2.MORPH_TOPHAT:顶帽运算cv2.MORPH_BLACKHAT:黑帽运算
1 | kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) |
approxPloyDP
用于多边形逼近,简化和近似复杂轮廓的多边形,减少顶点,用于在轮廓检测后对轮廓进行后处理。三个参数:
- curve:轮廓对象,一个numpy数组
- epsilon:逼近精度,是一个最大允许距离的参数(原始轮廓和逼近后的多边形之间的最大距离),较大的epsilon会导致更少的点,较小的会产生更多的点
- closed:布尔值,指定逼近后的多边形是否封闭,若为True,则逼近后的多边形首尾连接
1 | #获取轮廓角点坐标 |
rectangle
绘制矩形,可以是实心或仅包含边框,用于标记对象,参数:
- img:要在其上绘制矩形的图像
- pt1:矩形的左上角顶点坐标,两个整数值的元组
- pt2:右下角
- color
- thickness
- lineType
- shift:像素坐标的小数位数,通常为0
putText
在图像上绘制文本,用于标注
- img
- text
- org:文本的左下角坐标,元组
- fontFace:字体类型
- fontScale:文本大小比例因子
- color、thickness、lineType
- bottomLeftOrigin:布尔值,指定坐标原点位置,True左下角,False左上角,默认为False
boundingRect
用于计算包含整个轮廓的最小矩形边框
1 | x, y, w, h = cv2.boundingRect(points) |
- (x,y)是矩形左上角坐标(遍历轮廓的所有点,找到最小、最大x,y坐标)
- w,h是矩形的宽度和高度
drawContours
用于在已有图像上绘制轮廓线,参数:
- image:要在其上绘制轮廓的图像
- contours:轮廓列表
- contoursIdx:要绘制轮廓的索引,如果为负数,则绘制所有轮廓
- color:颜色
- thickness:轮廓线的粗细,如果为负数,则轮廓被填充
- lineType:线条类型
- hierarchy:层次结构
1 | import cv2 |
np.zeros用于创建一个零填充的数组,所有元素(像素值)初始化为0,(400, 400, 3)表示尺寸为400x400像素,三维数组(三个颜色通道)代表了一个彩色图像,这里是一个黑色画布。np.unit8指定数组的数据类型为无符号的8位整数,用于表示像素值在0到255的图像
contours = [np.array([[100, 100], [200, 100], [150, 200]])]解释:contours是一个列表,包含一个元素(NumPy数组),即一个轮廓,一组像素的坐标。该轮廓由三个坐标点组成,若为4个坐标,就是根据顺序首尾相连。而且每个轮廓是个独立的numpy数组
完整代码
1 | import cv2 |