正常的OBJ文件,应该附带一个MLT文件来记录各种材质信息,包括彩色信息。PCL提供两个函数pcl::io::loadPolygonFileOBJ()
和 pcl::io::loadOBJFile()
从这种OBJ文件中读取信息到数据类型pcl::TextureMesh
,然后在viewer中使用addTextureMesh
进行可视化
但是在某些情况下,只有一个OBJ文件,而颜色信息是记录在每个顶点上的(即x y z r g b),例如
v -1.285637 -0.170000 0.930000 0.568627 0.611765 0.584314
v -1.280000 -0.170000 0.931465 0.568627 0.611765 0.584314
v -1.280000 -0.168779 0.930000 0.568627 0.611765 0.584314
...
f 3 2 1
...
解决的大致方法如下:
C++代码如下:
#include
#include
#include
#include
#include
using namespace std;
// pcl::io::loadOBJFile(const std::string &file_name, pcl::PointCloud & cloud) 不能加载顶点颜色,于是我就自己实现了
bool LoadOBJFile(const string &filepath, pcl::PointCloud &cloud){
ifstream fin;
fin.open(filepath,ios::in);
if (!fin) return false;
string str;
float num_r,num_g,num_b;
pcl::PointXYZRGB point;
while(fin>>str){
if(str[0] == 118){ //判断是否是点的数据 118是v的ASCII
fin>>point.x>>point.y>>point.z>>num_r>>num_g>>num_b;
point.r = (int)(num_r*255); //OBJ提供的rgb范围是0-1,pcl中的RGB是0-255
point.g = (int)(num_g*255);
point.b = (int)(num_b*255);
cloud.points.push_back(point);
}else if(str[0] == 146) break; // 如果是f的话直接退出
}
fin.close();
return true;
}
int main(){
string filepath = "test.obj";
STEP1: 读取mesh信息(不带颜色)
pcl::PolygonMesh mesh;
if (pcl::io::loadPolygonFile(filepath, mesh)==-1) {
fprintf(stderr, " [ERROE] Could not read mesh from file %s\n", filepath.c_str());
exit(1);
}
STEP2: 读取点云信息(带颜色)
pcl::PointCloud cloud;
if (!LoadOBJFile(filepath, cloud)) {
fprintf(stderr, " [ERROE] Could not read cloud from file %s\n", filepath.c_str());
exit(1);
}
STEP3: 将mesh中的顶点替换成点云
pcl::toPCLPointCloud2(cloud, mesh.cloud);
STEP4: 可视化
pcl::visualization::PCLVisualizer::Ptr viewer_(new pcl::visualization::PCLVisualizer("results"));
viewer_->setBackgroundColor(0,0,0);
viewer_->addCoordinateSystem(1.0);
viewer_->initCameraParameters();
viewer_->addPolygonMesh(mesh, "mesh");
viewer_->spin();
return 0;
}