几天前,PyImageSearch读者Cameron通过电子邮件发送了邮件,询问了寻找从相机到图像中对象/标记之间距离的方法。他花了一些时间进行研究,但没有找到实现方案。

我确切地知道卡梅伦的感受。几年前,我正在做一个小项目,分析棒球在离开投手的手并驶向本垒板时的运动。

使用运动分析和基于轨迹的跟踪,我能够找到/估计视频帧中的球位置。而且由于棒球的大小已知,因此我也能够估算出到本垒板的距离。

这是一个有趣的项目,尽管该系统不如我希望的那样精确-球移动如此之快的“运动模糊”使得很难获得高度准确的估算值。

我的项目肯定是一个“异常”情况,但总的来说,确定从相机到标记的距离实际上是计算机视觉/图像处理领域中一个非常研究好的问题。您会发现非常简单明了的技术,例如三角形相似性。而且,您可以使用相机模型的固有参数找到复杂的方法(尽管更为准确)。

在此博客文章中,我将向您展示Cameron和我如何提出一种解决方案来计算从相机到已知物体或标记的距离。

对象/标记与相机距离的三角形相似度

为了确定从相机到已知物体或标记的距离,我们将利用三角形相似度

三角形相似性是这样的:假设我们有一个标记或对象,宽度称为W ^。然后,我们将该标记放置在距相机一定距离D处。我们使用相机拍摄物体的图片,然后测量像素P的视在宽度。这使我们能够得出摄像机的可感知焦距F

F =(P x D)/ W

例如,假设我将标准的8.5 x 11 英寸纸(水平;W = 11D = 24英寸放在我的相机前面,然后拍照。当我测量图像中纸的宽度时,我注意到纸的感知宽度为P = 248像素

那么我的焦距F是:

F =(248px x 24in)/ 11in = 543.45

当我继续将相机移离对象/标记越来越近时,可以应用三角形相似度来确定对象到相机的距离:

D'=(宽x F)/ P

再说一次,为了使它更具体,假设我将我的相机移离标记笔3英尺(或36英寸),并拍摄了同一张纸的照片。通过自动图像处理,我可以确定现在感知到的纸张宽度为170像素。将其插入方程式,我们现在得到:

D'=(11英寸x 543.45)/ 170 = 35英寸

或大约36英寸,即3英尺。

注意:在本示例中拍摄照片时,我的卷尺有些松弛,因此结果相差约1英寸。此外,我还匆忙拍摄了照片,而不是在卷尺的脚标记上方100%拍摄,这增加了1英寸的误差。综上所述,三角形相似性仍然成立,您可以使用此方法轻松计算从对象或标记到相机的距离。

现在有意义吗?

太棒了 让我们进入一些代码,看看如何使用Python,OpenCV,图像处理和计算机视觉技术完成从相机到物体或标记的距离查找。

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

让我们继续进行,开始这个项目。打开一个新文件,将其命名为 distance_to_camera 。py  ,我们将开始工作:

Find distance from camera to object using Python and OpenCV

Python

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 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)

我们要做的第一件事是导入必要的包(第2-5行)。我们将使用 路径   从 imutils   加载可用图像目录中。我们将使用NumPy进行数值处理,并使用 cv2   进行OpenCV绑定。

在这里,我们定义 find_marker   函数。此函数接受单个参数 image  ,用于查找要计算距离的对象。

在这种情况下,我们将使用8.5 x 11英寸的标准纸作为标记。

我们的首要任务是现在在图像中找到这张纸。

为此,我们将图像转换为灰度,将其稍微模糊以消除高频噪声,然后在9-11行上进行边缘检测  。

应用这些步骤后,我们的图像应如下所示:

图1:应用边缘检测找到我们的标记,在这种情况下,标记是一张纸。

如您所见,标记笔(纸)的边缘已经明显地暴露了出来。现在,我们要做的就是找到代表纸张的轮廓(即轮廓)。

我们 使用 cv2在第15和16行找到标记  。findContours  函数(小心处理不同的OpenCV版本),然后在第17行上确定具有最大面积的轮廓  。

我们假设最大面积的轮廓就是我们的纸。 该假设适用于此特定示例,但实际上在图像中查找标记是高度特定于应用程序的。

在我们的示例中,简单的边缘检测和找到最大轮廓效果很好。我们还可以通过应用轮廓逼近,舍弃不具有4个点的任何轮廓(因为一张纸是矩形,因此具有4个点),然后找到最大的4点轮廓,来使此示例更加健壮。

注意:有关此方法的更多信息,可以在构建脚踏式移动文档扫描器的这篇文章中找到。

在图像中查找标记的其他替代方案是利用颜色,以使标记的颜色与图像中其余场景的颜色实质上不同。您还可以应用诸如关键点检测,局部不变描述符和关键点匹配之类的方法来查找标记。但是,这些方法不在本文讨论范围之内,并且还是高度特定于应用程序的。

