单目相机测距

这篇具有很好参考价值的文章主要介绍了单目相机测距。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

单目相机测距



前言

根据导师的项目需求,需要在工厂环境下控制相机拍摄水泥罐车车顶图片,识别出车顶的水泥罐装圆形口并进行坐标定位,这其中需要涉及到 相机标定、单目测距、图像坐标确定、圆形物体识别 等。


一、单目测距

进行单目相机测距之前我们首先要做到两点:1.保证测距使用的图片是矫正后的、没有畸变的,可以提高我们的精度(涉及相机标定);2.我们已知相机的焦距(可以通过相机标定得到)。

1.相机标定

参考

https://blog.csdn.net/spw_1201/article/details/78417551

我们首先使用MATLAB对相机拍摄图片进行标定得到内外参数,再使用opencv通过已知内外参数进行图片矫正。

(1)获取标定板

使用最简单的黑白棋盘格标定板,可以直接从opencv官网下载得到:

https://docs.opencv.org/2.4/_downloads/pattern.png

单目相机测距

(2)拍摄图片

使用系统所用的单目相机拍摄带有棋盘格标定板各个角度的照片,保存大概15-20张即可。需要测量记录好棋盘格方格的大小,在标定中会使用。按照opencv官网提供的图片下载打印出的方格大小大约为26mm
单目相机测距

(3)进行标定

使用MATLAB进行相机标定:首先在命令行窗口中输入cameraCalibrator调用标定应用;
单目相机测距
或者在APP中找到cameraCalibrator。
单目相机测距
即可打开 Camera Calibrator
单目相机测距
将我们之前采集的图片添加进去,会出现选择棋盘格方格大小的窗口,按照我们之前的测量记录选择参数即可。
单目相机测距
单击确定后,MATLAB会自动地分析图片
单目相机测距
图片分析结束后,会出现结果窗口
单目相机测距
可以看到,我们的20张图片中有6个是不可以使用的,可能是由于角度等问题。点击view images也可以具体查看时哪些图片不可以使用。

点击确定后出现检测成功的图片结果
单目相机测距

后面就是比较关键的一步,我们需要选择标定的参数

畸变参数,总共有五个,径向畸变3个(k1,k2,k3)和切向畸变2个(p1,p2)。
在OpenCV中的畸变系数的排列(k1,k2,p1,p2,k3),千万不要以为k是连着的
单目相机测距

单目相机测距
1.camera model : standard(标准) fisheye(鱼眼),我的摄像头是标准。

2.options:选中径向畸变:“2 coefficients”并且选择偏差:“Skew“和切向畸变:“Tangential Distortion“

径向畸变:通常,两个系数足以进行校准。对于严重失真,例如在广角镜头中,您可以选择3″“3 coefficients””个系数来包含k3。

偏差: 选择Compute Skew 复选框时,校准器会估算图像轴偏斜。某些相机传感器包含缺陷,导致图像的x轴和y轴不垂直。您可以使用skew参数对此缺陷进行建模。如果不选中该复选框,则假定图像轴是垂直的,大多数现代相机都是这种情况。

切向畸变: 当镜头和图像平面不平行时,发生切向畸变。切向失真系数模拟了这种类型的失真:
(这些选项根据你的相机进行选择)

然后点击Calibrate按钮即可得到标定的结果。

单目相机测距
点击Show Undistorted按钮可以显示无畸变的图像
单目相机测距
选择导出数据,即可把参数进行保存
单目相机测距
保存后可以退出标定应用,在MATLAB主界面中将保存的cameraParams文件打开。
单目相机测距
里面的RadialDistortion对应 **k1,k2(k3设置为0了)。
单目相机测距
TangentialDistortion对应 p1,p2
单目相机测距
IntrinsicMatrix对应 内参数矩阵,注意这个和OpenCV中是转置的关系,注意不要搞错。
单目相机测距
对应于
单目相机测距

FocalLength对应 相机焦距,这个在后面进行测距工作会用到
单目相机测距

(4)使用opencv查看标定结果

代码如下

import cv2
import numpy as np


#将相机的参数设置好,固定值
#相机内参数矩阵,3*3矩阵
cameraMatrix = np.array([[3.520275278305173e+03, 7.951186274833666, 2.302224660073940e+03],
                         [0, 3.521771625935550e+03, 1.729056461937039e+03],
                         [0, 0, 1]])

#相机畸变系数矩阵,5*1矩阵(k1,k2,p1,p2,k3)
distCoeffs = np.array([0.092142020349690, -0.532537876414274, -0.002400984624408, 0.001577353702050, 0])

# 读入原图片
img = cv2.imread("E:/Cement Canning/600.jpg")
h, w = img.shape[:2]

newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, (w,h), 1, (w,h), 0)
# 计算无畸变和修正转换关系
mapx, mapy = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, None, newCameraMatrix, (w,h), cv2.CV_16SC2)

# 重映射
dst = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)

