OpenCV 例程200篇 总目录-202205更新
文章目录
- 【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征
-
- 2. 轮廓的特征描述
-
- 2.2 轮廓的面积、周长、质心和近似多边形
-
- 2.2.1 轮廓的面积
- 2.2.2 轮廓的周长
- 2.2.3 轮廓的质心
- 2.2.4 轮廓的近似
- 2.2.5 轮廓的凸包(凸壳)
- 例程 12.4:轮廓的面积、周长、质心和近似多边形
【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征
2. 轮廓的特征描述 在对实际图像进行轮廓查找时,得到的轮廓数量很多。获取轮廓后,通常基于轮廓的特征进行筛选、识别和处理。例如,基于轮廓的周长和面积对轮廓进行筛选,然后绘制筛选的目标轮廓或其最小外接矩形。
常用的轮廓特征,包括图像距、轮廓周长、轮廓近似、凸包、边界矩形、拟合图形等特征。
2.2 轮廓的面积、周长、质心和近似多边形
面积、周长、质心是常用的轮廓特征。
2.2.1 轮廓的面积 几何矩实质是面积或质量。函数 cv.moments() 的返回值 Moments[‘m00’] 表示轮廓面积。
轮廓的面积也可以使用函数 cv2.contourArea() 计算。
函数说明:
cv.contourArea(contour[, oriented] ) → retval
- contour:顶点构成的二维向量组(如轮廓列表 contours 中的一个轮廓)
- oriented:定向区域标志,默认值为 False,返回面积的绝对值,Ture 时则根据轮廓方向返回带符号的数值
2.2.2 轮廓的周长 轮廓的周长可以使用函数 cv2.arcLength() 计算。
函数说明:
cv.arcLength(curve, closed=True) → retval
- curve:以顶点构成的二维向量组表示的曲线(如轮廓列表 contours 中的一个轮廓)
- closed:曲线闭合标志,True 表示闭合曲线
2.2.3 轮廓的质心 轮廓的质心 (Cx,Cy) 可以通过一阶矩计算:
C x = M 10 / M 00 C y = M 01 / M 00 Cx = M_{10} / M_{00} \\ Cy = M_{01} / M_{00} Cx=M10?/M00?Cy=M01?/M00?
2.2.4 轮廓的近似 轮廓的近似是用顶点数量较少的多边形对轮廓进行近似,可以使用函数 cv2. approxPolyDP() 实现。近似多边形的边数取决于设定的最大近似距离。
函数说明:
cv.approxPolyDP(curve, epsilon, closed[, approxCurve]) → approxCurve
- curve:以顶点构成的二维向量组表示的曲线(如轮廓列表 contours 中的一个轮廓)
- approxCurve:近似多边形顶点坐标 (x,y) 的二维向量组
- epsilon:近似精度,浮点数,原始曲线与近似多边形之间的最大距离
- closed:曲线闭合标志,True 表示近似曲线是闭合的
2.2.5 轮廓的凸包(凸壳) 物体的凸包(凸壳)是指包含该物体的最小凸面体。在二维图像中凸壳可以想象为一条刚好包着所有点的橡皮圈。在凸壳与物体边缘之间的部分称为凸陷(Convexity defect)。
OpenCV 中的函数 cv.isContourConvex() 测试轮廓是否为凸面体,函数 cv.convexHull() 获取轮廓的凸壳 。
函数说明:
cv.convexHull(points[, hull[, clockwise[, returnPoints]]]) → hull
cv.isContourConvex( contour) → retval
参数说明:
- points:二维点向量集
- contour:二维点向量集(如轮廓列表 contours 中的一个轮廓)
- hull:输出凸包,凸包顶点的索引向量,或凸包顶点坐标 (x,y) 的二维向量组
- clockwise:方向标志,默认值 False 表示逆时针方向输出凸包,True 为是顺时针
- returnPoints:操作标志,默认值 True 表示返回凸包点集, False 返回凸包点的索引
函数 cv.isContourConvex() 测试轮廓是否为凸面,输入的轮廓必须没有自交叉线。
函数 cv.convexHull() 与函数 cv.drawContours() 配合,可以用来检测物体是否存在缺陷。
例程 12.4:轮廓的面积、周长、质心和近似多边形
# 12.4 轮廓的面积、周长、质心和近似多边形
img = cv2.imread("../images/seagull01.png", flags=1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 灰度图像
plt.figure(figsize=(9, 6))
plt.subplot(231), plt.axis('off'), plt.title("Origin")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# HSV 色彩空间图像分割
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)# 将图片转换到 HSV 色彩空间
lowerBlue, upperBlue = np.array([100, 43, 46]), np.array([124, 255, 255])# 蓝色阈值
segment = cv2.inRange(hsv, lowerBlue, upperBlue)# 背景色彩图像分割
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))# (5, 5) 结构元
binary = cv2.dilate(cv2.bitwise_not(segment), kernel=kernel, iterations=3)# 图像膨胀
plt.subplot(232), plt.axis('off'), plt.title("Tree contour")
plt.imshow(binary, 'gray')# 寻找二值化图中的轮廓
# binary, contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# OpenCV3
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)# OpenCV4~
print("len(contours) = ", len(contours))# 所有轮廓的列表# #绘制全部轮廓,contourIdx=-1 绘制全部轮廓
for i in range(len(contours)):# 绘制第 i 个轮廓
if hierarchy[0][i][3]==-1:# 最外层轮廓
rect = cv2.minAreaRect(contours[i])# 最小外接矩形
x, y = int(rect[0][0]), int(rect[0][1])# 最小外接矩形的中心(x,y)
text = "{}:({},{})".format(i, x, y)
img = cv2.drawContours(img, contours, i, (255, 255, 255), -1)# 绘制第 i 个轮廓, 内部填充
img = cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255))
# print("i=", i, ",contours[i]:", contours[i].shape, ",hierarchy[0][i] =", hierarchy[0][i], "text=", text)
plt.subplot(233), plt.axis('off'), plt.title("Contours")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 轮廓的特征矩
cnt = contours[0]# 第 0 个轮廓
moments = cv2.moments(cnt)# 返回字典,几何矩 mpq, 中心矩 mupq 和归一化矩 nupq
huM = cv2.HuMoments(moments)# 计算 Hu 不变矩# 轮廓面积
area = cv2.contourArea(cnt)
print("area by moments['m00']: ", moments['m00'])
print("area of contour: ", area)# 轮廓的质心 (Cx, Cy)
if moments['m00'] > 0:
cx = round(moments['m10'] / moments['m00'])
cy = round(moments['m01'] / moments['m00'])
print("centroid of contour: ({}, {})".format(cx, cy))
cv2.circle(img, (cx, cy), 5, (0, 0, 255), -1)# 在轮廓的质心上绘制圆点
plt.subplot(234), plt.axis('off'), plt.title("Contour centroid")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
else:
print("moments['m00'] = 0")# 轮廓的周长
perimeter = cv2.arcLength(cnt, True)# True表示输入是闭合轮廓
print("centroid of perimeter: {:.1f}".format(perimeter))# 轮廓近似多边形
epsilon = 0.01 * cv2.arcLength(contours[1], True)
approx = cv2.approxPolyDP(contours[1], epsilon, True)
approx.shape:(15, 1, 2)
cv2.polylines(img, [approx], True, (0, 0, 255), 2)# 绘制多边形
plt.subplot(235), plt.axis('off'), plt.title("Approximate polygon")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 检查轮廓是否为凸面体
isConvex = cv2.isContourConvex(contours[2])# True 凸面体, False 非凸
print("contours[2] ContourConvex?", isConvex)
# 获取轮廓的凸壳
hull = cv2.convexHull(contours[2], returnPoints=True)# 返回轮廓凸壳顶点坐标
print("hull.shape: ", hull.shape)# 凸壳顶点坐标 (x,y), (24, 1, 2)
cv2.polylines(img, [hull], True, (0, 0, 255), 2)# 绘制多边形
plt.subplot(236), plt.axis('off'), plt.title("Contour convex")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))plt.tight_layout()
plt.show()
运行结果:
len(contours) =6
area by moments['m00']:15523.0
area of contour:15523.0
centroid of contour: (394, 380)
centroid of perimeter: 783.5
approx.shape:(15, 1, 2)
contours[2] ContourConvex? False
hull.shape:(24, 1, 2)
文章图片
(本节完)
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125023990)
Copyright 2022 youcans, XUPT
Crated:2022-5-31
欢迎关注 『youcans 的 OpenCV 例程 200 篇』 系列,持续更新中
欢迎关注 『youcans 的 OpenCV学习课』 系列,持续更新中
【youcans|【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征】【youcans 的 OpenCV 例程200篇】194.寻找图像轮廓(cv.findContours)
【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓(cv.drawContours)
【youcans 的 OpenCV 例程200篇】196.图像的矩和不变矩(cv.moments)
【youcans 的 OpenCV 例程200篇】197.轮廓的基本特征
【youcans 的 OpenCV 例程200篇】198.基于不变矩的形状相似性检测
【youcans 的 OpenCV 例程200篇】199.轮廓的外接边界框
【youcans 的 OpenCV 例程200篇】200.轮廓的基本属性
更多内容,请见:
【OpenCV 例程200篇 总目录-202206更新】
推荐阅读
- 李宏毅机器学习HW|Homework 1: COVID-19 Cases Prediction (Regression)
- youcans|【youcans 的 OpenCV 例程200篇】199.轮廓的外接边界框
- youcans|【youcans 的 OpenCV 例程200篇】195.绘制图像轮廓(cv.drawContours)
- youcans|【youcans 的 OpenCV 例程200篇】194.寻找图像轮廓(cv.findContours)
- youcans|【youcans 的 OpenCV 例程200篇】196.图像的矩和不变矩(cv.moments)
- 着色器|老照片(黑白照片)如何一键上色()
- GDAL算法进度条使用说明
- Python中的图形绘制——3D绘图
- ers 会取代计算机视觉中的