如何根据深度图生成点云图

如何根据深度图生成点云图

此部分参考 https://blog.csdn.net/leon_zeng0/article/details/72956750

//程序开始


#include "stdafx.h" 

#include 
#include 

#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"

#include 
#include 
using namespace std;
using namespace cv;


// 定义点云类型
typedef pcl::PointXYZRGBA PointT;
typedef pcl::PointCloud PointCloud;

// 相机内参
const double camera_factor = 1000;
const double camera_cx = 623.827;// 325.5;
const double camera_cy = 354.457;// 253.5;
const double camera_fx = 699.751;// 518.0;
const double camera_fy = 699.751;// 519.0;

// 主函数
int main(int argc, char** argv)
{
	// 读取./data/rgb.png和./data/depth.png,并转化为点云

	// 图像矩阵
	cv::Mat rgb, depth;
	// 使用cv::imread()来读取图像
	// API: http: //docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imread#cv2.imread
	rgb = cv::imread("a1.png");
	// rgb 图像是8UC3的彩色图像
	// depth 是16UC1的单通道图像,注意flags设置-1,表示读取原始数据不做任何修改
	depth = cv::imread("a2.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(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(m)[n * 3];
			p.g = rgb.ptr(m)[n * 3 + 1];
			p.r = rgb.ptr(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("grassground.pcd", *cloud);
	// 清除数据并退出
	cloud->points.clear();
	cout << "Point cloud saved." << endl;
	return 0;
}
  

注意,我使用的是opencv4.0.0,如果使用的是opencv2.4.9,可能会出现无法找到文件opencv2/imgcodecs.hpp的错误,需要自己将文件添加到工程包含的目录中。

文件下载地址 https://github.com/opencv/opencv/blob/master/modules/imgcodecs/include/opencv2/imgcodecs.hpp

 

 

如何使用pcl_viewer显示带有纹理信息的点云图

参考 https://blog.csdn.net/zhuquan945/article/details/52808785?locationNum=6&fps=1

在安装好pcl1.8.1之后,找到pcl_viewer_debug.exe或者pcl_viewer_release.exe所在的位置,然后在文件夹空白位置,按住shift,点击鼠标右键,打开终端。执行以下命令。

pcl_viewer_debug 你的pcl文件目录
(base) PS D:\Equipment\Pointcloud\mypcl\PCL 1.8.1\bin> pcl_viewer_debug F:\cppcode\Nov20_pcltest\TestFunction\TestFunction\pointcloud.pcd
The viewer window provides interactive commands; for help, press 'h' or 'H' from within the window.
> Loading F:\cppcode\Nov20_pcltest\TestFunction\TestFunction\pointcloud.pcd [done, 117048 ms : 849059 points]
Available dimensions: x y z rgba
(base) PS D:\Equipment\Pointcloud\mypcl\PCL 1.8.1\bin>
(base) PS D:\Equipment\Pointcloud\mypcl\PCL 1.8.1\bin>

如何根据深度图生成点云图_第1张图片

如图所示的兔子。这里附上兔子的点云数据集。兔子

 

如何根据深度图生成点云图_第2张图片

或者是室外的草坪场地。

要养成记录的习惯,不然过了两个月我居然完全忘记我两个月前就已经做过这件事情了。

 

 

你可能感兴趣的:(三维重建)