【计算机视觉OpenCV基础】实验四 尺寸测量

您所在的位置:网站首页 opencv识别物体尺寸 【计算机视觉OpenCV基础】实验四 尺寸测量

【计算机视觉OpenCV基础】实验四 尺寸测量

2023-09-25 08:24| 来源: 网络整理| 查看: 265

实验四 尺寸测量

文章目录 OpenCV实验附录:列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包

OpenCV实验

计算机视觉OpenCV基础实验合辑(实验1234+扩展) 资源下载地址: https://download.csdn.net/download/weixin_53403301 合辑:(加在下载地址后面) /87113581 讲义(包括理论、图例、PPT、实验、代码、手册):(加在下载地址后面) /87113633

matplotlib中载入中文字体

plt.rcParams['font.sans-serif'] = ['SimHei'] # 载入字体

实验目的: 1、 通过已知尺寸的首目标来对比测量其他目标尺寸。 2、 标记所有目标尺寸。 实验内容: 1、首目标处理 图像目标尺寸检测类似于计算从我们的相机到一个物体的距离——在这两种情况下,我们都需要事先定义一个比率来测量每个给定度量单位的像素数(pixels_per_metric)。在这里所说的这个被称为“pixels_per_metric”的比率指标,我在接下来的部分中对其更正式的定义。

为了确定图像中物体的大小,我们首先需要使用一个参照物作为“校准”点。我们的参照物应该有两个重要的属性:

1、我们应该知道这个物体的真实尺寸(在宽度或高度上的毫米或英寸等值的大小)。

2、我们应该能够轻松地在图片中找到这个参照物,要么基于参照物的位置(如,参照物可以是一副图像中左上角的物体)或基于参照物的外表(例如参照物可以是图片中具有最独特的颜色或独一无二的形状,不同于所有其他的物体)。一句话而言:在任何一种情况下,我们的参照物都应该是以某种方式进行唯一可识别的The One。

在图中,我们将使用美分硬币作为我们的参照物,其选择方式为选择图像中最左侧的物体作为参照物。

我们将使用一个美分硬币作为我们的参照物,并确保它总是被放置在图像中最左边,这使得我们可以通过对它们位置的轮廓大小进行排序,进一步来提取信息。

通过保证这个美分硬币是最左边的物体后,我们可以从左到右对我们的物体等高线区域进行排列,抓住这个硬币(它将始终对应于排序列表中的第一个等高线区域),并使用它来定义我们的pixels_per_metric比率,我们将其定义为:

pixels_per_metric = 物体像素宽 / 物体真实宽

美分硬币的真实宽度是0.955英寸。现在,假设我们图像中硬币的像素宽为150像素(基于它的相关边界框)。那么这种情况下pixels_per_metric这样计算:

pixels_per_metric = 150px / 0.955in = 157px

因此,在我们这幅图像中,每英寸大约有157个像素。有了这个比率,我们可以计算图像中其他物体的大小了。

1、测量物体大小 既然我们已经理解了pixels_per_metric,我们就可以实现用于测量图像中对象大小的Python程序脚本了。

打开一个新的py文件,插入以下代码:

# -*- coding: utf-8 -*- """ Created on Sat May 8 14:19:04 2021 ​ @author: ZHOU """ ​ # 导入库 from scipy.spatial import distance as dist # from imutils import perspective # from imutils import contours import contours import perspective import numpy as np # import argparse import imutils import cv2 ​ import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # 载入字体 ​ ​ # card=input('输入图像路径和文件名:') ​ def midpoint(ptA, ptB): return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5) def pshow(words,picture): plt.imshow(picture[:,:,::-1]) plt.title(words), plt.xticks([]), plt.yticks([]) plt.show()

定义了一个midpoint函数,顾名思义,它用于计算两个(x,y)坐标之间的中点。

然后我们在第14-19行中解析我们的命令行参数。我们需要两个参数,–image,它是我们输入图像的路径,其中包含我们想要测量的对象,–width,也就是我们的参照物的宽度(英寸),–image路径图像中所认定的那个最左边的物体。

我们现在可以加载我们的图像并对其进行预处理:

# 图像导入,预处理 #image = cv2.imread(card) image = cv2.imread('exp02.png') ​ pshow('原图',image) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (7, 7), 0) ​ # 执行边缘检测,然后执行膨胀+腐蚀 # 闭合对象边之间的间隙 edged = cv2.Canny(gray, 50, 100) edged = cv2.dilate(edged, None, iterations=1) edged = cv2.erode(edged, None, iterations=1) ​ # 在边缘图中查找等高线 #编译器所装cv版本为4.4.0版本,不同版本cv2.findContours语句输出的值的数量、顺序不一样,根据不同版本需进行调整 ​ #cv版本4 cnts,a = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ​ #cv版本3 # a,cnts,b = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ​ #cv版本2 # a,cnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) ​ # cnts = cnts[0] if imutils.is_cv2() else cnts[1] ​ # 从左到右排列轮廓并初始化 #“每公制像素”校准变量 (cnts, _) = contours.sort_contours(cnts) pixelsPerMetric = None

从磁盘加载我们的图像,将其转换为灰度,然后使用高斯过滤器平滑它。然后我们执行边缘检测和扩张+磨平,以消除边缘图中边缘之间的任何间隙。

找到等高线,也就是我们边缘图中物体相对应的轮廓线。

然后,这些等高线区域从左到右(使得我们可以提取到参照物)在第39行中进行排列。然后我们在第40行时,对pixelsPerMetric值进行初始化。

下一步是对每一个等高线区域值大小进行检查校验。

# 分别在轮廓上循环 for c in cnts: print(cv2.contourArea(c)) # 如果轮廓不够大,请忽略它 if cv2.contourArea(c)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3