Python,OpenCV应用轮廓逼近算法,检测对象的形状

news/2024/9/22 15:32:22

上一篇博客,我们学习了如何利用Python、OpenCV计算轮廓的中心,这一节学习仅运用轮廓的基本属性来检测其形状,三角形,正方形,矩形,五边形,圆。

(1)利用轮廓逼近,将曲线上的点数减少为更简单的近似版本的过程。
(2)基于该轮廓逼近,检查每种形状具有的顶点数量。有了顶点数,就能准确地标记每个形状。三个点——三角形,四个点(结合宽高比确定矩形和正方形),5个点五边形,其他的结合膨胀腐蚀假设其为圆;

在这里插入图片描述

# python detect_shapes.py --image shapes_and_colors.png# 导入必要的包
import argparse
import imutils
import cv2class ShapeDetector:def __init__(self):pass# 轮廓形状识别器 只有一个参数 c:轮廓# 为了进行形状检测,我们将使用轮廓近似法。 顾名思义,轮廓近似(contour approximation)是一种算法,用于通过减少一组点来减少曲线中的点数,因此称为术语近似。# 轮廓近似是基于以下假设:一条曲线可以由一系列短线段近似。这将导致生成近似曲线,该曲线由原始曲线定义的点子集组成。# 轮廓近似实际上已经通过cv2.approxPolyDP在OpenCV中实现。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"# 如果是五边形(pentagon),将有5个顶点elif len(approx) == 5:shape = "pentagon"# 否则,根据上边的膨胀腐蚀,我们假设它为圆形else:shape = "circle"# 返回形状的名称return shape# 构建命令行参数
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,help="path to the input image")
args = vars(ap.parse_args())# 加载图片 保持宽高比并resize到一个比较小的大小,以使其有更好的轮廓近似结果
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)[1]# 在阈值图像上进行形状检测,并初始化形状检测器
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
# 兼容opencv版本获取正确的轮廓结果
cnts = imutils.grab_contours(cnts)
sd = ShapeDetector()# 注意图像是如何二值化的-形状在黑色背景上显示为白色前景。
# 循环遍历每个轮廓,对每个轮廓执行形状检测,然后在对象上绘制形状的名称。
for c in cnts:# 计算轮廓的中心,应用轮廓检测其形状M = cv2.moments(c)cX = int((M["m10"] / M["m00"]) * ratio)cY = int((M["m01"] / M["m00"]) * ratio)shape = sd.detect(c)# 还原原始的轮廓大小# 将轮廓* 缩放的ratio比例 并将其绘制在图像上,同时将形状的标签文本绘制在图像上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, (255, 255, 255), 2)# 展示输出图片cv2.imshow("Image", image)cv2.waitKey(0)

参考:
https://www.pyimagesearch.com/2016/02/08/opencv-shape-detection/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/17462.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

使用python,dlib,OpenCV提取眼睛,鼻子,嘴唇及下颌

使用python,dlib,OpenCV提取眼睛,鼻子,嘴唇及下颌 1. 效果图2. 原理3. 源码参考上一篇博客中,我们了解了什么是面部标志,以及如何使用dlib,OpenCV和Python检测它们。利用dlib的HOG SVM的形状预测器获得面部ROI中面部区域的68个点(x,y)坐标。 这一篇博客中,将演示如何…

Keras ImageDataGenerator用于数据扩充/增强的原理及方法

摘要 在这篇博客中,您将学习如何使用Keras的ImageDataGenerator类执行数据扩充/增强。另外将介绍什么是数据增强,数据增强的类型,为什么使用数据增强以及它能做什么/不能做什么。 有三种数据增强类型,默认情况下,Keras的ImageDataGenerator该类执行就地/即时数据扩充。 检…

使用Python,OpenCV构建透明的叠加层

为了构造透明的叠加层&#xff0c;需要准备两个图像&#xff1a;&#xff08;1&#xff09;原始图片&#xff1b;&#xff08;2&#xff09;要 “叠加”在第一个图像上的图像&#xff08;包含某种级别的Alpha透明度&#xff09;。 透明叠加层的用例几乎无穷无尽&#xff0c;其…

ListView style

步骤一&#xff1a;在使用的ListView的activiey里使用android&#xff1a;theme“style/Theme的名字” 步骤二&#xff1a;创建Themes.xml 在Themes.xml里定义的使用的样式。如&#xff1a; 步骤三&#xff1a;在themes.xml使用了styles.xml定义的listView的属性&#xff0c;创…

使用Python,OpenCV线程化方式提高视频FPS(每秒帧数)

使用Python,OpenCV处理视频流时,获得更高FPS(Frams Per Second)的“秘密”是将I / O(即从摄像机传感器读取帧)交给线程去处理; 读取帧 I/O是阻塞型的,定义主线程处理读到的帧,一个新的线程一直读取帧,等主线程处理完,将新读取到的帧接过来继续处理; I/O 密集型的用…

小D学blend-----如何创建自定义的Tooltip控件

运行环境&#xff1a;blend 4.0或者blend 3.0 silverlight 3.0&#xff08;其实我相信步骤应该是差不多的&#xff09; 语言&#xff1a;C# Tooltip类:它是表示一个长方形的小弹出窗口&#xff0c;该窗口在用户将指针悬停在一个控件上时显示有关该控件用途的简短说明。<p&g…

一步一步实现自己的模拟控件(9)——消息处理

这次我们将要给Widget增加一些状态&#xff0c;并使其能够接受出消息处理扩展&#xff0c;测试工程中实现了一个按钮的消息处理扩展。 Widget状态&#xff1a; 之前的控件只是绘制了一个边框&#xff0c;并且总是会在窗口中显示。实际上我们往往会希望能够让某个控件显示或者隐…

ES集群状态、节点、索引等查看及根据字段、排序查询

ES集群基础&#xff1a; 1. 查看集群&#xff1a; http://172.xxx.xxx.8:92002. 查看状态&#xff1a; http://172.xxx.xxx.8:9200/_cat/health?v3. 查看索引&#xff1a; http://172.xxx.xxx.8:9200/_cat/indices?v4. 查看节点&#xff1a; http://172.xxx.xxx.8:9200/…