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

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

3天内不再提示

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

jt_rfid5 来源:今日光电 作者:今日光电 2022-11-29 14:47 次阅读

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

使用相似三角形计算物体到相机的距离

假设物体的宽度为 W,将其放到离相机距离为 D 的位置,然后对物体进行拍照。在照片上量出物体的像素宽度 P,于是可以得出计算相机焦距 F 的公式:
b8e83df2-6f0c-11ed-8abf-dac502259ad0.svg

比如我在相机前 24 英寸距离(D=24 inches)的位置横着放了一张 8.5 x 11 英寸(W=11 inches)的纸,拍照后通过图像处理得出照片上纸的像素宽度 P=248 pixels。所以焦距 F 等于:

b8fb5fc2-6f0c-11ed-8abf-dac502259ad0.svg

此时移动相机离物体更近或者更远,我们可以应用相似三角形得到计算物体到相机的距离的公式:
b90c7cbc-6f0c-11ed-8abf-dac502259ad0.svg

原理大概就是这样,接下来使用 OpenCV 来实现。

获取目标轮廓

# import the necessary packages
from imutils import paths
import numpy as np
import imutils
import cv2
def find_marker(image):
    # convert the image to grayscale, blur it, and detect edges
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    edged = cv2.Canny(gray, 35, 125)
    # find the contours in the edged image and keep the largest one;
    # we'll assume that this is our piece of paper in the image
    cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    c = max(cnts, key = cv2.contourArea)
    # compute the bounding box of the of the paper region and return it
    return cv2.minAreaRect(c)

定义一个 find_marker 函数,接收一个参数 iamge,用来找到要计算距离的物体。这里我们用一张 8.5 x 11 英寸的纸作为目标物体。第一个任务是在图片中找到目标物体。

下面这三行是先将图片转换为灰度图,并进行轻微模糊处理以去除高频噪声,然后进行边缘检测

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
edged = cv2.Canny(gray, 35, 125)

做了这几步后图片看起来是这样的:

现在已经可以清晰地看到这张纸的边缘,接下来需要做的是找出这张纸的轮廓。

cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = max(cnts, key = cv2.contourArea)

用 cv2.findContours 函数找到图片中的众多轮廓,然后获取其中面积最大的轮廓,并假设这是目标物体的轮廓。

这种假设只适用于我们这个场景,在实际使用时,在图片中找出目标物体的方法与应用场景有很大关系。

我们这个场景用简单的边缘检测并找出最大的轮廓就可以了。当然为了使程序更具有鲁棒性,也可以用轮廓近似,并剔除不是四个点的轮廓(纸张是一个有四个点的矩形),然后再找出面积最大,具有四个点的轮廓。

注意: 关于这个方法,详情可以查看这篇文章,用于构建一个移动文本扫描工具。

我们也可以根据颜色特征在图片中找到目标物体,因为目标物体和背景的颜色有着很明显的不同。还可以应用关键点检测(keypoint detection),局部不变性描述子(local invariant descriptors)和关键点匹配(keypoint matching)来寻找目标。但是这些方法不在本文的讨论范围内,而且高度依赖具体场景。

我们现在得到目标物体的轮廓了,find_marker 函数最后返回的是包含轮廓 (x, y) 坐标、像素长度和像素宽度的边框,

计算距离

接下来该使用相似三角形计算目标到相机的距离。

def distance_to_camera(knownWidth, focalLength, perWidth):
    # compute and return the distance from the maker to the camera
    return (knownWidth * focalLength) / perWidth

distance_to_camera 函数传入目标的实际宽度,计算得到的焦距和图片上目标的像素宽度,就可以通过相似三角形公式计算目标到相机的距离了。

下面是调用 distance_to_camera 函数之前的准备:

# initialize the known distance from the camera to the object, which
# in this case is 24 inches
KNOWN_DISTANCE = 24.0


# initialize the known object width, which in this case, the piece of
# paper is 12 inches wide
KNOWN_WIDTH = 11.0


