【python】OpenCV—Shape Detection

文章目录

1、需求描述

给出图像,找出其轮廓,近似确认其为几变形图像

输入

输出

2、代码实现

python 复制代码
# 导入必要的包
import cv2
import argparse
import imutils
import os


class ShapeDetector:
    def __init__(self):
        pass

    def detect(self, c):
        # 初始化形状名称并近似轮廓
        shape = "unidentified"
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.04 * peri, True)
        # 如果形状是一个三角形,它将有3个顶点
        if len(approx) == 3:
            shape = "triangle"
        # 如果形状有4个顶点,它要么是正方形,要么是矩形
        elif len(approx) == 4:
            # 计算轮廓的包围框,并使用包围框计算高宽比
            (x, y, w, h) = cv2.boundingRect(approx)
            ar = w / float(h)
            # 正方形的长宽比大约等于1,否则,形状就是矩形
            shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
        # 如果形状是一个五边形,它将有5个顶点
        elif len(approx) == 5:
            shape = "pentagon"
        # 否则,我们假设形状是一个圆
        else:
            shape = "circle"
        # 返回形状的名称
        return shape


# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", default="inpaint.jpg", help="path to the input image")
args = vars(ap.parse_args())


# 加载图像并将其调整图像大小,以便更好地近似形状
image = cv2.imread(args["image"])
resized = imutils.resize(image, width=300)
ratio = image.shape[0] / float(resized.shape[0])
# 将调整后的图像转换为灰度,稍微模糊它,并阈值化
gray = cv2.cvtColor(resized, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)
thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imwrite(f"{os.path.splitext(args['image'])[0]}_thresh.jpg", thresh)
# 在阈值化图像中找到轮廓并初始化形状检测器
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
                        cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
sd = ShapeDetector()


# 遍历所有轮廓
for index, c in enumerate(cnts):
    # 计算轮廓的中心,然后仅使用轮廓检测形状的名称
    M = cv2.moments(c)
    cX = int((M["m10"] / M["m00"]) * ratio)
    cY = int((M["m01"] / M["m00"]) * ratio)
    shape = sd.detect(c)
    # 将轮廓(x, y)坐标乘以调整比例,然后在图像上绘制轮廓和形状的名称
    c = c.astype("float")
    c *= ratio
    c = c.astype("int")
    cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
    cv2.putText(image, shape, (cX, cY), cv2.FONT_HERSHEY_SIMPLEX,
                0.5, (0, 0, 255), 2)
    # 显示输出图像
    cv2.imwrite(f"{os.path.splitext(args['image'])[0]}_{str(index)}.jpg", image)
    cv2.imshow("Image", image)
    cv2.waitKey(0)

代码中可以明确看到对多边形的定义

3、涉及到的库函数

cv2.arcLength

cv2.arcLength 是 OpenCV(Open Source Computer Vision Library)库中的一个函数,用于计算多边形的周长或轮廓的弧长。这个函数在处理图像中的形状分析、轮廓检测等任务时非常有用。它接受一个轮廓(轮廓是一系列的点,通常通过边缘检测或轮廓查找算法获得)作为输入,并返回该轮廓的周长。

python 复制代码
length = cv2.arcLength(contour, True)
  • contour:输入轮廓,应该是一个点集(通常是numpy.ndarray类型),这些点定义了轮廓的形状。

  • 第二个参数是True或False,指定轮廓是否应该被近似为闭合的(通过连接轮廓的第一个点和最后一个点)。如果轮廓已经是闭合的,或者你不关心轮廓是否闭合,可以传递True。如果轮廓不是闭合的,但你不希望它被视为闭合的,应该传递False。注意,这个参数在一些版本的OpenCV中可能不是必需的,或者默认值为True。

返回值

  • length:返回轮廓的周长或弧长,类型为浮点数。

cv2.approxPolyDP

cv2.approxPolyDP 是 OpenCV 库中的一个函数,用于对轮廓或曲线进行多边形逼近。该函数使用 Douglas-Peucker 算法来减少表示轮廓或曲线所需的点数,同时尽可能保持其形状特征。这个功能在图像处理、计算机视觉和机器学习等领域中非常有用,特别是在处理轮廓检测、形状分析等方面。

python 复制代码
approx = cv2.approxPolyDP(curve, epsilon, closed)
  • curve:要逼近的曲线或轮廓,可以是二维点的列表或 NumPy 数组。
  • epsilon:逼近精度。这是一个距离值,表示原始曲线上的点与逼近后的多边形之间的最大距离。epsilon 的值越小,逼近结果越精确,但所需的点数也可能越多。
  • closed:一个布尔值,指定逼近后的多边形是否闭合。如果为 True,则逼近后的多边形是闭合的;如果为 False,则逼近结果可能不是闭合的。

返回值

  • approx:逼近后的多边形,以二维点的列表或 NumPy 数组的形式返回。

需要注意的是,epsilon 的值是一个权衡参数,需要根据具体应用进行调整。较小的 epsilon 值会产生更精确的逼近结果,但可能会增加计算复杂性和所需的存储空间。较大的 epsilon 值则会产生更简单的逼近结果,但可能会损失一些形状细节。因此,在实际应用中,需要根据具体需求来选择合适的 epsilon 值。

4、案例










更多例子

输入图片

输出图片

输入图片

输出图片

5、参考

参考学习来自:OpenCV形状检测

相关推荐
飞yu流星26 分钟前
c++ stl 遍历算法和查找算法
开发语言·c++·算法
苦瓜汤补钙1 小时前
(二)QT——按钮小程序
开发语言·c++·qt·小程序
山海青风1 小时前
OpenAI 实战进阶教程 - 第七节: 与数据库集成 - 生成 SQL 查询与优化
数据库·人工智能·python·sql
SomeB1oody3 小时前
【Rust自学】18.1. 能用到模式(匹配)的地方
开发语言·后端·rust
萧月霖3 小时前
Scala语言的安全开发
开发语言·后端·golang
金融OG3 小时前
98.2 AI量化开发:基于DeepSeek打造个人专属金融消息面-AI量化分析师(理论+全套Python代码)
人工智能·python·算法·机器学习·数学建模·金融
LUCIAZZZ3 小时前
弄懂Runable,Callable,Future之间的关系
java·开发语言
山海青风4 小时前
OpenAI 实战进阶教程 - 第四节: 结合 Web 服务:构建 Flask API 网关
前端·人工智能·python·chatgpt·flask
白嫖勇者4 小时前
Python(Pandas)数据分析学习
python·数据分析·pandas
MATLAB代码顾问4 小时前
MATLAB实现多种群遗传算法
开发语言·matlab