.PCD 转 .PLY 转 .OBJ

日期:2021/12/1

.PCD 转 .PLY

该部分转换通过程序来实现,参考程序:https://github.com/miyaxu0312/pcd2ply
环境配置:opencv3.4 pcl1.9.1(cmakelists.txt中的要求),我用的pcl1.8编译运行也没有问题。
main.cpp修改如下:
== 注意:参考程序中,主函数第二部分注释存在问题,采用以下方式即可。==

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/ply_io.h>
#include <pcl/PCLPointCloud2.h>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/io/io.h>

using namespace pcl::io;
using namespace cv;
using namespace std;
using namespace std;
int user_data;

//第一部分函数:
/*
pcl::PointCloud<pcl::PointXYZRGB>::Ptr depth2cloud(cv::Mat rgb_image, cv::Mat depth_image)
{
	float f = 570.3;
	float cx = 342.0, cy = 456.0;

	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>());
	cloud_ptr->width = rgb_image.cols;
	cloud_ptr->height = rgb_image.rows;
	cloud_ptr->is_dense = false;

	for (int y = 0; y < rgb_image.rows; ++y) {
		for (int x = 0; x < rgb_image.cols; ++x) {
			pcl::PointXYZRGB pt;
			//pt.r = rgb_image.at<cv::Vec3b>(y, x)[2];
			if (depth_image.at<unsigned short>(y, x) != 0)
			{
				pt.z = depth_image.at<unsigned short>(y, x) / 1000.0;
				//pt.z = depth_image.at<unsigned short>(y, x);
				pt.x = (x - cx)*pt.z / f;
				pt.y = (y - cy)*pt.z / f;
				pt.r = rgb_image.at<cv::Vec3b>(y, x)[2];
				pt.g = rgb_image.at<cv::Vec3b>(y, x)[1];
				pt.b = rgb_image.at<cv::Vec3b>(y, x)[0];
				cloud_ptr->points.push_back(pt);
			}
			else
			{
				pt.z = 0;
				pt.x = 0;
				pt.y = 0;
				pt.r = 0;
				pt.g = 0;
				pt.b = 0;
				cloud_ptr->points.push_back(pt);
			}
		}
	}
	return cloud_ptr;
}
*/
//第二部分函数:
void viewerOneOff(pcl::visualization::PCLVisualizer& viewer)
{
	viewer.setBackgroundColor(1.0, 0.5, 1.0);
	pcl::PointXYZ o;
	o.x = 1.0;
	o.y = 0;
	o.z = 0;
	viewer.addSphere(o, 0.25, "sphere", 0);
	std::cout << "i only run once" << std::endl;

}

void viewerPsycho(pcl::visualization::PCLVisualizer& viewer)
{
	static unsigned count = 0;
	std::stringstream ss;
	ss << "Once per viewer loop: " << count++;
	viewer.removeShape("text", 0);
	viewer.addText(ss.str(), 200, 300, "text", 0);

	//FIXME: possible race condition here:
	user_data++;
}
//第三部分函数:
int PCDtoPLYconvertor(string & input_filename, string& output_filename)
{
	pcl::PCLPointCloud2 cloud;
	if (loadPCDFile(input_filename, cloud) < 0)
	{
		cout << "Error: cannot load the PCD file!!!" << endl;
		return -1;
	}
	pcl::PLYWriter writer;
	writer.write(output_filename, cloud, Eigen::Vector4f::Zero(), Eigen::Quaternionf::Identity(), true, true);
	return 0;

}

int main(int argc, char* argv[])
{

	string str = "mainpath";
	string className = "";
	//string imgPath = str + className + "_img2.png";
	//string depthPath = str + className + "_prediction.png";
	string pcdName2 = "result.pcd";

	cv::Mat depth;
	cv::Mat image;

	//第一部分:生成点云pcd文件
	/*
	image = cv::imread(imgPath);
	//cv::Size t_s;
	//t_s.width = 320;
	//t_s.height = 240;
	//cv::resize(image, image, t_s);
	depth = cv::imread(depthPath, IMREAD_ANYDEPTH);
	//cv::resize(depth, depth, t_s);
	string pcdName(pcdName2);
	if (!image.data || !depth.data)        // 判断图片调入是否成功
	return -1;        // 调入图片失败则退出

	pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);

	cloud = depth2cloud(image, depth);

	pcl::io::savePCDFileASCII(pcdName, *cloud);
	*/

	//第二部分:显示pcd文件
	/*
	cout << "line 136" << endl;
	pcl::PointCloud<pcl::PointXYZRGBA>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBA>);
	cout << "line 138" << endl;
	pcl::io::loadPCDFile("result.pcd", *cloud);
	cout << "line 140" << endl;

	pcl::visualization::CloudViewer viewer("Cloud Viewer");

	//blocks until the cloud is actually rendered
	viewer.showCloud(cloud);

	//use the following functions to get access to the underlying more advanced/powerful
	//PCLVisualizer

	//This will only get called once
	viewer.runOnVisualizationThreadOnce(viewerOneOff);
	cout << "line 150" << endl;
	//This will get called once per visualization iteration
	viewer.runOnVisualizationThread(viewerPsycho);
	while (!viewer.wasStopped())
	{
		user_data++;
	}
	*/

	//第三部分:将pcd转化为ply

	string input_filename = "/home/sun/Filtering/pork/voxelgrid/before1_inliers_downsampled.pcd";  //pcd文件所在地址
	string output_filename = "/home/sun/Filtering/pork/voxelgrid/before1_inliers_downsampled.ply";  //ply文件的保存位置
	PCDtoPLYconvertor(input_filename, output_filename);
	

	return 0;
}

编译运行过程修改如下:

 mkdir build
 cd build
 cmake ..
 make -j8
 ./ get_ply  //参考程序中是./pcd2ply,与cmakelists.txt中书写的不符。

.PLY 转 .OBJ

参考链接:https://blog.csdn.net/qq_43679414/article/details/114639759
按照上述过程可以实现转换,可是在操作过程中会出现一个问题:
生成的法向量方向是相反的,进而导致生成的网格也是在相反的一面,如下图所示:在这里插入图片描述解决方法:
在meshlab中,进行如下操作:filters——normals,curvatures and orientation——invert faces orientation,可以实现法向量反向,进而得到理想的网格。
在这里插入图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

兔子的倔强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值