# 调整显示窗口大小
cv2.namedWindow("dst",0);
cv2.resizeWindow("dst", 1268, 952);
cv2.imshow("dst", dst)
#按任意键退出
cv2.waitKey(0)
cv2.destroyAllWindows()

矫正后的结果如下:
单目相机测距
可以看到矫正的效果并不理想,可能是选择options时不合适。
对比其他博主的效果,我认为问题可能是由于,我的图片是用手机拍摄的,手机可能已经带有去畸变矫正,所以导致实验效果不佳?

2.测距

参考

https://blog.csdn.net/m0_37811342/article/details/80394935

通过阅读其他资料可以得知 焦距F(单位像素值)、目标物体宽度W(单位m)、目标物体在图片中的像素宽度P(单位像素值)、目标物体距离相机距离X(单位m) 之间的关系:
F = (P*X) / W

那么在我们已知F、P、W的情况下即可求得物体距离D:
X = (F*W) / P

F我们在上面可以得到:
Fx = 3.520275278305173e+03
Fy = 3.521771625935550e+03

至于为什么一个相机出现两个焦距可以参考下面的讲解:

https://www.cnblogs.com/zipeilu/p/6658177.html

目标物体我使用的是标准的A4纸对折,宽度W为:0.21m,高度H为:0.1485m

单目相机测距

至于像素宽度P我们可以使用霍夫变换检测并求出白纸在图像中的像素宽度值

代码如下,用霍夫变换检测到图像中的矩形,即可得到矩形的,并通过得到的矩阵的轮廓长度和面积来计算像素宽度和像素高度

需要注意的是: 拍摄的图片中最后不要出现太多无关物体,否则识别白纸时会造成干扰。)

import cv2
import math
import numpy as np

img = cv2.imread("E:/Cement Canning/400.jpg")    #读取图像
cv2.namedWindow("img",0);
cv2.resizeWindow("img", 1268, 952);
cv2.imshow("img",img) #显示原图像

dst = img.copy()
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转为灰度值图
gaussian = cv2.GaussianBlur(gray, (5, 5), 0, 0) #高斯去噪
cv2.namedWindow("gaussian",0);
cv2.resizeWindow("gaussian", 1268, 952);
cv2.imshow("gaussian", gaussian)

ret, binary = cv2.threshold(gaussian,127,255,cv2.THRESH_BINARY) #转为二值图
cv2.namedWindow("binary",0);
cv2.resizeWindow("binary", 1268, 952);
cv2.imshow("binary", binary)

contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE) #寻找轮廓

#n=len(contours)       #轮廓个数
#for i in range(n):
    #去除掉根本不可能是要识别的矩形的物体,这个可以在
    # if len(contours[i]) >= 4:
    #     print(contours[i])
    #     length = cv2.arcLength(contours[i], True)  #获取轮廓长度
    #     area = cv2.contourArea(contours[i])        #获取轮廓面积
    #     print('length['+str(i)+']长度=',length)
    #     print("contours["+str(i)+"]面积=",area)
    #     cv2.drawContours(dst, contours, i, (0, 0, 255), 3) #绘制轮廓

#通过面积来筛选出我们要识别的矩形
c = max(contours, key=cv2.contourArea)
print(c)
cv2.drawContours(dst, c, -1, (0, 0, 255), 3) #绘制轮廓
#轮廓长度
length = cv2.arcLength(c, True)
#轮廓面积
area = cv2.contourArea(c)
#通过周长和面积计算矩形的高度和宽度
x = length/4 - (math.sqrt(math.pow(length, 2)/16 - area))
y = length/2 - x
print("高度或宽度:", x)
print("高度或宽度:", y)
cv2.namedWindow("dst",0);
cv2.resizeWindow("dst", 1268, 952);
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()

单目相机测距

单目相机测距
接下来就可以计算相机距离拍摄的白纸的距离,我们在拍摄时测量了手机镜头到白纸的距离为0.21m,后面我们通过计算来看看误差是多少。

(1)通过高度计算:
距离 = (Fy * H)/ 2251.85589
距离 = 0.23225m
误差: 10.595%

(2)通过宽度计算:

距离 = (Fx * W)/ 4381.74687
距离 = 0.16871m
误差:19.662%

分析:(1)x,y方向到白纸的距离有差别,可能是我用手机拍摄时,手机镜头不是水平的原因;(2)误差较大,可能是我测量镜头到白纸的距离用尺子测得不准确,还有就是拍摄的图片效果不好,后面可以使用工业相机再次进行尝试;(3)霍夫变换检测矩形时,检测到矩形边缘上的点不是连续的,这就导致计算出来的轮廓长度和面积有误差,导致计算出来的像素宽度和高度有误差。

根据(3)中原因,我尝试使用手动测量像素宽度和高度,高度为:2711.0158px宽度为:3757.6278px
高度计算出的距离为:0.19291m, 误差为:8.138%
宽度计算出的距离为:0.19674m, 误差为:6.314%文章来源地址https://www.toymoban.com/news/detail-425173.html

