MATLAB R2022b 相机单目标定+点云-相机联合标定+opencv投影点云至图像(附保姆级教程+源码)
单目棋盘格图像,图像为一分钟视频(1秒10帧)导出,60张,标定之后还要进行筛选,保留20组就可以了。棋盘格制作:打印店,pvc材质,格子大小为110mm,有没有白边都可以。(为了便于稳定用双面胶固定在了白板上)APP里面有的相机单目标定和相机-雷达联合标定工具,注意安装matlab的时候选择Computer Vision Toolbox。按下列操作进行单目相机标定,注意图中红字注释。注意:此处要
数据准备
单目棋盘格图像,图像为一分钟视频(1秒10帧)导出,60张,标定之后还要进行筛选,保留20组就可以了。
棋盘格制作:打印店,pvc材质,格子大小为110mm,有没有白边都可以。(为了便于稳定用双面胶固定在了白板上)

一、MATLAB R2022b 单目标定
APP里面有的相机单目标定和相机-雷达联合标定工具,注意安装matlab的时候选择Computer Vision Toolbox。按下列操作进行单目相机标定,注意图中红字注释。




注意:此处要在“设置”中选择输出3个径向畸变参数,因为后续得到内参外参和畸变系数后要利用opencv中的投影方法cv2.projectPoints(np.array(pts_3d), rvec, tvec, camera_matrix, distCoeffs),进行点到图像的投影,distCoeffs变量处一般需要3个径向畸变系数和2个切向畸变系数。

注意:erros小于0.3较为合适 。



二、MATLAB R2022b 雷达-相机联合标定
APP里面有的相机单目标定和相机-雷达联合标定工具,注意安装matlab的时候选择Computer Vision Toolbox。按下列操作进行相机-雷达联合标定,注意图中红字注释。


注意:此处等待时间稍长,耐心等待 。

遇到问题:“根据提供的参数未自动匹配到检测对象。请检查棋盘格和检测参数设置执行标定”
点击确定,继续如下操作即可。



顺序刷完所有影像-点云对后,点击“APPLY”。







三、 opencv投影点云至图像
import cv2
import numpy as np
import open3d as o3d
# 读取对应时间戳的原始图像和点云数据
image_path = "img/1731575992055.png"
pcd_path = "unrefined/1731575992042.npy"
# 读取图像和点云数据
image_origin = cv2.imread(image_path)
pts_3d = np.load(pcd_path)[:,:3]
# 检查图像文件是否存在
if image_origin is None:
raise FileNotFoundError(f"Image file not found: {image_path}")
# 检查点云文件是否存在
if pts_3d is None:
raise FileNotFoundError(f"Point cloud file not found: {pcd_path}")
# 替换为你的matalab2022b,lidar-camera联合标定得到的 旋转矩阵
R_mat = np.array([[-0.03066333,-0.99949681,0.00811706],
[-0.05387041,-0.0064565,-0.99852706],
[ 0.99807702,-0.03105543,-0.05364533]])
# 将旋转矩阵转换为旋转向量,忽略雅克比矩阵
rvec, _ = cv2.Rodrigues(R_mat)
# matalab2022b,lidar-camera联合标定得到的 平移矩阵
tvec = np.float64 ([-0.33628258,-0.23184742,-1.56922673])
# 替换为你的单目相机标定得到的 内参矩阵
camera_matrix = np.array([[3.667707933106739e+03,0,1.433499422496609e+03],
[0,3.662269624729289e+03,1.045217443029531e+03],
[0,0,1]])
# 替换为你的单目相机标定得到的 径向、切向畸变系数,注意畸变系数的顺序[k1,k2,p1,p2,k3],径向畸变[k1,k2,k3],切向畸变[p1,p2]
distCoeffs = np.array([-0.180612996704174,-0.049926197398823,0, 0,2.102459188343559])
# 点云投影到图像平面
pts_2d, _ = cv2.projectPoints(np.array(pts_3d), rvec, tvec, camera_matrix, distCoeffs)
image_project = image_origin.copy()
# 遍历所有投影点,用蓝色绘制
for point_2d in pts_2d:
x, y = point_2d.ravel()
x, y = int(x), int(y)
if 0 <= x < image_origin.shape[1] and 0 <= y < image_origin.shape[0]:
cv2.circle(image_project, (x, y), 2, (255, 0, 0), -1) # 用蓝色绘制
# 显示图像
image_origin = cv2.resize(image_origin, (int(image_origin.shape[1]/2), int(image_origin.shape[0]/2)))
image_project = cv2.resize(image_project, (int(image_project.shape[1]/2), int(image_project.shape[0]/2)))
cv2.imshow("project image", image_project)
cv2.waitKey(0)
结果示例:

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)