python代码实现OpenCV 轮廓近似原理

本文末尾为大家整理了人工智能学习资料包,需要可自取

历史优秀文章推荐:

刚毕业的AI博士年薪近百万,人工智能人才已抢疯

人工智能图像识别深度解析:弱人工智能时代最重要的一个应用

NLP三大特征提取器全梳理:RNN vs CNN vs Transformer

什么是轮廓近似?

Contour approximation 使用Ramer - Douglas - Peucker (RDP)算法,旨在通过减少给定阈值的顶点来简化折线。通俗地说,我们采用一条曲线并减少其顶点数量,同时保留其大部分形状。我将在这里给出算法的粗略概念。给定曲线的起点和终点,算法将首先找到距离连接两个参考点的线最大距离的顶点。让我们将其称为max_point。如果max_point距离小于阈值,我们会自动忽略起点和终点之间的所有顶点,使曲线成为一条直线。如果max_point超出阈值,我们将递归重复该算法,现在将其max_point作为参考之一,并重复检查过程。

假如,我们要 开发一个自动导航的机器人,在机器人导航的过程中,必然会搜集大量的路径数据,进而指导机器人的前进,但是很多时候,路径上的拐点很多,这就加大了计算的负担,如何能尽可能地保留原始路径数据,又可以降低大量的计算,这就需要路径的一些估算,这就要使用到本次的路径轮廓近似原理。

python代码实现OpenCV 轮廓近似原理

原始路径

python代码实现OpenCV 轮廓近似原理

轮廓近似后的图片

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行)轻松抠图该形状。

python代码实现OpenCV 轮廓近似原理

原图片以及隔离开的图形状

# 在阈值图像中找到最大的轮廓
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函数把外框形状画出来。

python代码实现OpenCV 轮廓近似原理

外框轮廓

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

python代码实现OpenCV 轮廓近似原理

轮廓近似原理图

当然,在应用中,我们需要找到合适的eps的值,以便在保证轮廓精度的情况下,降低计算的成本。

我整理了一份关于pytorch、python基础,图像处理opencv\自然语言处理、机器学习、数学基础等资源库,想学习人工智能或者转行到高薪资行业的,大学生都非常实用,无任何套路免费提供,,可以领取的内部资源,人工智能题库,大厂面试题 学习大纲 自学课程大纲还有200G人工智能资料大礼包免费送哦~扫码加V免费领取资料.

### OpenCV轮廓近似实现原理 在计算机视觉领域,OpenCV 提供了一种用于简化复杂轮廓的有效方法,这种方法基于 **Douglas-Peucker 算法** 和 `cv2.approxPolyDP()` 函数。以下是关于该技术的工作机制及其背后的理论。 #### 1. 轮廓近似的核心概念 轮廓近似是一种通过减少点的数量来表示形状的技术,特别适用于处理复杂的几何图形或边界。它能够保留主要特征的同时降低计算成本。`cv2.approxPolyDP()` 是 OpenCV 实现这一功能的主要工具之一[^2]。 此函数采用 Douglas-Peucker 算法作为基础逻辑,这是一种经典的递归算法,旨在用尽可能少的直线段逼近一条曲线。它的目标是在满足一定精度的前提下,最大程度地减少所需的数据量[^3]。 #### 2. Douglas-Peucker 算法详解 Douglas-Peucker 算法的具体流程如下: - 首先定义起点和终点之间的直线段。 - 找到距离这条直线最远的一个点;如果这个最大偏差超过预设阈值,则将这一点标记为新的分割点,并重复上述过程分别针对两部分子轨迹执行相同操作[^5]。 - 如果所有点都位于允许误差范围内,则仅需保存首尾两端即可完成当前阶段的拟合。 这种分治策略使得即使面对非常曲折的对象边缘也能高效运作,最终得到一组能良好描述整体形态的关键顶点集合[^4]。 #### 3. cv2.approxPolyDP 的参数说明 为了便于开发者灵活控制结果质量与性能平衡,`cv2.approxPolyDP()` 设计了几项重要输入选项: ```python epsilon = 0.02 * cv2.arcLength(contour, True) approximation = cv2.approxPolyDP(contour, epsilon, closed=True) ``` - 参数一 (`contour`) 表示待处理的目标区域边界; - 参数二 (`epsilon`) 定义了容许的最大偏离程度,通常建议设置为其周长百分比形式以便适应不同尺度下的需求; - 参数三决定输出是否闭合 (True/False)。 以上代码片段展示了如何利用弧长比例动态调整容忍度从而获得更加鲁棒的结果表现。 --- ### 结论 综上所述,OpenCV轮廓近似功能依托于强大的 Douglas-Peucker 技术框架实现了既简洁又精准的表现效果。通过对原始数据序列逐步筛选过滤直至达到指定标准为止的方式,成功兼顾效率与准确性两大核心诉求^.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值