0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简述我们该如何使用OpenCV测量图像中物体之间的距离

新机器视觉 来源: OpenCV视觉实践 作者: OpenCV视觉实践 2021-03-12 11:39 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

计算物体之间的距离与计算图像中物体的大小算法思路非常相似——都是从参考对象开始的。我们将使用0.25美分作为我们的参考对象,它的宽度为0.955英寸。

并且我们还将0.25美分总是放在图片最左侧使其容易识别。这样它就满足了我们上面提到的参考对象的两个特征。

我们的目标是找到0.25美分,然后利用0.25美分的尺寸来测量0.25美分硬币与所有其他物体之间的距离。

定义参考对象并计算距离

打开一个新文件,将其命名为distance_between.py,插入以下代码:

# import the necessary packagesfrom scipy.spatial import distance as distfrom imutils import perspectivefrom imutils import contoursimport numpy as npimport argparseimport imutilsimport cv2def midpoint(ptA, ptB):return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)# construct the argument parse and parse the argumentsap = argparse.ArgumentParser()ap.add_argument("-i", "--image", required=True,help="path to the input image")ap.add_argument("-w", "--width", type=float, required=True,help="width of the left-most object in the image (in inches)")args = vars(ap.parse_args())

我们这里的代码与上周的代码几乎相同。我们从在第2-8行上导入所需的Python包开始。第12-17行解析命令行参数。这里我们需要两个参数:——image,它是包含我们想要测量的对象的输入图像的路径,以及——width,为我们参考对象的宽度(单位为英寸)。

接下来,我们需要对图像进行预处理:

# load the image, convert it to grayscale, and blur it slightlyimage = cv2.imread(args["image"])gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)gray = cv2.GaussianBlur(gray, (7, 7), 0)# perform edge detection, then perform a dilation + erosion to# close gaps in between object edgesedged = cv2.Canny(gray, 50, 100)edged = cv2.dilate(edged, None, iterations=1)edged = cv2.erode(edged, None, iterations=1)# find contours in the edge mapcnts = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)# sort the contours from left-to-right and, then initialize the# distance colors and reference object(cnts, _) = contours.sort_contours(cnts)colors = ((0, 0, 255), (240, 0, 159), (0, 165, 255), (255, 255, 0),(255, 0, 255))refObj = None

第2-4行从磁盘加载图像,将其转换为灰度图,然后使用7 x 7内核的高斯滤波器对其进行模糊降噪。

当我们的图像被模糊后,我们应用Canny边缘检测器来检测图像中的边缘,然后进行膨胀+腐蚀来缩小边缘图中的缝隙(第7-9行)。

调用cv2.findContours检测边缘图中对象的轮廓(第11-13行),而第16行从左到右对轮廓进行排序。由于我们知道0.25美分(即参考对象)将始终是图像中最左边,因此从左到右对轮廓进行排序可以确保与参考对象对应的轮廓始终是cnts列表中的第一个。

然后,我们初始化用于绘制距离的colors列表以及refObj变量,该变量将存储参考对象的边界框、质心和pixels-per-metric值(看上一篇就明白pixels-per-metric的具体定义,其实就是参考对象的实际大小(单位英寸)与图片中的宽度(单位为像素)的比值)。

# loop over the contours individuallyfor c in cnts:# if the contour is not sufficiently large, ignore itif cv2.contourArea(c) < 100:continue# compute the rotated bounding box of the contourbox = cv2.minAreaRect(c)box = cv2.cv.BoxPoints(box) if imutils.is_cv2() else cv2.boxPoints(box)box = np.array(box, dtype="int")# order the points in the contour such that they appear# in top-left, top-right, bottom-right, and bottom-left# order, then draw the outline of the rotated bounding# boxbox = perspective.order_points(box)# compute the center of the bounding boxcX = np.average(box[:, 0])cY = np.average(box[:, 1])

在第2行,我们开始对cnts列表中的每个轮廓进行循环。如果轮廓比较小(第4和5行),我们认为是噪声并忽略它。

然后,第7-9行计算当前对象的最小旋转包围框。

第14行上调用order_points函数(此系列第一篇定义的函数)来对矩形框四个顶点以左上角、右上角、右下角和左下角的顺序排列,我们将看到,在计算物体之间的距离时,这一点非常重要。

第16行和第17行通过取边界框在x和y方向上的平均值来计算旋转后的边界框的中心(x, y)坐标。

下一步是校准我们的refObj:

# if this is the first contour we are examining (i.e.,# the left-most contour), we presume this is the# reference objectif refObj is None:# unpack the ordered bounding box, then compute the# midpoint between the top-left and top-right points,# followed by the midpoint between the top-right and# bottom-right(tl, tr, br, bl) = box(tlblX, tlblY) = midpoint(tl, bl)(trbrX, trbrY) = midpoint(tr, br)# compute the Euclidean distance between the midpoints,# then construct the reference objectD = dist.euclidean((tlblX, tlblY), (trbrX, trbrY))refObj = (box, (cX, cY), D / args["width"])continue

如果refObj为None(第4行),则需要对其进行初始化。

我们首先获取(排序后的)最小旋转边界框坐标,并分别计算四个顶点之间的中点(第10-15行)。

然后计算中点之间的欧氏距离,给出我们的“像素/尺寸”比例,来确定一英寸为多少像素宽度。

最后,我们将refObj实例化为一个3元组,包括:

  • 物体对象的最小旋转矩形对象box

  • 参考对象的质心。

  • 像素/宽度比例,我们将用其来结合物体之间的像素距离来确定物体之间的实际距离。

下一个代码块负责绘制参考对象和当前检查对象的轮廓,然后定义变量refCoords和objCoords,这样(1)最小包围矩阵坐标和(2)质心的(x, y)坐标都包含在同一个数组中:

# draw the contours on the imageorig = image.copy()cv2.drawContours(orig, [box.astype("int")], -1, (0, 255, 0), 2)cv2.drawContours(orig, [refObj[0].astype("int")], -1, (0, 255, 0), 2)# stack the reference coordinates and the object coordinates# to include the object centerrefCoords = np.vstack([refObj[0], refObj[1]])objCoords = np.vstack([box, (cX, cY)])

现在我们可以开始计算图像中各个物体的质心和质心之间的距离了:
# loop over the original points

for ((xA, yA), (xB, yB), color) in zip(refCoords, objCoords, colors):# draw circles corresponding to the current points and# connect them with a linecv2.circle(orig, (int(xA), int(yA)), 5, color, -1)cv2.circle(orig, (int(xB), int(yB)), 5, color, -1)cv2.line(orig, (int(xA), int(yA)), (int(xB), int(yB)),color, 2)# compute the Euclidean distance between the coordinates,# and then convert the distance in pixels to distance in# unitsD = dist.euclidean((xA, yA), (xB, yB)) / refObj[2](mX, mY) = midpoint((xA, yA), (xB, yB))cv2.putText(orig, "{:.1f}in".format(D), (int(mX), int(mY - 10)),cv2.FONT_HERSHEY_SIMPLEX, 0.55, color, 2)# show the output imagecv2.imshow("Image", orig)cv2.waitKey(0)

在第2行,我们开始对图片中物体对象的顶点(x, y)坐标进行循环。

然后我们画一个圆表示我们正在计算距离的当前点坐标,并画一条线连接这些点(第5-7条线)。

然后,第12行计算参考位置和对象位置之间的欧式距离,然后除以“像素/度量”,得到两个对象之间的实际距离(以英寸为单位)。然后在图像上标识出计算的距离(第13-15行)。

距离测量结果

下面是一个GIF动画,演示了我们的程序运行效果:

在每种情况下,我们的脚本都匹配左上(红色)、右上(紫色)、右下(橙色)、左下(蓝绿色)和质心(粉色)坐标,然后计算参考对象和当前对象之间的距离(以英寸为单位)。

注意图像中的两个0.25美分完全平行,这意味着所有五个顶点之间的距离均为6.1英寸。

下面是第二个例子,这次计算的是参考对象和药丸之间的距离:

这个例子可以作为药片分类机器人的输入,自动获取一组药片,并根据它们的大小和与药片容器的距离来组织它们。

编辑:jq


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • OpenCV
    +关注

    关注

    33

    文章

    651

    浏览量

    44420