到了这里,关于单目相机测距的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【单目测距】3D检测框测距

    3D 检测模型用的 fcos3D。 如何对 3D 框测距 ? 3D 检测框测距对比 2D 检测框测距优势在哪? (1) 横向测距偏差。当目标有一定倾斜角度时,尤其近距离目标。如下图id = 0目标白车,如果是2D检测框测距,会误认为车尾在点 A 处,而实际应该在图像最左侧外部 (2) 无法测量目标的本身

    2024年01月23日
    浏览(30)
  • 单目测距(yolo目标检测+标定+测距代码)

    实时感知本车周围物体的距离对高级驾驶辅助系统具有重要意义,当判定物体与本车距离小于安全距离时便采取主动刹车等安全辅助功能,这将进一步提升汽车的安全性能并减少碰撞的发生。上一章本文完成了目标检测任务,接下来需要对检测出来的物体进行距离测量。首先

    2023年04月17日
    浏览(26)
  • 单目测距终于摆脱了参考物,实现单目测距、检测物体大小,增加了实验数据,效果很好

    🥇版权:本文由作者【 Brson.AI 】原创首发、各位读者大大敬请查阅、感谢三连🎉🎉🎉 🏆声明:作为大脑的儿子AI,专注于分享更多AI知识干货给大家🌞 🏅文章若有错误之处请大方指出,我会认真改正,谢谢各位看官❤️ 📆最近一直在捣腾关于 单目测距 和 检测物体大小

    2024年02月06日
    浏览(35)
  • 单目测距实战

    单目测距是通过使用单个摄像头捕获的图像信息俩估计物体的距离。这是一种在计算机领域广泛研究的问题,并且困难之处在于从2d图像中恢复3d信息。 单目测距常用的或者是实用方法是相似三角形法。 相似三角形法:假设有一个宽度为w的目标的或者物体。然后,我们用相机

    2024年01月25日
    浏览(29)
  • YOLOv5+单目测距(python)

    相关链接 1. YOLOV7 + 单目测距(python) 2. YOLOV5 + 单目跟踪(python) 3. YOLOV7 + 单目跟踪(python) 4. YOLOV5 + 双目测距(python) 5. YOLOV7 + 双目测距(python) 6. 具体实现效果已在Bilibili发布,点击跳转 本篇博文工程源码下载 链接1:https://download.csdn.net/download/qq_45077760/87708260 链接2:

    2024年02月05日
    浏览(90)
  • 目标检测+目标追踪+单目测距(毕设+代码)

    更多视觉额自动驾驶项目请见: 小白学视觉 自动驾驶项目 现推出专栏项目:从图像处理(去雾/去雨)/目标检测/目标跟踪/单目测距/到人体姿态识别等视觉感知项目 ------------------------传送门 废话不多说,切入正文! YOLOv5是一种计算机视觉算法,它是YOLO(You Only Look Once)系

    2024年02月05日
    浏览(36)
  • YOLOV5 + PYQT5单目测距(四)

    系统:win 10 YOLO版本:yolov5 5.0 拍摄视频设备:安卓手机 电脑显卡:NVIDIA 2080Ti(CPU也可以跑,GPU只是起到加速推理效果) 详见文章 YOLOV5 + 单目测距(python) 首先安装一下pyqt5 接着再pycharm设置里配置一下 添加下面两个工具: 工具1:Qt Designer 工具2:PyUIC 实验采用的是一个博主

    2024年02月08日
    浏览(34)
  • 单目测距(车辆测距+前车碰撞预警)-基于yolov8/yolov7/yolov5——毕业设计

    一、开发环境 部署平台:英伟达的Jetson Nano 环境:Linux + ROS 语言:C++ 设备:1920*1080像素的摄像头、开发板。 模型:yolo-v8s 二、单目测距实现思路 0、标定相机和车辆(假设已经标定完成) 1、通过yolo对目标检测,获得ROI区域 2、根据ROI计算车辆和地面接触的中心点 3、根据车

    2024年02月02日
    浏览(49)
  • 计算机视觉实战项目2(单目测距+图像处理+路径规划+车牌识别)

    用python3+opencv3做的中国车牌识别,包括算法和客户端界面,只有2个文件,一个是界面代码,一个是算法代码,点击即可出结果,方便易用! 链接:车牌识别 大致的UI界面如下,点击输入图片,右侧即可出现结果! 额外说明:算法代码只有500行,测试中发现,车牌定位算法的

    2024年02月07日
    浏览(49)
  • 自动驾驶:低阶可部署的单目测距算法-基于YOLO与透视变换

    一、开发环境 部署平台:英伟达的Jetson Nano 环境:Linux + ROS 语言:C++ 设备:1920*1080像素的摄像头、开发板。 模型:yolo-v8s 二、单目测距实现思路 0、标定相机和车辆(假设已经标定完成) 1、通过yolo对目标检测,获得ROI区域 2、根据ROI计算车辆和地面接触的中心点 3、根据车

    2024年02月02日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包