欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 【python】OpenCV—Shape Detection

【python】OpenCV—Shape Detection

2024/12/26 11:42:23 来源:https://blog.csdn.net/bryant_meng/article/details/140579442  浏览:    关键词:【python】OpenCV—Shape Detection

在这里插入图片描述

文章目录

  • 1、需求描述
  • 2、代码实现
  • 3、涉及到的库函数
    • cv2.arcLength
    • cv2.approxPolyDP
  • 4、案例
  • 5、参考

1、需求描述

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

输入
在这里插入图片描述
输出

在这里插入图片描述

2、代码实现

# 导入必要的包
import cv2
import argparse
import imutils
import osclass ShapeDetector:def __init__(self):passdef 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 *= ratioc = 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)库中的一个函数,用于计算多边形的周长或轮廓的弧长。这个函数在处理图像中的形状分析、轮廓检测等任务时非常有用。它接受一个轮廓(轮廓是一系列的点,通常通过边缘检测或轮廓查找算法获得)作为输入,并返回该轮廓的周长。

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

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

返回值

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

cv2.approxPolyDP

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

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

返回值

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

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

4、案例

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

更多例子

输入图片

在这里插入图片描述

输出图片
在这里插入图片描述

输入图片

在这里插入图片描述

输出图片

在这里插入图片描述

5、参考

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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com