首页 > 编程知识 正文

pcd转ply,虚幻5转obj

时间:2023-05-06 00:08:27 阅读:234848 作者:3498

文章目录 利用PCL库函数解析OBJ利用meshlab转化自己解析OBJOBJ格式解析转换代码编译环境可视化效果

利用PCL库函数解析OBJ

利用pcl库函数解析obj的方法有bug,解析过来的时候纹理坐标确实,也就是缺少RGB信息。
这是PCL库的bug,见参考1 参考2
因此,只好自己读懂obj的格式后,自己写一下解析函数。

利用meshlab转化

转化后也缺失了RGB信息

自己解析OBJ OBJ格式解析

obj文件如下:

mtllib Tile_+003_+002_+000.mtlv -9.67653046e+001 -2.54838577e+002 2.69715271e+001v -9.76558914e+001 -2.55053558e+002 2.70283375e+001v -9.92712021e+001 -2.52890640e+002 2.68646297e+001...vt 0.11269743 0.9384023vt 0.11295749 0.93755996vt 0.11307663 0.93885833vt 0.11191387 0.93955261vt 0.11083307 0.93842274vt 0.1146261 0.93710536vt 0.11188133 0.93438381vt 0.11429998 0.93874836...usemtl Tile_+003_+002_+000_0f 4/59167 8/59168 3/59169f 38/59173 32/59170 3/59169f 106240/59180 64527/59188 2/59199f 38/59173 35/59196 34/59198f 3/59169 32/59170 4/59167f 31/59192 10/59204 20/59217f 21/151853 12/151854 49010/151855f 13/151879 14/151881 64452/151880f 18/151857 17/151862 15/151867f 23/140584 22/140585 24/140586f 113546/151859 25/151866 17/151862f 25/151866 113546/151859 105583/151870f 30275/59265 19/59229 105583/59286f 30275/59265 28/59248 19/59229...

v:vertices(顶点坐标)
vt:vertices texture(顶点纹理坐标,这里的坐标系与OPENCV的坐标系不一样,见下图,左边为这里的坐标系,右边为OpenCV的坐标系)

f:face(面,一个面对应三个顶点)其格式如下(索引从1开始):

f 顶点索引/顶点纹理索引 顶点索引/顶点纹理索引 顶点索引/顶点纹理索引f 1/1 2/2 3/3 转换代码

该代码并不通用,只试用于我的这种格式,其他的格式需要相应修改,仅供参考。

