如何在Matlab中从.ply点云文件提取RGB图像
问题根因
ptCloud.Color 返回的是 N×3 格式的一维颜色数组,每一行对应一个点的R/G/B通道值,并非imshow要求的 高度×宽度×3 格式的三维图像矩阵。你直接传入imshow时,软件会将其识别为宽度仅为3像素、高度为256601像素的极窄图像,视觉上看起来就是空白的图窗。
解决方法
根据你使用的点云类型不同,对应两种解决方案:
场景1:有序点云(由结构光/深度相机直接输出的规整点云)
有序点云的点排布和原始成像的行列顺序一一对应,你只需要把颜色数组reshape成对应分辨率的三维图像矩阵即可:
% 先确认你的点云对应的原始图像分辨率,这里H*W需要等于总点数256601,可根据你采集设备的参数调整数值 H = 421; W = 609; % 转换为图像格式 I = reshape(ptCloud.Color, H, W, 3); imshow(I);
如果reshape后图像是错乱的,调整H和W的数值,或者交换reshape的前两个维度即可。
场景2:无序点云(由三维重建/多片拼接得到的非规整散点云)
需要先将点云投影到二维平面生成图像,两种常用投影方式的实现代码如下:
正射投影(无透视形变,适合正视/俯视切片生成)
% 自定义投影分辨率,数值越大生成的图像越精细 resolution = 100; % 计算图像尺寸 xRange = ptCloud.XLimits; yRange = ptCloud.YLimits; imgW = round(diff(xRange)*resolution); imgH = round(diff(yRange)*resolution); % 初始化空白RGB图像 I = zeros(imgH, imgW, 3, 'uint8'); % 计算每个点对应的像素坐标 xIdx = round((ptCloud.Location(:,1) - xRange(1))*resolution) + 1; yIdx = round((yRange(2) - ptCloud.Location(:,2))*resolution) + 1; % 过滤超出边界的无效点 valid = xIdx >=1 & xIdx <= imgW & yIdx >=1 & yIdx <= imgH; % 给对应像素赋值颜色 linearIdx = sub2ind([imgH, imgW], yIdx(valid), xIdx(valid)); for channel = 1:3 I(linearIdx + (channel-1)*imgH*imgW) = ptCloud.Color(valid, channel); end imshow(I);
透视投影(模拟相机视角生成图像)
直接借助Matlab点云渲染接口获取渲染结果:
% 渲染点云,调整MarkerSize可避免点之间出现空隙 pcshow(ptCloud, 'MarkerSize', 1); % 隐藏坐标轴 axis off; % 提取当前轴的渲染结果 frame = getframe(gca); I = frame.cdata; imshow(I);
内容的提问来源于stack exchange,提问作者solomon
相关产品推荐
相关产品推荐

