处理点云数据(四):点云到图像平面的投影

点云到图像平面的投影

坐标系的定义

相机(x:右,y:下,z:前)
点云(x:前,y:左,z:上)

读取传感器校准参数

在KITTI数据集raw_data中有两个传感器校准参数文件calib_cam_to_cam.txt(相机到相机的标定) 和 calib_velo_to_cam.txt(点云到相机的定位)。

base_dir  = 'D:/KITTI/data_set/2011_09_26/2011_09_26_drive_0009_sync'; % 图片目录
calib_dir = 'D:/KITTI/data_set/data_object_calib/2011_09_26'; % 相机参数目录

cam       = 2; % 第3个摄像头
frame     = 0; % 第1帧(第一张图片)

calib = loadCalibrationCamToCam(fullfile(calib_dir,'calib_cam_to_cam.txt'));
Tr_velo_to_cam = loadCalibrationRigid(fullfile(calib_dir,'calib_velo_to_cam.txt'));

calib_cam_to_cam.txt(相机到相机的标定):
1
其中:
- S_xx:1x2 矫正前的图像xx的大小
- K_xx:3x3 矫正前摄像机xx的校准矩阵
- D_xx:1x5 矫正前摄像头xx的失真向量
- R_xx:3x3 (外部)的旋转矩阵(从相机0到相机xx)
- T_xx:3x1 (外部)的平移矢量(从相机0到相机xx)
- S_rect_xx:1x2 矫正后的图像xx的大小
- R_rect_xx:3x3 纠正旋转矩阵(使图像平面共面)
- P_rect_xx:3x4 矫正后的投影矩阵

3

KITTI中有四个摄像头,cell一行四列中的四列分别代表了四个不同的摄像头。


calib_velo_to_cam.txt(点云到相机的定位):
2
其中,
- R:3x3旋转矩阵
- T:3x1平移向量
- delta_f:弃用
- delta_c:弃用

4

计算点云到图像平面的投影矩阵

计算点云到图像的投影矩阵需要三个参数,分别是P_rect(相机内参矩阵)和R_rect(参考相机0到相机xx图像平面的旋转矩阵)以及Tr_velo_to_cam(点云到相机的[R T]外参矩阵)。

% 计算点云到图像平面的投影矩阵
R_cam_to_rect = eye(4);
R_cam_to_rect(1:3,1:3) = calib.R_rect{1};  % 参考相机0到相机xx图像平面的旋转矩阵
P_velo_to_img = calib.P_rect{cam+1}*R_cam_to_rect*Tr_velo_to_cam; % 内外参数 

读取点云数据

fid = fopen(sprintf('%s/velodyne_points/data/%010d.bin',base_dir,frame),'rb');
velo = fread(fid,[4 inf],'single')';
velo = velo(1:5:end,:); % 显示速度每5点移除一次
fclose(fid);

% 删除图像平面后面的所有点(近似值)
idx = velo(:,1)<5; 
velo(idx,:) = [];

5

N*4的矩阵每一列分别代表X, Y, Z轴坐标和反射率

点云投影到图像

function p_out = project(p_in,T)
% p_in为点云坐标,T为点云到图像的投影矩阵

% 数据和投影矩阵的维数
dim_norm = size(T,1); % 3维
dim_proj = size(T,2); % 4维

% 在齐次坐标中进行转换
p2_in = p_in;
if size(p2_in,2)<dim_proj
  p2_in(:,dim_proj) = 1;
