当前位置:网站首页>【OpenCV 例程200篇】223. 特征提取之多边形拟合(cv.approxPolyDP)
【OpenCV 例程200篇】223. 特征提取之多边形拟合(cv.approxPolyDP)
2022-07-07 18:36:00 【小白YouCans】
『youcans 的 OpenCV 例程200篇 - 总目录』
【youcans 的 OpenCV 例程200篇】223. 特征提取之多边形拟合
目标特征的基本概念
通过图像分割获得多个区域,得到区域内的像素集合或区域边界像素集合。我们把感兴趣的人或物称为目标,目标所处的区域就是目标区域。
特征通常是针对于图像中的某个目标而言的。图像分割之后,还要对目标区域进行适当的表示和描述,以便下一步处理。
“表示”是直接具体地表示目标,以节省存储空间、方便特征计算。目标的表示方法,有链码、多边形逼近(MPP)、斜率标记图、边界分段、区域骨架。
“描述”是对目标的抽象表达,在区别不同目标的基础上,尽可能对目标的尺度、平移、旋转变化不敏感。
边界特征描述子
目标的边界描述符(Boundary descriptors),也称为边界描述子。
轮廓就是对目标边界的描述,轮廓属性是基本的边界描述子。
例如:
- 边界的长度,轮廓线的像素数量是边界周长的近似估计;
- 边界的直径,边界长轴的长度,等于轮廓最小矩形边界框的长边长度;
- 边界的偏心率,边界长轴与短轴之比,等于轮廓最小矩形边界框的长宽比;
- 边界的曲率,相邻边界线段的斜率差;
- 链码,通过规定长度和方向的直线段来表示边界;
- 傅里叶描述符,对二维边界点进行离散傅里叶变换得到的傅里叶系数,对旋转、平移、缩放和起点不敏感;
- 统计矩,把边界视为直方图函数,用图像矩对边界特征进行描述,具有平移、灰度、尺度、旋转不变性。
### 例程 12.12:轮廓的多边形拟合
OpenCV 中的函数 cv.approxPolyDP() 可以用于对图像轮廓点进行多边形拟合。
函数说明:
cv.approxPolyDP(curve, epsilon, closed[, approxCurve=None]) → approxCurve
函数 cv.approxPolyDP 使用 Douglas-Peucker 算法求得一条顶点较少的多折线/多边形,以指定的精度近似输入的曲线或多边形。(参考:拟合直线,拟合椭圆)
参数说明:
- curve:输入点集,二维点向量的集合
- approxCurve:输出点集,表示拟合曲线或多边形,数据与输入参数 curve 一致
- epsilon:指定的近似精度,原始曲线与近似曲线之间的最大距离
- close: 闭合标志,True 表示闭合多边形,False 表示多边形不闭合
注意事项:
Douglas-Peucker算法:
(1)在曲线的起点 A 和终点 B 之间做一条直线 AB,是曲线的弦;
(2)寻找曲线上离该直线段距离最大的点 C,计算其与 AB 的距离 d;
(3)比较距离 d 与设定的阈值 threshold,如果小于设定阈值则该直线段作为曲线的近似,该段曲线处理完毕。
(4)如果距离 d 大于设定阈值,则以 C 点将曲线 AB 分为两段 AC 和 BC,并分别对这两段进行以上步骤的处理。
(5)当所有曲线都处理完毕时,依次连接所有分割点形成的折线,作为曲线的近似。
# 12.12 轮廓的多边形拟合
img = cv2.imread("../images/Fig1105.tif", flags=1)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像
blur = cv2.boxFilter(gray, -1, (5, 5)) # 盒式滤波器,9*9 平滑核
_, binary = cv2.threshold(blur, 205, 255, cv2.THRESH_OTSU + cv2.THRESH_BINARY)
# 寻找二值化图中的轮廓
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # OpenCV4~
print('len:', len(contours))
# 绘制全部轮廓,contourIdx=-1 绘制全部轮廓
imgCnts = np.zeros(gray.shape[:2], np.uint8) # 绘制轮廓函数会修改原始图像
imgCnts = cv2.drawContours(imgCnts, contours, -1, (255, 255, 255), thickness=2) # 绘制全部轮廓
plt.figure(figsize=(9, 6))
plt.subplot(231), plt.axis('off'), plt.title("Origin")
plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
plt.subplot(232), plt.axis('off'), plt.title("Binary")
plt.imshow(binary, 'gray')
plt.subplot(233), plt.axis('off'), plt.title("Contour")
plt.imshow(imgCnts, 'gray')
cnts = sorted(contours, key=cv2.contourArea, reverse=True) # 所有轮廓按面积排序
cnt = cnts[0] # 第 0 个轮廓,面积最大的轮廓,(664, 1, 2)
print("shape of max contour:", cnt.shape[0])
eps = [50, 30, 10]
for i in range(len(eps)):
polyFit = cv2.approxPolyDP(cnt, eps[i], True)
print("eps={}, shape of fitting polygon:{}".format(eps[i], polyFit.shape[0]))
fitContour = np.zeros(gray.shape[:2], np.uint8) # 初始化最大轮廓图像
cv2.polylines(fitContour, [cnt], True, 205, thickness=2) # 绘制最大轮廓,多边形曲线
cv2.polylines(fitContour, [polyFit], True, 255, 3)
plt.subplot(2,3,i+4), plt.axis('off'), plt.title("approxPoly(eps={})".format(eps[i]))
plt.imshow(fitContour, 'gray')
plt.tight_layout()
plt.show()