# load the furst image that contains an object that is KNOWN TO BE 2 feet
# from our camera, then find the paper marker in the image, and initialize
# the focal length
image = cv2.imread("images/2ft.jpg")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

首先是测量目标物体的宽度,和目标物体到相机的距离,并根据上面介绍的方法计算相机的焦距。其实这些并不是真正的摄像机标定。真正的摄像机标定包括摄像机的内参,相关知识可以可以查看这里。

使用 cv2.imread 函数从磁盘加载图片,然后通过 find_marker 函数得到图片中目标物体的坐标和长宽信息,最后根据相似三角形计算出相机的焦距。

现在有了相机的焦距,就可以计算目标物体到相机的距离了。

# loop over the images
for imagePath in sorted(paths.list_images("images")):
    # load the image, find the marker in the image, then compute the
    # distance to the marker from the camera
    image = cv2.imread(imagePath)
    marker = find_marker(image)
    inches = distance_to_camera(KNOWN_WIDTH, focalLength, marker[1][0])


    # draw a bounding box around the image and display it
    box = cv2.cv.BoxPoints(marker) if imutils.is_cv2() else cv2.boxPoints(marker)
    box = np.int0(box)
    cv2.drawContours(image, [box], -1, (0, 255, 0), 2)
    cv2.putText(image, "%.2fft" % (inches / 12),
        (image.shape[1] - 200, image.shape[0] - 20), cv2.FONT_HERSHEY_SIMPLEX,
        2.0, (0, 255, 0), 3)
    cv2.imshow("image", image)
    cv2.waitKey(0)

使用 for 循环遍历每个图片,计算每张图片中目标对象到相机的距离。在结果中,我们根据得到的轮廓信息将方框画了出来,并显示出了距离。

总结

通过这篇文章,我们学会了使用相似三角形计算图片中一个已知物体到相机的距离。

需要先测量出目标物体的实际宽度和目标物体到相机的距离,然后使用图像处理的方法自动计算图片中目标物体的像素宽度,并使用相似三角形计算出相机的焦距。

根据相机的焦距就可以计算图片中的目标物体到相机的距离。

审核编辑:郭婷

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

    关注

    59

    文章

    4810

    浏览量

    95442
  • 相机
    +关注

    关注

    4

    文章

    1344

    浏览量

    53508

原文标题:【光电智造】使用OpenCV实现摄像头测距