end
p2_out = (T*p2_in')';

% 归一化齐次坐标:
p_out = p2_out(:,1:dim_norm-1)./(p2_out(:,dim_norm)*ones(1,dim_norm-1));

画点

点云数据中,X轴坐标代表了点云深度,所以用点云深度的大小代表了颜色的深度。

cols = jet;
% velo_img为点云在图像上的坐标
for i=1:size(velo_img,1)
  col_idx = round(64*5/velo(i,1));
  plot(velo_img(i,1),velo_img(i,2),'o','LineWidth',4,'MarkerSize',1,'Color',cols(col_idx,:));
end

6

完整代码

clear;close all; dbstop error; clc;

base_dir  = 'D:/KITTI/data_set/2011_09_26/2011_09_26_drive_0009_sync'; % 图片目录
calib_dir = 'D:/KITTI/data_set/data_object_calib/2011_09_26'; % 相机参数目录

cam       = 2; % 第3个摄像头
frame     = 5; % 第0帧(第一张图片)

calib = loadCalibrationCamToCam(fullfile(calib_dir,'calib_cam_to_cam.txt'));
Tr_velo_to_cam = loadCalibrationRigid(fullfile(calib_dir,'calib_velo_to_cam.txt'));

% 计算点云到图像平面的投影矩阵
R_cam_to_rect = eye(4);
R_cam_to_rect(1:3,1:3) = calib.R_rect{1}; % R_rect:纠正旋转使图像平面共面
P_velo_to_img = calib.P_rect{cam+1}*R_cam_to_rect*Tr_velo_to_cam; % 内外参数 P_rect:矫正后的投影矩阵

img = imread(sprintf('%s/image_%02d/data/%010d.png', base_dir, cam, frame));
imshow(img); hold on;

fid = fopen(sprintf('%s/velodyne_points/data/%010d.bin',base_dir,frame),'rb');
velo = fread(fid,[4 inf],'single')';
velo = velo(1:5:end,:); % 显示速度每5点移除一次
fclose(fid);

% 删除图像平面后面的所有点(近似值)
idx = velo(:,1)<5; 
velo(idx,:) = [];

% 投影到图像平面(排除亮度)
velo_img = project(velo(:,1:3),P_velo_to_img);

% 画点
cols = jet;
for i=1:size(velo_img,1)
  col_idx = round(64*5/velo(i,1));
  plot(velo_img(i,1),velo_img(i,2),'o','LineWidth',4,'MarkerSize',1,'Color',cols(col_idx,:));
end
  • 39
    点赞
  • 262
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
### 回答1: Kitti数据集是一个用于自动驾驶以及计算机视觉的数据集,包含了许多不同类型的数据,包括激光雷达和相机的数据。如果想要将激光雷达数据可视化到图像上,可以使用Python编写代码来实现。 首先需要加载点云数据,在Python中可以使用PCL库或Open3D库。在加载点云数据之后,需要将其转换成图像数据,这可以通过将点云数据投影到一个平面上来实现,这个平面是车辆朝向的平面。在投影点云数据时可以根据需求选择投影的范围和分辨率。然后使用opencv库将投影数据从灰度图像转换为彩色图像,并将图像保存在本地或者在屏幕上播放。 当然,对于初学者来说,上述代码并不容易理解和实现。因此,建议学习和掌握以下内容: 1. Python基础知识,包括语法、控制流和函数等。 2. PCL和Open3D库的基本使用方法。 3. Opencv库的基本使用方法。 4. 点云数据转换成图像数据的方法和参数。 最后,建议查阅相关的代码示例和文档,因为这有助于更好地理解代码和算法。通过不断练习,您可以将点云数据可视化到图像上,并得到更深层次的理解。 ### 回答2: Kitti数据集是一个基于激光雷达的自动驾驶数据集,里面包括了多种不同场景下的点云数据图像数据和各种传感器数据。其中,点云数据对于自动驾驶系统的实现具有重要意义。以下是使用Python将点云数据可视化到图像上的步骤: 1. 安装必要的Python库: ```python pip install numpy matplotlib open3d opencv-python ``` 2. 加载点云数据: 从Kitti数据集中选取某个场景下的点云数据,使用Python加载点云数据文件: ```python import numpy as np pcd = np.fromfile("path_to_point_cloud_file.bin", dtype=np.float32).reshape(-1, 4) ``` 3. 可视化点云数据: 使用Open3D库可视化点云数据,实现点云数据在三维空间内的展示: ```python import open3d as o3d pcd = o3d.geometry.PointCloud() pcd.points = o3d.utility.Vector3dVector(points) o3d.visualization.draw_geometries([pcd]) ``` 4. 投影点云数据图像平面: 将点云数据投影图像平面上,通过OpenCV库将点云数据可视化到图像上: ```python import cv2 from kitti_projection import KittiProjection range_image = KittiProjection().project_lidar_to_image(points, image_size=(1242, 375)) cv2.imshow("Range Image", range_image) cv2.waitKey(0) ``` 5. 结论: 通过上述步骤,我们可以将Kitti数据集中的点云数据可视化到图像上,实现自动驾驶系统中点云数据图像数据的结合,为自动驾驶系统的实现提供支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值