文章目录
- 一、简介
- 1.意义
- 2.类别
- 二、代码实现
- 1.数据预处理
- 2.计算周长
- 3.绘制外接圆轮廓
- 4.绘制外接矩阵
- 三、总结
一、简介
1.意义
在OpenCV中,轮廓检测后得到的轮廓不仅是一系列点的集合,还可以进一步分析以提取有用的特征。这些特征包括但不限于轮廓的面积、周长、边界框、凸包、质心、方向、矩等。
2.类别
1.面积(Area):
- 轮廓所包围区域的像素数。可以使用cv2.contourArea()函数计算。
2.周长(Perimeter)或弧长(Arc Length):
- 轮廓边界的像素总数。虽然OpenCV没有直接提供计算周长的函数,但可以通过近似轮廓(如使用cv2.approxPolyDP())后计算其顶点间的距离总和来近似得到。
3.边界框(Bounding Rectangle):
- 完全包含轮廓的最小矩形。可以是直角的(cv2.boundingRect()),也可以是旋转的(cv2.minAreaRect()),后者会给出矩形的中心、大小(宽度和高度)以及旋转角度。
4.最小外接圆(Minimum Enclosing Circle):
- 完全包含轮廓的最小圆。可以使用cv2.minEnclosingCircle()函数找到。
5.凸包(Convex Hull):
- 轮廓的凸包是包含轮廓所有点的最小凸多边形。可以使用cv2.convexHull()函数计算。
6.质心(Centroid):
- 轮廓的几何中心或质心。对于二维图像,质心是一个点,表示轮廓的“平均”位置。可以通过矩(Moments)计算得到,cv2.moments()函数返回轮廓的矩,然后可以使用这些矩来计算质心。
7.方向(Orientation):
- 轮廓的主要方向或角度。这通常通过计算轮廓的矩(如Hu矩)或使用其他形状描述符(如轮廓的拟合椭圆)来估计。
8.轮廓的近似(Contour Approximation):
- 使用较少的点来近似表示轮廓,这有助于减少数据量和提高处理速度。可以使用cv2.approxPolyDP()函数进行轮廓的近似。
9.轮廓的矩(Moments):
- 矩是形状描述符,可以用于计算轮廓的各种属性,如面积、质心、惯性矩等。cv2.moments()函数返回一个包含所有计算出的矩的字典。
10.拟合形状(Shape Fitting):
- 可以使用不同的方法将轮廓拟合到基本形状(如圆形、椭圆形、多边形等)。这有助于进一步分析轮廓的形状特征。
二、代码实现
提取以上特征后,你可以根据它们进行进一步的图像处理、分析或识别任务。例如,你可以根据轮廓的面积和周长来过滤掉噪声或不需要的轮廓,或者根据轮廓的质心和方向来对齐或旋转图像。这里我们为大家举部分代码展示。
1.数据预处理
import cv2
phone = cv2.imread('sj.png')
phone_gray = cv2.cvtColor(phone,cv2.COLOR_BGR2GRAY)
cv2.imshow('phone_b',phone_gray)
cv2.waitKey(0)
ret,phone_binary = cv2.threshold(phone_gray,120,255,cv2.THRESH_BINARY)
cv2.imshow('phone_binary',phone_binary)
cv2.waitKey(0)
_,contours,hierarchy = cv2.findContours(phone_binary,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print(hierarchy)
print(len(contours))
image_copy = phone.copy()
image_copy = cv2.drawContours(image=image_copy,contours=contours,contourIdx=-1,color=(0,255,0),thickness=3)
cv2.imshow('Contours_show',image_copy)
cv2.waitKey(0)
这段代码用于读取一张图片,将其转换为灰度图,应用二值化处理,然后查找并绘制轮廓,对图片处理之后方便我们进行后续提取特征。
2.计算周长
在代码中,使用了cv2.contourArea()函数来计算轮廓的面积,并且也使用了cv2.arcLength()函数来计算轮廓的周长(或称为弧长)。
area_0 = cv2.contourArea(contours[0])
area_1 = cv2.contourArea(contours[1])
length = cv2.arcLength(contours[0],closed=True) # 周长
print(length)
轮廓索引:contours[0]和contours[1]分别表示找到的第一个和第二个轮廓。确保contours列表中有足够的元素,否则访问contours[1]可能会引发索引错误。
周长计算:cv2.arcLength()函数用于计算轮廓的周长或弧长。参数closed设置为True表示轮廓是闭合的,这对于大多数通过cv2.findContours()找到的轮廓是适用的。
3.绘制外接圆轮廓
cnt = contours[6]
(x, y), r = cv2.minEnclosingCircle(cnt) # 计算轮廓外接圆
phone_circle = cv2.circle(phone, (int(x), int(y)), int(r), (0, 255, 0), 2) # 绘制外接圆
cv2.imshow('phone_circle', phone_circle)
cv2.waitKey(0)
在代码中,正在从contours列表中获取第七个轮廓(索引为6,这里是铅笔的外接圆),并计算该轮廓的最小外接圆(如下图)。然后,在这个轮廓周围绘制一个绿色的圆来表示这个外接圆。
4.绘制外接矩阵
x, y, w, h = cv2.boundingRect(cnt) # 计算轮廓的外接矩阵
phone_rectangle = cv2.rectangle(phone, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imshow('phone_rectangle', phone_rectangle)
cv2.waitKey(0)
cv2.destroyAllWindows()
在代码中,使用cv2.boundingRect()函数来计算给定轮廓cnt的外接矩形(也称为边界框),并使用cv2.rectangle()函数在原始图像phone上绘制这个矩形。
三、总结
OpenCV中的轮廓特征提取和分析在计算机视觉领域具有许多重要的好处和应用。这些特征不仅可以帮助我们理解和分析图像内容,还能在图像识别、物体检测、形状分析、运动跟踪等多种场景中发挥关键作用。以下是一些OpenCV轮廓特征的主要好处:
- 物体识别和定位:通过检测图像中的轮廓,可以识别和定位图像中的物体。轮廓是物体边界的精确表示,有助于区分不同的物体并确定它们的位置。
- 形状分析:轮廓提供了物体的形状信息。通过分析轮廓的周长、面积、圆形度、矩等特征,可以对物体的形状进行分类和识别。例如,圆形轮廓可能代表一个球或车轮,而矩形轮廓可能代表一个书本或盒子。
- 图像分割:轮廓检测是图像分割的一种重要方法。通过识别图像中的轮廓,可以将图像分割成不同的区域,每个区域对应一个物体或图像的一部分。这有助于后续的图像分析和处理。
- 简化图像表示:轮廓提供了一种简洁的图像表示方式。相比于原始图像,轮廓仅包含物体的边界信息,大大减少了数据量。这种简化的表示方式有助于加快处理速度并降低存储需求。
- 运动跟踪:在视频处理中,轮廓检测可以用于跟踪移动物体的位置和运动轨迹。通过连续检测图像序列中的轮廓,并计算它们之间的对应关系,可以实现对移动物体的实时跟踪。
- 场景理解:通过提取和分析图像中的轮廓,可以帮助计算机理解场景的结构和布局。例如,在自动驾驶领域,通过检测道路上的轮廓,可以识别车道线、交通标志等关键信息,从而辅助车辆进行决策和导航。
- 增强的鲁棒性:轮廓特征通常对光照变化、颜色变化等环境因素具有一定的鲁棒性。这意味着即使在不同的光照条件下或图像颜色发生变化时,仍然能够准确地检测和识别轮廓。
易于集成和扩展:OpenCV提供了丰富的轮廓检测和分析函数,这些函数易于与其他图像处理和分析技术集成。此外,OpenCV的开源特性使得开发者可以轻松地扩展和改进现有的轮廓处理算法。
综上所述,OpenCV的轮廓特征提取和分析在计算机视觉领域具有广泛的应用和重要的好处。它们不仅有助于我们理解和分析图像内容,还能为后续的图像处理和分析任务提供有力的支持。