#include <pcl/io/io.h>#include <pcl/io/pcd_io.h>#include <pcl/io/obj_io.h>#include <pcl/io/ply_io.h>#include <pcl/PolygonMesh.h>#include <pcl/point_cloud.h>#include <pcl/io/vtk_lib_io.h>#include <pcl/visualization/pcl_visualizer.h>#include <string>#include <cstring>#include <fstream>#include <sstream>#include <map>#include <algorithm>#include <bits/stdc++.h>#include <opencv2/opencv.hpp>#include <opencv2/imgcodecs.hpp>using namespace cv;using namespace std;struct _xyz{public: float x; float y; float z; unsigned char r; unsigned char g; unsigned char b;public: _xyz():x(0.0),y(0.0),z(0.0),r(255),g(255),b(255) { }};struct _xy{ float x; float y;};int WIDTH,HEIGHT;Mat img;vector<int> split(string s,string delim){ vector<int> a; int index = 0; for(unsigned int i = 0;i < s.size();i++) { if(delim[0] == s[i] || i == s.size() - 1) { istringstream ss; if(i == s.size() - 1) ss.str(s.substr(index,i + 1 - index)); else ss.str(s.substr(index,i - index)); int tmp; ss >> tmp; a.push_back(tmp); index = i + 1; } } return a;}int main(int argc,char** argv){ ifstream file(argv[1],ios::in); if(!file.is_open()) { cout << "open file error!" << endl; return -1; } string line; getline(file,line); vector<_xyz> xyz; vector<_xy> rgb_index; map<int,int> Imap; while(getline(file,line) && line.size() >0) { istringstream ss(line); string type; ss >> type; if(type == "v") { _xyz item; ss >> item.x >> item.y >> item.z; xyz.push_back(item); } else if(type == "vt") { _xy item; ss >> item.x >> item.y; rgb_index.push_back(item); } else if(type == "mtllib") { continue; } else if(type == "usemtl") { string img_path; ss >> img_path; if(img_path.find("untextured") != string::npos) continue; img_path+=".jpg"; string img_path1(argv[1]); size_t pos = img_path1.rfind("/"); img_path1.replace(pos+1,img_path1.size() - pos-1,img_path); img = imread(img_path1,1); if(img.data == NULL) { cout << "can not find the texture file!" << endl; return -1; } WIDTH = img.cols; HEIGHT = img.rows; } else if(type == "f") { string s1,s2,s3; ss >> s1 >> s2 >> s3; auto s1_v = split(s1,"/"); auto s2_v = split(s2,"/"); auto s3_v = split(s3,"/"); Imap[s1_v[0]] = s1_v[1]; Imap[s2_v[0]] = s2_v[1]; Imap[s3_v[0]] = s3_v[1]; } } for(int i = 0;i < xyz.size();++i) { int index = Imap[i+1]; _xy tmp = rgb_index[index-1]; int x = tmp.x * WIDTH; int y = tmp.y * HEIGHT; y = HEIGHT - y; int b = img.at<Vec3b>(y, x)[0]; int g = img.at<Vec3b>(y, x)[1]; int r = img.at<Vec3b>(y, x)[2]; xyz[i].r = r; xyz[i].g = g; xyz[i].b = b; } // get label// pcl::PointCloud<pcl::PointXYZL>::Ptr cloud_xyzl (new pcl::PointCloud<pcl::PointXYZL>()); pcl::PLYReader reader;// string label_file(argv[1]);// label_file.replace(label_file.find("good"),4,"good/data");// label_file.replace(label_file.rfind(".obj"),4,".ply"); reader.read<pcl::PointXYZL>(label_file,*cloud_xyzl);// if (pcl::io::loadPLYFile<pcl::PointXYZL>(label_file, *cloud_xyzl) == -1) {// PCL_ERROR("Couldnot read file.n");// return -1;// }// assert(cloud_xyzl->width * cloud_xyzl->height == xyz.size()); pcl::PointCloud<pcl::PointXYZRGBL>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGBL>()); cloud->resize(xyz.size()); for(int i = 0;i < xyz.size();++i) { cloud->points[i].x = xyz[i].x; cloud->points[i].y = xyz[i].y; cloud->points[i].z = xyz[i].z; cloud->points[i].r = xyz[i].r; cloud->points[i].g = xyz[i].g; cloud->points[i].b = xyz[i].b;// cloud->points[i].label = cloud_xyzl->points[i].label; } pcl::PLYWriter writer; string save_name(argv[1]); save_name.replace(save_name.rfind(".obj"),4,".ply"); writer.write<pcl::PointXYZRGBL>(save_name,*cloud,false,false); cout << "convert finished" << endl; return 0;} 编译环境

OpenCV3.4.0 + PCL1.9
CMakeLists.txt 如下:

cmake_minimum_required(VERSION 2.6 FATAL_ERROR)project(ObjToPly)find_package(PCL 1.7 REQUIRED)find_package(OpenCV REQUIRED)include_directories(${PCL_INCLUDE_DIRS})INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})include_directories(/usr/include)link_directories(${PCL_LIBRARY_DIRS})link_directories(${OpenCV_LIBRARY_DIRS})add_definitions(${PCL_DEFINITIONS})add_definitions(-std=c++11)add_executable(2_objTopcd 2_objTopcd.cpp)target_link_libraries(2_objTopcd ${PCL_LIBRARIES}${OpenCV_LIBRARIES}) 可视化效果

左边图为利用meshlab打开的obj格式图,右图为利用meshlab打开的ply图。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。