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

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

3天内不再提示

如何使用OpenCV测量图像中物体间距离

新机器视觉 来源:光头哥哥的博客 2023-03-23 11:42 次阅读

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

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

386aa49c-c8aa-11ed-bfe3-dac502259ad0.jpg

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

定义参考对象并计算距离

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

# import the necessary packages
from scipy.spatial import distance as dist
from imutils import perspective
from imutils import contours
import numpy as np
import argparse
import imutils
import cv2
def midpoint(ptA, ptB):
return ((ptA[0] + ptB[0]) * 0.5, (ptA[1] + ptB[1]) * 0.5)
# construct the argument parse and parse the arguments
ap = 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 slightly
image = 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 edges
edged = cv2.Canny(gray, 50, 100)
edged = cv2.dilate(edged, None, iterations=1)
edged = cv2.erode(edged, None, iterations=1)
# find contours in the edge map
cnts = 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 individually
for c in cnts:
  # if the contour is not sufficiently large, ignore it
if cv2.contourArea(c) < 100:
continue
  # compute the rotated bounding box of the contour
box = 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
  # box
box = perspective.order_points(box)
  # compute the center of the bounding box
cX = 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 object
if 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 object
    D = 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 image
orig = 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 center
  refCoords = 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 line
    cv2.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
# units
    D = 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 image
    cv2.imshow("Image", orig)
    cv2.waitKey(0)

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

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

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

距离测量结果

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

37fca960-c8aa-11ed-bfe3-dac502259ad0.gif

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

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

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

38fe3194-c8aa-11ed-bfe3-dac502259ad0.gif

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

最后一个例子计算了我们的参考对象(一张3.5英寸x 2英寸的名片)和一组7英寸的黑胶唱片和信封之间的距离:

3964b2ca-c8aa-11ed-bfe3-dac502259ad0.gif

编辑:黄飞

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

    关注

    29

    文章

    611

    浏览量

    40795

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

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

收藏 人收藏

    评论

    相关推荐

    使用Python和OpenCV查找从相机到物体/标记的距离

    摄像头测距就是计算照片中的目标物体到相机的距离。可以使用相似三角形(triangle similarity)方法实现,或者使用更复杂但更准确的相机模型的内参来实现这个功能。 使用相似三角形计算物体
    的头像 发表于 11-29 17:44 1741次阅读

    使用Labview vision来搜索图像物体

    ` 本帖最后由 1453544229 于 2015-8-19 15:39 编辑 效果如下图:上图为整个图像,可选择图像的部分区域,并搜索图像
    发表于 08-19 15:39

    【芯灵思A83T试用申请】嵌入式视觉--远距离物体跟踪与定位

    OpenCV环境,连接工业相机3)物体跟踪与定位算法的实现4)结项与项目演示具体描述:本方案拟以嵌入式开发为基础,基于CMOS相机和数字图像处理技术的远距离目标定位技术,研究
    发表于 04-27 14:18

    CCD图像测量系统的组成

    信号,然后进一步通过AGC自动增益控制来补偿照明条件的起伏。用做测量图像信号经二值化处理后进入像素检测器,在这里通过像素计数确定二值化图形脉冲的间距值,并在乘以脉冲当量数值后得到实测的物体
    发表于 11-15 15:06

    AD软件中点对点的测量距离 边缘与边缘间距测量方法介绍

    AD软件中点对点的测量距离 边缘与边缘间距测量方法介绍Altium提供了两种方式进行测量,一种是点对点的
    发表于 03-22 21:47

    如何使用PythonOpenCV模块检测颜色

    numpy然后,导入模块。读取图像并使用 OpenCV 模块的 cvtColor() 函数将BGR图像转换为 HSV (色调、饱和度、值) 图像
    发表于 02-09 16:31

    PCB技术的距离测量介绍

    距离测量大体分两种:一种是点到点距离测量,另一种是边到边距离测量(边缘
    的头像 发表于 10-15 10:14 3463次阅读

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

    计算物体之间的距离与计算图像物体的大小算法思路非常相似——都是从参考对象开始的。我们将使用0.25美分作为我们的参考对象,它的宽度为0.955英寸。
    的头像 发表于 03-12 11:39 3539次阅读

    关于一种新的远距离测量高温物体的方案

    需要新的高温物体远距测量方式 在钢铁、冶金、矿山等工业行业中,高温物体的检测是一项重要的检测项目,如高温物体的尺寸、轮廓、位移等。因为受高温工作环境约束,一般会选择远
    发表于 06-23 15:31 491次阅读

    高温物体距离测量方案不受物体表面红光影响

    需要新的高温物体远距测量方式 在钢铁、冶金、矿山等工业行业中,高温物体的检测是一项重要的检测项目,如高温物体的尺寸、轮廓、位移等。因为受高温工作环境约束,一般会选择远
    发表于 07-16 16:07 923次阅读

    高温物体距离测量方案的简介

    需要新的高温物体远距测量方式 在钢铁、冶金、矿山等工业行业中,高温物体的检测是一项重要的检测项目,如高温物体的尺寸、轮廓、位移等。因为受高温工作环境约束,一般会选择远
    发表于 07-21 15:33 1168次阅读

    使用OpenCV实现目标物体到相机的距离测量

    假设物体的宽度为 W,将其放到离相机距离为 D 的位置,然后对物体进行拍照。在照片上量出物体的像素宽度 P,于是可以得出计算相机焦距 F 的公式:
    的头像 发表于 11-29 14:47 1650次阅读

    用于距离测量物体检测的飞行时间系统

    。时间延迟与相机与物体间距离的两倍(往返)成正比。因此,距离可以估计为深度 d = (c × Δt)/2,其中 c 是光速。因此,ToF相机输出2D数据以及所需的深度信息。
    的头像 发表于 12-09 15:41 740次阅读
    用于<b class='flag-5'>距离</b><b class='flag-5'>测量</b>和<b class='flag-5'>物体</b>检测的飞行时间系统

    用于距离测量物体检测的飞行时间系统

    现有的像素尺寸可实现高芯片分辨率,不仅可以进行距离测量,还可以实现物体和手势识别。要测量距离范围从几厘米(
    的头像 发表于 12-16 14:46 460次阅读

    使用超声波测距仪测量物体距离

    电子发烧友网站提供《使用超声波测距仪测量物体距离.zip》资料免费下载
    发表于 12-29 14:42 1次下载
    使用超声波测距仪<b class='flag-5'>测量</b>到<b class='flag-5'>物体</b>的<b class='flag-5'>距离</b>