文章出处:【微信号:今日光电,微信公众号:今日光电】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    如何用OpenCV相机捕捉视频进行人脸检测--基于米尔NXP i.MX93开发板

    提供了一个非常简单的接口,用于相机捕捉一个视频(我用的电脑内置摄像头) 1、安装python3-opencv apt install python3-opencv 2、查看摄像头支持的格式与分辨率
    发表于 11-15 17:58

    基于OPENCV相机捕捉视频进行人脸检测--米尔NXP i.MX93开发板

    本文将介绍基于米尔电子MYD-LMX93开发板(米尔基于NXPi.MX93开发板)的基于OpenCV的人脸检测方案测试。OpenCV提供了一个非常简单的接口,用于相机捕捉一个视频(我用的电脑内置
    的头像 发表于 11-07 09:03 980次阅读
    基于<b class='flag-5'>OPENCV</b>的<b class='flag-5'>相机</b>捕捉视频进行人脸检测--米尔NXP i.MX93开发板

    目标检测中大物体的重要性

    导读实验表明,对大型物体赋予更大的权重可以提高所有尺寸物体的检测分数,从而整体提升目标检测器的性能(在COCOval2017数据集上使用InternImage-T模型,小物体检测精度提
    的头像 发表于 10-09 08:05 415次阅读
    在<b class='flag-5'>目标</b>检测中大<b class='flag-5'>物体</b>的重要性

    红外光电远距离传感器TYPE:E3K-M5DDK-S原理采用什么方式

    红外光电远距离传感器通过发射红外光束并接收其反射信号来测量目标物体距离,其原理基于红外线的物体
    的头像 发表于 09-25 14:36 172次阅读

    什么是高光谱相机?高光谱相机有什么用?

    进行成像,从而获得目标物体丰富的光谱特征。 高光谱相机通常由光学系统、探测器、信号处理单元等部分组成。光学系统负责收集目标物体反射或发射的光
    的头像 发表于 09-06 15:39 339次阅读
    什么是高光谱<b class='flag-5'>相机</b>?高光谱<b class='flag-5'>相机</b>有什么用?

    opencv的主要功能有哪些

    OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,提供了大量的计算机视觉算法和工具。以下是OpenCV的主要功能: 图像处理
    的头像 发表于 07-16 10:35 1334次阅读

    测量物体表面的静电值的方法

    金属板方便随时随地进行离子平衡的测量。FMX-004 静电场测量仪的测量标准为距离物件表面25mm(±0.5mm)处所检测数据 (即2个红色LED 灯照射在
    的头像 发表于 07-03 15:53 681次阅读

    OpenCV携奥比中光3D相机亮相CVPR 2024

    6月17日-21日,奥比中光合作伙伴OpenCV携Orbbec 3D相机参展在美国西雅图举办的CVPR 2024(即IEEE国际计算机视觉与模式识别会议),让开发者亲身体验Orbbec 3D相机
    的头像 发表于 06-21 09:38 505次阅读

    开发者手机 AI - 目标识别 demo

    应用的demo。 应用程序通过相机进行预览,对预览画面中的物体进行目标识别,目前该应用程序支持识别100种物体。 系统架构 下图为demo应用以及Openharmony AI子系统的架
    发表于 04-11 16:14

    如何使用Rd-03E雷达实现实时监测目标距离呢?

    Rd-03E基于STM32F103C8T6平台以UART为抓手实现监测目标距离可视化,通过GPIO赋能LED、Buzzer进一步强化视觉、听觉感知。
    的头像 发表于 03-25 14:44 611次阅读
    如何使用Rd-03E雷达<b class='flag-5'>实现</b>实时监测<b class='flag-5'>目标</b><b class='flag-5'>距离</b>呢?

    工业镜头中常见的参数之工作距离、物距、法兰距及镜头接口

    工业镜头中常用的一些关于距离的参数,别再傻傻分不清了。工作距离(WD)是指镜头最下端机械面物体距离。物像
    的头像 发表于 03-11 15:29 4753次阅读
    工业镜头中常见的参数之工作<b class='flag-5'>距离</b>、物距、法兰距及镜头接口

    使用V851se视觉开发板制作超低成本的小相机

    这个超低成本的小相机是在V851se上移植使用全志在线开源版本的Tina Linux与OpenCV框架开启摄像头拍照捕获视频,并结合NPU实现Mobilenet v2目标分类识别以及运
    的头像 发表于 02-25 10:05 1193次阅读
    使用V851se视觉开发板制作超低成本的小<b class='flag-5'>相机</b>

    AD CAM文件如何测量距离

    如何测量距离距离的定义和重要性 在AD CAM文件中,距离是指广告目标受众与广告内容之间的距离
    的头像 发表于 01-08 10:16 1348次阅读

    OpenCV零代码实现线段距离测量

    OpenMV2024版本即将发行,支持多种主流深度学习模型从训练到部署,支持更多传统OpenCV算子流程设计与组合,支持一键导出流程,相比2023版本OpenMV,提供更多辅助开发工具。
    的头像 发表于 01-08 09:15 549次阅读
    <b class='flag-5'>OpenCV</b>零代码<b class='flag-5'>实现</b>线段<b class='flag-5'>距离</b><b class='flag-5'>测量</b>

    线阵相机与面阵相机的区别

    工业相机是机器视觉系统必不可少的核心组件,根据不同的类别有不同的分类标准。按传感器的结构特性分类,可分为面阵相机与线阵相机两种。其中,面阵相机是以面为单位来进行图像采集,可以一次性获取
    的头像 发表于 12-14 16:55 1140次阅读
    线阵<b class='flag-5'>相机</b>与面阵<b class='flag-5'>相机</b>的区别