【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形状检测

相关推荐
无语......8 分钟前
安装uv并管理 Python / 包
开发语言·python·uv
道剑剑非道10 分钟前
【C++ 仿 MFC 反射系统】
开发语言·c++·mfc
测试老哥11 分钟前
白盒测试用例的设计
自动化测试·软件测试·python·测试工具·职场和发展·单元测试·测试用例
2201_7568473320 分钟前
Golang如何处理JSON空值null_Golang JSON空值处理教程【精通】
jvm·数据库·python
YuanDaima204828 分钟前
双指针基础原理与题目说明
数据结构·人工智能·python·算法·leetcode·手撕代码
hef28829 分钟前
怎么诊断MongoDB Config Server响应极慢的问题_高频Auto-split导致的元库写入压力
jvm·数据库·python
qq_3806191634 分钟前
html怎么用deno运行_Deno如何作为本地服务器运行HTML文件
jvm·数据库·python
小鱼~~34 分钟前
进程和线程
python
Elastic 中国社区官方博客41 分钟前
在 Elastic 中使用 OpenTelemetry 内容包可视化 OpenTelemetry 数据
大数据·开发语言·数据库·elasticsearch·搜索引擎
断眉的派大星43 分钟前
pytorch中保存训练模型和加载训练模型的用法
人工智能·pytorch·python