运行结果:
shape of max contour: 547
eps=50, shape of fitting polygon:5
eps=30, shape of fitting polygon:8
eps=10, shape of fitting polygon:13
运行结果表明,用 13个顶点的多边形可以很好地逼近该轮廓的边界,描述轮廓的边界特征,显著降低了数据量。
【本节完】
版权声明:
[email protected] 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125598167)
Copyright 2022 youcans, XUPT
Crated:2022-6-30
边栏推荐
- Solve the problem that the executable file of /bin/sh container is not found
- Gorilla official: sample code for golang to open websocket client
- Force buckle 643 Subarray maximum average I
- Traversée des procédures stockées Oracle
- 凌云出海记 | 赛盒&华为云:共助跨境电商行业可持续发展
- ERROR: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your
- [award publicity] issue 22 publicity of the award list in June 2022: Community star selection | Newcomer Award | blog synchronization | recommendation Award
- 万字总结数据存储,三大知识点
- When easygbs cascades, how to solve the streaming failure and screen jam caused by the restart of the superior platform?
- Opencv learning notes high dynamic range (HDR) imaging
猜你喜欢

Mrs offline data analysis: process OBS data through Flink job

【mysql篇-基础篇】事务

ISO 26262 - 基于需求测试以外的考虑因素

Helix QAC 2020.2新版静态测试工具,最大限度扩展了标准合规性的覆盖范围

C语言 整型 和 浮点型 数据在内存中存储详解(内含原码反码补码,大小端存储等详解)
Klocwork code static analysis tool

Splicing and splitting of integer ints

AIRIOT助力城市管廊工程,智慧物联守护城市生命线

Chapter 9 Yunji datacanvas company won the highest honor of the "fifth digital finance innovation competition"!

机械臂速成小指南(十一):坐标系的标准命名
随机推荐
Nebula Importer 数据导入实践
ISO 26262 - 基于需求测试以外的考虑因素
Lingyun going to sea | saihe & Huawei cloud: jointly help the sustainable development of cross-border e-commerce industry
Flask1.1.4 Werkzeug1.0.1 源码分析:路由
嵌入式系统真正安全了吗?[ OneSpin如何为开发团队全面解决IC完整性问题 ]
智能软件分析平台Embold
With st7008, the Bluetooth test is completely grasped
【网络原理的概念】
数值法求解最优控制问题(〇)——定义
CodeSonar通过创新型静态分析增强软件可靠性
Referrer和Referrer-Policy简介
School 1 of vulnhub
使用高斯Redis实现二级索引
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
Get webkitformboundary post login
Mongodb由浅入深学习
CodeSonar网络研讨会
Update iteration summary of target detection based on deep learning (continuous update ing)
Force buckle 643 Subarray maximum average I
Graduation season | regretful and lucky graduation season