网站首页 > 技术文章 正文
什么是轮廓近似?
Contour approximation 使用Ramer - Douglas - Peucker (RDP)算法,旨在通过减少给定阈值的顶点来简化折线。通俗地说,我们采用一条曲线并减少其顶点数量,同时保留其大部分形状。我将在这里给出算法的粗略概念。给定曲线的起点和终点,算法将首先找到距离连接两个参考点的线最大距离的顶点。让我们将其称为max_point。如果max_point距离小于阈值,我们会自动忽略起点和终点之间的所有顶点,使曲线成为一条直线。如果max_point超出阈值,我们将递归重复该算法,现在将其max_point作为参考之一,并重复检查过程。
假如,我们要 开发一个自动导航的机器人,在机器人导航的过程中,必然会搜集大量的路径数据,进而指导机器人的前进,但是很多时候,路径上的拐点很多,这就加大了计算的负担,如何能尽可能地保留原始路径数据,又可以降低大量的计算,这就需要路径的一些估算,这就要使用到本次的路径轮廓近似原理。
cv2.approxPolyDP实现轮廓近似原理
# -*- coding: utf-8 -*-
import numpy as np
import cv2
image = cv2.imread("C:/Users/angel/Desktop/image.png")
cv2.imshow("Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 200, 255,
cv2.THRESH_BINARY_INV)[1]
cv2.imshow("Thresh", thresh)
cv2.waitKey(0)
首先我们导入需要的第三方包,这里最主要的是CV2,然后使用imread函数加载一张本地的图片,由于我们将使用图像中形状的边界,因此我们将图像从 RGB 转换为灰度(第6 行)。一旦采用灰度格式,就可以使用 OpenCV 的threshold函数(第7-8行)轻松抠图该形状。
# 在阈值图像中找到最大的轮廓
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
#不同opencv版本的不同
if len(cnts) == 2:
cnts = cnts[0]
elif len(cnts) == 3:
cnts = cnts[1]
c = max(cnts, key=cv2.contourArea)
#在输出图像上绘制轮廓的形状,计算
边界框,并显示轮廓中的点数
output = image.copy()
cv2.drawContours(output, [c], -1, (0, 255, 0), 3)
(x, y, w, h) = cv2.boundingRect(c)
text = "original, num_pts={}".format(len(c))
cv2.putText(output, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (0, 255, 0), 1)
print("[INFO] {}".format(text))
cv2.imshow("Original Contour", output)
cv2.waitKey(0)
使用 OpenCV 的findContours函数,我们可以挑选出给定图像中所有可能的轮廓,我们使用了RETR_EXTERNAL参数,它只返回可用轮廓的单一表示,使用的另一个参数是CHAIN_APPROX_SIMPLE。这将删除单个链线连接中的许多顶点,这些顶点本质上是冗余的。然后我们从轮廓数组中抓取最大的轮廓,并使用drawContours函数把外框形状画出来。
for eps in np.linspace(0.001, 0.05, 10):
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, eps * peri, True)
output = image.copy()
cv2.drawContours(output, [approx], -1, (0, 255, 0), 3)
text = "eps={:.4f}, num_pts={}".format(eps, len(approx))
cv2.putText(output, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (0, 255, 0), 1)
print("[INFO] {}".format(text))
cv2.imshow("Approximated Contour", output)
cv2.waitKey(0)
我们需要一个 value eps,它将作为测量顶点的阈值,利用此阈值进行轮廓近似计算的参数
在第2行,使用 计算轮廓的周长cv2.arcLength函数。然后我们使用该cv2.approxPolyDP函数,启动轮廓近似过程(第3行)。eps×peri乘积值充当近似精度,通过遍历不同的eps,进行轮廓的近似计算。
通过运行代码,我们可以看出,随着eps值不断增加,其轮廓顶点数不断减少,直到顶点数量不再减少为止,这表明轮廓近似算法确实有效。
[INFO] original, num_pts=402
[INFO] eps=0.0010, num_pts=30
[INFO] eps=0.0064, num_pts=25
[INFO] eps=0.0119, num_pts=18
[INFO] eps=0.0173, num_pts=15
[INFO] eps=0.0228, num_pts=14
[INFO] eps=0.0282, num_pts=10
[INFO] eps=0.0337, num_pts=7
[INFO] eps=0.0391, num_pts=6
[INFO] eps=0.0446, num_pts=5
[INFO] eps=0.0500, num_pts=5
当然,在应用中,我们需要找到合适的eps的值,以便在保证轮廓精度的情况下,降低计算的成本。
猜你喜欢
- 2024-10-12 智能监测:皮带输送系统堵料问题的解决方案
- 2024-10-12 Python-OpenCV 10. 图像边缘算法 opencv边缘识别
- 2024-10-12 Net AI学习笔记系列第五章 net教程
- 2024-10-12 深度学习和神经网络——图像读取和显示
- 2024-10-12 十三句Python搞定找茬游戏 找茬游戏规则
- 2024-10-12 「深度学习」手把手教你用PythonOpenCV物体识别-识别水果
- 2024-10-12 OpenCV找出图片中的圆并标注圆心 opencv检测圆代码
- 2024-10-12 分享3个干货满满的Python实战项目,点赞收藏
- 2024-10-12 OpenCV(28)——凸包 opencv轮廓凹凸
- 2024-10-12 基于OpenCV实战:动态物体检测 opencv动态阈值
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)