当前位置:网站首页>【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
边栏推荐
- How to test CIS chip?
- 微服务远程Debug,Nocalhost + Rainbond微服务开发第二弹
- Apifox interface integrated management new artifact
- 嵌入式系统真正安全了吗?[ OneSpin如何为开发团队全面解决IC完整性问题 ]
- 万字总结数据存储,三大知识点
- Don't fall behind! Simple and easy-to-use low code development to quickly build an intelligent management information system
- 最新版本的CodeSonar改进了功能安全性,支持MISRA,C ++解析和可视化
- Oracle 存儲過程之遍曆
- Klocwork code static analysis tool
- How C language determines whether it is a 32-bit system or a 64 bit system
猜你喜欢
大厂经典指针笔试题
Don't fall behind! Simple and easy-to-use low code development to quickly build an intelligent management information system
Yolov6:yolov6+win10--- train your own dataset
嵌入式系统真正安全了吗?[ OneSpin如何为开发团队全面解决IC完整性问题 ]
如何满足医疗设备对安全性和保密性的双重需求?
[philosophy and practice] the way of program design
I Basic concepts
[MySQL - Basic] transactions
CodeSonar如何帮助无人机查找软件缺陷?
Opencv学习笔记 高动态范围 (HDR) 成像
随机推荐
Optimization cases of complex factor calculation: deep imbalance, buying and selling pressure index, volatility calculation
One click deployment of any version of redis
Data sorting in string
Get webkitformboundary post login
Graduation season | regretful and lucky graduation season
Traversée des procédures stockées Oracle
【解决】package ‘xxxx‘ is not in GOROOT
Small guide for rapid formation of manipulator (11): standard nomenclature of coordinate system
You want to kill a port process, but you can't find it in the service list. You can find this process and kill it through the command line to reduce restarting the computer and find the root cause of
浅尝不辄止系列之试试腾讯云的TUIRoom(晚上有约,未完待续...)
字符串中数据排序
php 获取图片信息的方法
AIRIOT助力城市管廊工程,智慧物联守护城市生命线
Flask1.1.4 werkzeug1.0.1 source code analysis: Routing
Make this crmeb single merchant wechat mall system popular, so easy to use!
VMWare中虚拟机网络配置
Mrs offline data analysis: process OBS data through Flink job
如何满足医疗设备对安全性和保密性的双重需求?
ERROR: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your
实战:sqlserver 2008 扩展事件-XML转换为标准的table格式[通俗易懂]