如何计算已知大小物体的距离
你需要事先知道以下两件事之一
- 焦距(以毫米和每毫米像素为单位)
- 图像传感器的物理尺寸(以计算每毫米像素)
我将使用焦距,因为我不想为传感器数据表搜索谷歌。
校准相机
使用OpenCV的calibrate.py
工具和提供在源代码中的棋盘格图案PNG生成校准矩阵。我从尽可能多的角度拍摄了大约两打棋盘格照片,并将文件导出到我的Mac。有关更多详细信息,请查看OpenCV相机校准文档。
相机校准矩阵(iPhone 5S后置摄像头)
RMS: 1.13707201375
camera matrix:
[[ 2.80360356e+03 0.00000000e+00 1.63679133e+03]
[ 0.00000000e+00 2.80521893e+03 1.27078235e+03]
[ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]
distortion coefficients: [ 0.03716712 0.29130959 0.00289784 -0.00262589 -1.73944359]
- f_x = 2803,对应横向焦距
- f_y = 2805,对应纵向焦距
- c_x = 1637,图像中心点的横坐标
- c_y = 1271,图像中心点的纵坐标
检查你拍摄的棋盘照片系列的细节,可以发现照片的本机分辨率(3264x2448),并且在它们的JPEG EXIF header中,可在iPhoto中找到焦距值(4.15mm)。这些项目应根据相机而异。
每毫米像素数
我们需要知道图像传感器上的像素每毫米(px/mm)。从相机重定位页面上得知,f_x和f_y是焦距乘以缩放因子。
f_x = f * m_x
f_y = f * m_y
由于每个公式都有两个变量,我们可以解出m_x和m_y的值。我只是将2803和2805取平均值得到了2804。
m = 2804px / 4.15mm = 676px/mm
像素中的对象大小
我使用OpenCV(C++)来获取旋转矩形的点,并确定对象的大小为41px。请注意,我已经检索到了对象的角落,并要求边界矩形给出其大小。
cv::RotatedRect box = cv::minAreaRect(cv::Mat(points))
小皱纹
该物体在640x480的摄像机拍摄视频中为41像素。
在低分辨率下将px转换为mm
3264/676 = 640/x
x = 133 px/mm
所以,根据 41px/133px/mm 的比例,我们可以看出图像传感器上物体的大小为 0.308mm。
距离公式
distance_mm = object_real_world_mm * focal-length_mm / object_image_sensor_mm
distance_mm = 70mm * 4.15mm / .308mm
distance_mm = 943mm
这很不错。我测量了910毫米,通过一些改进,我可能可以减少误差。
欢迎反馈。
类似三角形方法
Adrian在pyimagesearch.com演示了使用类似三角形的
不同技术。我们之前讨论过这个话题,他采用了类似三角形的方法,而我则采用了相机内参法。