无论如何,现在我们有了与标记相对应的轮廓,我们将包含(x,y)坐标以及框的宽度和高度(以像素为单位)的边界框返回  到第20行的调用函数。

我们还快速定义一个函数,该函数使用上面详述的三角形相似度计算到对象的距离:

Find distance from camera to object using Python and OpenCV

Python

22
23
24

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

该函数接受一个 knownWidth  标记的,一个计算 长焦点  和图像(以像素为单位)中的对象的感知宽度,并适用上面详述来计算到对象的实际距离的三角形相似。

要了解我们如何利用这些功能,请继续阅读:

Find distance from camera to object using Python and OpenCV

Python

26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 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.png")
marker = find_marker(image)
focalLength = (marker[1][0] * KNOWN_DISTANCE) / KNOWN_WIDTH

找到与图像中的对象或标记的距离的第一步是校准  和计算焦距。为此,我们需要知道:

  • 相机到物体的距离。
  • 该对象的宽度(以英寸,米等为单位)。注意: 也可以使用高度,但是本示例仅使用宽度。

让我们再说一秒钟,我们正在做  的不是真正的相机校准。真正的相机校准涉及相机的固有参数,您可以在此处进一步了解。

第28行,我们  将从摄像机到对象的已知KNOWN_DISTANCE初始化 为24英寸。在  第32行上,我们  将对象的KNOWN_WIDTH初始化 为11英寸(即,水平放置8.5 x 11英寸的标准纸)。

下一步很重要:  这是我们简单的校准步骤。

我们在第37行的 磁盘上加载了第一张图像  -我们将使用该图像作为校准图像。

加载图像后,我们在第38行找到图像中的纸  ,然后使用三角形相似度  在  第39行 计算出 focusLength。

现在,我们已经“校准”了系统并拥有了 focusLength  ,我们可以很容易地计算后续图像中相机到标记的距离。

让我们看看如何做到这一点:

Find distance from camera to object using Python and OpenCV

Python

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

# 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)

我们开始在第42行上遍历图像路径。

然后,对于列表中的每个图像,我们在第45行上将图像从磁盘上加载下来,在第46行上找到图像中的标记    然后在第47行上计算对象到摄像机的距离  。

从那里,我们只需在标记周围画一个边界框并在第50-57行显示距离  ( boxPoints   是在第50行计算的,请  注意处理不同的OpenCV版本)。

结果

要查看我们的脚本,请打开一个终端,导航到您的代码目录,然后执行以下命令:

Find distance from camera to object using Python and OpenCV

Shell

1
$ python distance_to_camera.py

如果一切顺利的话,你应该首先看到的结果 2ft.png  ,这是我们用来“校准”我们的系统和计算我们最初的图像 长焦点  :

图2:此图像用于计算系统的初始焦距。我们首先利用图像中对象/标记的已知宽度和到对象的已知距离开始。

从上图可以看出,  根据代码中的KNOWN_DISTANCE   和 KNOWN_WIDTH变量,可以正确确定焦距,并且到纸的距离为2英尺 。

现在我们有了焦距,我们可以在后续图像中计算到标记的距离:

图3:利用焦距确定我们的纸笔标记距相机大约3英尺。

在上面的示例中,我们的相机现在距离标记大约3英尺。

让我们尝试移回另一只脚:

图4:利用计算出的焦距确定我们的相机距离我们的标记大约4英尺。

再次提醒您,当我为该示例拍摄照片时,我仓促行事,并在卷尺上留下了太多的懈怠。此外,我也没有确保我的相机在脚标上对齐了100%,因此,在这些示例中,还是有大约1英寸的误差。

综上所述,本文详细介绍的三角形相似度方法仍然可以使用,并允许您查找图像中的对象或标记到相机的距离。

摘要

在此博客文章中,我们学习了如何确定图像中已知物体到相机的距离  。

为了完成此任务,我们利用了  三角形相似度,这需要我们在应用算法之前了解两个重要参数:

  1. 我们用作标记的对象在某种距离度量中的宽度(或高度),例如英寸或米。
  2. 步骤1中相机到标记的  距离(以英寸或米为单位)。

然后,可以使用计算机视觉和图像处理算法来自动确定以像素为单位的对象的感知宽度/高度,并完成三角形相似度并为我们提供焦距。

然后,在后续图像中,我们只需要找到标记/对象​​并利用计算出的焦距来确定距相机到对象的距离。

