几天前,一个叫 Cameron 的 PyImageSearch 读者发来邮件询问摄像头测距的方法。他花了一些时间研究,但是没有找到解决办法。
我很能体会 Cameron 的感受。几年前我做过一个分析棒球离手飞向本垒的运动的小项目。
我通过使用运动分析和基于轨迹的跟踪方法来确定或者估计小球在视频帧中的位置。并且因为棒球的大小是已知的,所以我也能估计出其到本垒的距离。
那是个有趣的项目,虽然系统的精度没有达到我的预期。——棒球运动太快所造成的“运动模糊”让达到高精度变得十分困难。
我的项目完全算是一个个例,但是通常来说,在计算机视觉或者图形处理领域计算从相机到目标的距离实际上是一个非常容易的问题。你可以找到一个像三角形相似这样简单粗暴的方法,或者你也可以用上相机模型的内参这样更复杂一点(但是更精确)的方法。
在这篇博客,我将会告诉大家我和 Cameron 是如果解决这个计算相机到已知物体或目标的距离。
千万要看——你一定不想错过。
OpenCV 和 Python 版本:这个例子可以在Python 2.7/Python 3.4+和OpenCV 2.4.X上运行。
用相似三角形计算物体或者目标到相机的距离
我们将使用相似三角形来计算相机到一个已知的物体或者目标的距离。
相似三角形就是这么一回事:假设我们有一个宽度为 W 的目标或者物体。然后我们将这个目标放在距离我们的相机为 D 的位置。我们用相机对物体进行拍照并且测量物体的像素宽度 P 。这样我们就得出了相机焦距的公式:
F = (P x D) / W
举个例子,假设我在离相机距离 D = 24 英寸的地方放一张标准的 8.5 x 11 英寸的 A4 纸(横着放;W = 11)并且拍下一张照片。我测量出照片中 A4 纸的像素宽度为 P = 249 像素。
因此我的焦距 F 是:
F = (248px x 24in) / 11in = 543.45
当我继续将我的相机移动靠近或者离远物体或者目标时,我可以用相似三角形来计算出物体离相机的距离:
D’ = (W x F) / P
为了更具体,我们再举个例子,假设我将相机移到距离目标 3 英尺(或者说 36 英寸)的地方并且拍下上述的 A4 纸。通过自动的图形处理我可以获得图片中 A4 纸的像素距离为 170 像素。将这个代入公式得:
D’ = (11in x 543.45) / 170 = 35 英寸
或者约 36 英寸,合 3 英尺。
注意:当我给这次例子拍照时,我的卷尺有一点松,因此结果造成了大约 1 英寸的误差。还有我也是很快速地拍下了照片并且没有完全对齐卷尺上的脚标,这也会对最终结果的 1 英寸误差产生影响。综上所述,相似三角形的方法还是合理的,你也可以用这个方法很简单地计