1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 使用opencv以及pcl将2D图像转换为3D点云

使用opencv以及pcl将2D图像转换为3D点云

时间:2020-03-31 19:08:36

相关推荐

使用opencv以及pcl将2D图像转换为3D点云

如果你要问怎么得到2D图片,可以看我另文博客:深度相机的图像深度实时显示

本文其实是转载自 /zhuquan945/article/details/52808785?locationNum=6&fps=1

但我做了一点小的修改。程序注释足够清楚,但你也可以参考一下原文,那有更多解说。

网上有人总发问,后来我要了他程序,我给他调试成功了,他的程序就是来自原文。

或许是环境的缘故吧,我是在windows 8, visual studio c++ 下,编译运行的。而原文在此环境下运行有问题。

编译运行此程序需要安装共享软件opencv和 pcl。 opencv 的版本是3.00beta, pcl 的版本是1.6.0。

//程序开始

#include <iostream>

#include <string>

#include "opencv2/imgcodecs.hpp"

#include "opencv2/highgui/highgui.hpp"

#include <pcl/io/pcd_io.h>

#include <pcl/point_types.h>

using namespace std;

using namespace cv;

// 定义点云类型

typedef pcl::PointXYZRGBA PointT;

typedef pcl::PointCloud<PointT> PointCloud;

// 相机内参

const double camera_factor = 1000;

const double camera_cx = 325.5;

const double camera_cy = 253.5;

const double camera_fx = 518.0;

const double camera_fy = 519.0;

// 主函数

int main( int argc, char** argv )

{

// 读取./data/rgb.png和./data/depth.png,并转化为点云

// 图像矩阵

cv::Mat rgb, depth;

// 使用cv::imread()来读取图像

// API: /modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#cv2.imread

rgb = cv::imread( "C:\\study\\1341847980.722988.png" );

// rgb 图像是8UC3的彩色图像

// depth 是16UC1的单通道图像,注意flags设置-1,表示读取原始数据不做任何修改

depth = cv::imread( "C:\\study\\1341847980.723020.png", -1 );

// 点云变量

// 使用智能指针,创建一个空点云。这种指针用完会自动释放。

PointCloud::Ptr cloud ( new PointCloud );

// 遍历深度图

for (int m = 0; m < depth.rows; m++)

for (int n=0; n < depth.cols; n++)

{

// 获取深度图中(m,n)处的值

ushort d = depth.ptr<ushort>(m)[n];

// d 可能没有值,若如此,跳过此点

if (d == 0)

continue;

// d 存在值,则向点云增加一个点

PointT p;

// 计算这个点的空间坐标

p.z = double(d) / camera_factor;

p.x = (n - camera_cx) * p.z / camera_fx;

p.y = (m - camera_cy) * p.z / camera_fy;

// 从rgb图像中获取它的颜色

// rgb是三通道的BGR格式图,所以按下面的顺序获取颜色

p.b = rgb.ptr<uchar>(m)[n*3];

p.g = rgb.ptr<uchar>(m)[n*3+1];

p.r = rgb.ptr<uchar>(m)[n*3+2];

// 把p加入到点云中

cloud->points.push_back( p );

}

// 设置并保存点云

cloud->height = 1;

cloud->width = cloud->points.size();

cout<<"point cloud size = "<<cloud->points.size()<<endl;

cloud->is_dense = false;

pcl::io::savePCDFile( "C:\\study\\pointcloud.pcd", *cloud );

// 清除数据并退出

cloud->points.clear();

cout<<"Point cloud saved."<<endl;

return 0;

}

//程序结束

程序的结果是2张图片,形成一个立体点云图片

输入的图片如下:

第2张

那么结果是怎么样的呢?

形成的是点云文件

pointcloud.pcd 放在目录c:\study 下面, 输入的图片也是放在c:\study下面。

那结果图片是怎么显示出来的呢?我就用pcl 的教学文件cloud_viewer。

在我的电脑上其目录是:

C:\Program Files (x86)\PCL 1.6.0\share\doc\pcl-1.6\tutorials\sources\cloud_viewer

很感谢原文作者的好文章,只是由于笔误,或者环境的缘故,让他在windows vs 下可以编译链接,但运行到保存文件时报错。

原文就是一把ak47 步枪,但有一粒沙子,扣动时子弹会卡,而我只是去掉它,让子弹发出去。

沙子是什么,留给读者去对比发现。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。