使用Python和OpenCV查找从摄像机到对象/标记的距离相关推荐

  1. 使用Python,OpenCV查找图像中的最亮点

    Python,OpenCV找出图像中的最亮点 1. 原理 2. 优化 3. 效果图 4. 源码 参考 这篇博客将向您展示如何使用Python和OpenCV查找图像中的最亮点,以及应用单行预处理代码-- ...

  2. 使用Python,OpenCV转换颜色空间,追踪对象的轨迹

    使用Python,OpenCV转换颜色空间,追踪对象的轨迹 1. 效果图 2. 源码 参考 这篇博客可以看作是之前俩篇博客的融合,将介绍如何使用Python,OpenCV转换颜色空间,并利用HSV追踪 ...

  3. 用 Python 和 OpenCV 检测和跟踪运动对象

    这个该死的家伙.我就知道他偷了我最后一罐啤酒! 对于一个男人来讲,这些话永远都不该说.但是当我关上冰箱门的时候,我愤怒地叹息,感到厌恶,自言自语地说了这些. 你看,我花了12个小时写了这篇将要发表的文 ...

  4. python使用opencv查找轮廓_(八)OpenCV-Python学习—轮廓查找,绘制和拟合

    针对物体轮廓,opencv还提供了一些相关的函数,来处理轮廓查找,绘制,拟合,以及计算轮廓周长和面积等,详细介绍如下: 1. 寻找和绘制轮廓 opencv的findContours()能寻找图片中的轮 ...

  5. python使用opencv查找轮廓_Python+opencv学习记录20:轮廓发现,Pythonopencv

    1.轮廓发现 轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法,所以边缘提取的阈值选定会影响最终轮廓发现结果. 1.1发现轮廓 在此步骤中我们会使用到findContours这个API,其原型为: ...

  6. 使用Python,OpenCV寻找图像中的轮廓

    使用Python和OpenCV查找图像中的形状 1. 效果图 2. 步骤 3. 源码 参考 这篇博客将讨论使用Python和OpenCV查找图像中的形状,具体是 cv2.inRange在图像中查找形状 ...

  7. 使用Python、OpenCV计算轮廓的中心

    1. 使用Python.OpenCV计算轮廓的中心并标记 2. 使用Python.OpenCV检测轮廓的形状并标记 3. 使用颜色通道统计信息来标记形状的实际颜色并标记 本博客的目标:(1)检测图像中 ...

  8. 使用Python,OpenCV从图像中删除轮廓

    使用Python,OpenCV从图像中删除轮廓 1. 效果图 2. 步骤 3. 源码 4. 参考 1. 使用Python.OpenCV计算轮廓的中心并标记 2. 使用Python.OpenCV检测轮廓 ...

  9. 使用Python,OpenCV检测摄像机到标记对象的距离

    使用Python,OpenCV检测摄像机到标记对象的距离 1. 效果图 2. 三角形相似性是什么? 3. 三角形相似性检测距离原理 4. 使用Python,OpenCV检测标记对象 5. 源码 参考 ...

最新文章

  1. numpy list df tensor的相互转换
  2. leetcode算法题--石子游戏
  3. java 正则表达式 反向_正则表达式中的数量表示符、反向引用、零宽断言、以及java中的用法...
  4. 做数据分析还在死磕Excel?用这个简单工具,摆脱复杂函数和公式
  5. Android之使用Intent跳转到一个网页
  6. Streaming API
  7. 文件设置索引_Linux文件系统是怎么工作的?
  8. AtCoder Beginner Contest 223
  9. C语言中 指针和数组
  10. 第二十七讲 DataSet和XML
  11. java unicode 藏文_藏文各个字母对应的unicode编码和十进制
  12. odis工程师使用教程_大众奥迪工程师软件ODIS-E车型代码说明大全完整版
  13. php收费视频网站实现,超好影视网站PHP源码,一键采集视频资源,对接第三方免签码支付,能设置每个视频能否收费...
  14. ffmpeg实现各种视频特效
  15. 四川全国计算机一级考试查询系统,2013四川计算机一级成绩查询入口
  16. ASP.NET会话(Session) 转载自:寒羽枫(cityhunter172)
  17. 引入微信支付Java SDK WxPayAPI_JAVA.zip
  18. Errors during downloading metadata for repository ‘AppStream‘: - Status code: 404 for http://mirro
  19. Android程序员必备的六大顶级开发工具,快加入你的清单,看完没有不懂的
  20. STL源码剖析-第一章STL概论与版本简介

热门文章

  1. 大视频上传服务器,支持HTML5断点续传,支持4GB以上大视频文件上传
  2. 新来CTO 强烈禁止使用Calendar...,那用啥?
  3. 新阶段金融科技发展规划:数据安全成监管重点
  4. 小程序TOP100榜单:零售、泛娱乐、内容类潜力大丨智能科技
  5. 秒速五厘米(快速二分跳跃查找答案)
  6. C语言实现基础版扫雷
  7. 玖乐解密垃圾某山代刷网废话不多自行看就行了可二开可运营
  8. IE8浏览器调试模式打开方法
  9. 运维之道 | Redis 命令解析大全
  10. 魅蓝s6 android系统版本,魅族魅蓝S6 Android 7.0 ROM刷机包 3GB RAM 全网通 官方固件