原文标题:使用OpenCV测量图像中物体之间的距离

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    工业镜头测量的“工作距离”是什么?

    工业镜头作为机器视觉系统的核心组件,在自动化生产、质量检测和精密测量等领域发挥着关键作用。其中,“工作距离”(WorkingDistance,简称WD)是一个至关重要的参数,它直接影响系统
    的头像 发表于 12-06 16:46 23次阅读
    工业镜头<b class='flag-5'>测量</b><b class='flag-5'>中</b>的“工作<b class='flag-5'>距离</b>”是什么?

    【上海晶珩睿莓1开发板试用体验】TensorFlow-Lite物体归类(classify)

    用。 OpenCV库编译成功之后,就可以新建一个线程进行TensorFlow-Lite物体归类了,这里我直接使用现成的pb和pbtxt文件,具体内容不赘述,来看看识别效果:
    发表于 09-12 22:43

    零成本钢铁侠手套!树莓派+OpenCV 秒变手势遥控器!

    使用树莓派和OpenCV实时扫描并存储二维码使用树莓派和OpenCV实现物体与动物识别使用树莓派、摄像头和OpenCV进行速度检测用树莓派+Open
    的头像 发表于 08-16 16:16 886次阅读
    零成本钢铁侠手套!树莓派+<b class='flag-5'>OpenCV</b> 秒变手势遥控器!

    如何使用树莓派与OpenCV实现面部和运动追踪的云台系统?

    使用树莓派和OpenCV实时扫描并存储二维码使用树莓派和OpenCV实现物体与动物识别使用树莓派、摄像头和OpenCV进行速度检测用树莓派+Open
    的头像 发表于 08-14 17:45 961次阅读
    如何使用树莓派与<b class='flag-5'>OpenCV</b>实现面部和运动追踪的云台系统?

    【VisionFive 2单板计算机试用体验】人脸及物体识别、图像边缘检测

    个通用的USB摄像机,即可高效实现基于OpenCV的人脸检测识别、通用物体识别、二维码检测与解析,图像边缘检测等功能,证实开发板可以运用在AI智能终端产品设计上,赛昉科技也提供了诸多
    发表于 08-07 00:49

    超声波测距换能器:工业与生活测量利器

    在科技飞速发展的今天,各类传感器在各个领域发挥着至关重要的作用。其中,超声波测距换能器凭借其独特的优势,成为了距离测量领域的明星产品。无论是工业生产中的精密检测,还是日常生活的智能应用,超声波测距
    发表于 07-02 16:20

    为何激光三维扫描无需喷粉也能精准测量高反光物体?—— 基于光学抗反射技术的突破

    喷粉也能实现高反光物体的精准测量,为领域带来新突破。 传统高反光物体测量的困境与技术瓶颈 传统激光三维扫描基于三角测距原理,高反光
    的头像 发表于 06-27 09:58 377次阅读
    为何激光三维扫描无需喷粉也能精准<b class='flag-5'>测量</b>高反光<b class='flag-5'>物体</b>?—— 基于光学抗反射技术的突破

    itop-3568开发板机器视觉opencv开发手册-图像绘制-画线

    demo11_line.py 然后向该文件添加以下内容: 第 1 行和第 2 行分别导入了 opencv 和 numpy 库; 第 3 行使用 zeros()函数创建一个 512x512 的黑色图片; 第 4 行使
    发表于 06-04 10:38

    基于LockAI视觉识别模块:C++使用图像的统计信息

    图像处理,统计信息可以帮助我们了解图像的特性,例如区域内的像素分布、颜色转换以及特定区域的分析。本文将介绍基于LockAI视觉识别模块如何提取兴趣区域(ROI)、转换颜色通道、计算
    发表于 05-08 10:31

    基于LockAI视觉识别模块:C++图像的基本运算

    图像处理,理解图像的基本操作是掌握计算机视觉技术的关键。本文章将介绍 基于LockAI视觉识别模块下OpenCV
    发表于 05-06 16:56

    电机、变频器之间距离多少为宜?·

    分析与实际应用两个角度,深入探讨电机与变频器之间距离多少为宜的问题。 一、距离分类与影响 首先,我们需要明确电机与变频器之间距离的界定。一般而言,根据
    的头像 发表于 04-17 16:44 1426次阅读
    电机、变频器<b class='flag-5'>之间</b>的<b class='flag-5'>距离</b>多少为宜?·

    图像尺寸测量优势:数量识别

    普密斯图像尺寸测量仪运用了先进的光学成像与图像处理技术,这一技术是其实现高效精准测量的核心。当面对多个电子产品同时测量时,
    的头像 发表于 01-17 15:13 767次阅读
    <b class='flag-5'>图像</b>尺寸<b class='flag-5'>测量</b>优势:数量识别

    AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV

    视觉领域最有力的研究工具。在深度学习我们会经常接触到两个名称,图像处理和计算机视觉,它们之间有什么区别呢? 图像处理 (Image Pr
    发表于 12-14 09:31

    AI模型部署边缘设备的奇妙之旅:如何在边缘端部署OpenCV

    力的研究工具。在深度学习我们会经常接触到两个名称,图像处理和计算机视觉,它们之间有什么区别呢?图像处理(ImageProcessing)
    的头像 发表于 12-14 09:10 1264次阅读
    AI模型部署边缘设备的奇妙之旅:如何在边缘端部署<b class='flag-5'>OpenCV</b>

    如何远距离的传输camera图像呢?

    如何远距离的传输camera图像呢?camera可以是lvds,mipi等接口。
    发表于 12-12 07:32