首页 > 其他分享 >使用OpenCV实现摄像头测距

使用OpenCV实现摄像头测距

时间:2024-07-17 14:26:07浏览次数:12  
标签:image cv2 目标 相机 OpenCV 摄像头 marker 物体 测距

使用OpenCV实现摄像头测距

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

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

假设物体的宽度为 W,将其放到离相机距离为 D 的位置,然后对物体进行拍照。在照片上量出物体的像素宽度 P,于是可以得出计算相机焦距 F 的公式:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此时移动相机离物体更近或者更远,我们可以应用相似三角形得到计算物体到相机的距离的公式:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

附赠自动驾驶最全的学习资料和量产经验:链接

获取目标轮廓

# import the necessary packagesfrom imutils import pathsimport numpy as npimport imutilsimport cv2def 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)

这里我们用一张 8.5 x 11 英寸的纸作为目标物体。第一个任务是在图片中找到目标物体。

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

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

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

image

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

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 inchesKNOWN_DISTANCE = 24.0# initialize the known object width, which in this case, the piece of# paper is 12 inches wideKNOWN_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 lengthimage = cv2.imread("images/2ft.jpg")marker = find_marker(image)focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

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

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

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

# loop over the imagesfor 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 循环遍历每个图片,计算每张图片中目标对象到相机的距离。在结果中,我们根据得到的轮廓信息将方框画了出来,并显示出了距离。下面是得到的几个结果图:

image

image

总结

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

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

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

标签:image,cv2,目标,相机,OpenCV,摄像头,marker,物体,测距
From: https://blog.csdn.net/NEON7788/article/details/140494238

相关文章

  • Python学习笔记—100页Opencv详细讲解教程
    目录1创建和显示窗口...-4-2加载显示图片...-6-3保存图片...-7-4视频采集...-8-5视频录制...-11-6控制鼠标...-12-7TrackBar控件...-14-8.RGB和BGR颜色空间...-16-9.HSV和HSL和YUV..-17-10颜色空间的转化...-18-11mat的深......
  • 让摄像头带上智慧“智驭视界·AIEye”
     接上一篇《物联网浏览器(IoTBrowser)-基于计算机视觉开发的应用“智慧眼AIEye”》,经过AI的包装很高级,确实很屌炸天。   智驭视界·AIEye在科技赋能的浪潮中,智驭视界(AIEye) 横空出世,它不仅仅是一款视觉监测工具,更是直播、视频、图片世界中的智慧之眼,深度融合Yolov5尖......
  • OpenCV开发笔记(七十八):在ubuntu上搭建opencv+python开发环境以及匹配识别Demo
    若该文为原创文章,转载请注明原文出处本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140435870长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中…OpenCV开发专栏......
  • 树莓派4b最新系统下CSI摄像头使用
     最新的64位系统下opencv的capture不支持libcamera 直接调用capturevideo运行代码会出现如下报错:    WARN:[email protected]]global./modules/videoio/src/cap_gstreamer.cpp(2401)handleMessageOpenCV|GStreamerwarning:Embeddedvideoplaybackhalted;modulev4......
  • 网课没有摄像头,手机如何变成电脑摄像头?
    电脑虚拟摄像头是一种可以在电脑上模拟网络摄像头功能的软件,它可以使用多种视频来源作为视频内容,如录制好的视频、图片等。虚拟摄像头有很多,包括常见的金舟虚拟摄像头、OBSStudio、ManyCam、Webcamoid等。​(一)电脑虚拟摄像头分享金舟虚拟摄像头是一款Windows虚拟摄像头软件......
  • Turtlebot3在ROS Gazebo中使用OpenCV检测并跟踪球体
    原文链接:https://www.youtube.com/watch?v=Rw6ATkORRG8   一个小巧的机器人在虚拟世界中敏捷地追踪着一个滚动的球体。Turtlebot3,一个搭载ROS操作系统的智能机器人,在Gazebo仿真环境中,利用OpenCV的神奇力量,展现出令人惊叹的视觉追踪能力。 Turtlebot3的"眼睛"是一台高清......
  • opencv—常用函数学习_“干货“_7
    目录十九、模板匹配从图像中提取矩形区域的子像素精度补偿(getRectSubPix)在图像中搜索和匹配模板(matchTemplate)比较两个形状(轮廓)的相似度(matchShapes)解释二十、图像矩计算图像或轮廓的矩(moments)计算图像或轮廓的Hu不变矩(HuMoments)解释使用示例二一、......
  • OpenCV——实现视频图像抖动的效果
    #Jitterimportcv2importnumpyasnp#视频路径和输出路径input_video_path=r'D:\desk\20240713_test\Ori_Videos\ori_videos\IR\ir_shake_20240713.mp4'output_video_path=r'D:\desk\20240713_test\Ori_Videos\enhance\IR\jitter\jitter_20.......
  • OpenCV——实现视频图像的来回摆动的效果
    #Swingimportcv2defrotate_img(image,angle):#Readingtheimage#dividingheightandwidthby2togetthecenteroftheimageheight,width=image.shape[:2]#getthecentercoordinatesoftheimagetocreatethe2Drotationmatr......
  • OpenCV图像处理——霍夫圆检测与最小二乘法拟合圆
    HoughCircles:霍夫圆检测voidHoughCircles(InputArrayimage,OutputArraycircles,intmethod,doubledp,doubleminDist,doubleparam1=100,doubleparam2=100,intminRadius=0,intmaxRadius=0);image:输入,8-bit单通道灰度图circles:输出,vector,含有3或......