参考博客:
https://blog.csdn.net/Architet_Yang/article/details/90037205#commentBox
在创建一个云点时将(p.x,p.y,p.z)分别加个负号
原代码:
// 创建一个pcl::PointXYZRGB格式的云点
// 此时生成的点云是反的
...
typedef pcl::PointXYZRGB PointT;
PointT P;
p.x = point[0];
p.y = point[1];
p.z = point[2];
p.b = rgbImg.ptr<uchar>(m)[n*3];
p.g = rgbImg.ptr<uchar>(m)[n*3+1];
p.r = rgbImg.ptr<uchar>(m)[n*3+2];
修改后
...
typedef pcl::PointXYZRGB PointT;
PointT P;
p.x = - point[0]; // 在这里分别添加负号
p.y = - point[1];
p.z = - point[2];
p.b = rgbImg.ptr<uchar>(m)[n*3];
p.g = rgbImg.ptr<uchar>(m)[n*3+1];
p.r = rgbImg.ptr<uchar>(m)[n*3+2];
将一张图像转化为点云
PointCloud::Ptr PointCloudCreate(const cv::Mat &rgbImg, const cv::Mat &depthImg)
{
// 相机内参
double cx = 320.1;
double cy = 247.6;
double fx = 535.4;
double fy = 539.2;
double depthScale = 5000.0;
PointCloud::Ptr cloud ( new PointCloud );
for (int m = 0; m < rgbImg.rows; m++)
{
for (int n=0; n < rgbImg.cols; n++)
{
// 获取深度图中(m,n)处的值
ushort d = depthImg.ptr<ushort>(m)[n];
// d 可能没有值,若如此,跳过此点
if (d == 0)
continue;
// d 存在值,则向点云增加一个点
PointT p;
// 计算这个点的空间坐标
// 在这里加负号
p.z = - double(d) / depthScale;
p.x = - (n - cx) * p.z / fx;
p.y = - (m - cy) * p.z / fy;
// 从rgb图像中获取它的颜色
// rgb是三通道的BGR格式图,所以按下面的顺序获取颜色
p.b = rgbImg.ptr<uchar>(m)[n*3];
p.g = rgbImg.ptr<uchar>(m)[n*3+1];
p.r = rgbImg.ptr<uchar>(m)[n*3+2];
cloud->points.push_back( p );
}
}
// 设置并保存点云
cloud->height = 1;
cloud->width = cloud->points.size();
cloud->is_dense = false;
return cloud;
}