终于把点云单侧面投影正射投影的代码写完了,为一个阶段,主要使用平面插值方法,且只以XOY平面作为的正射投影面。有些凑合的地方,待改进。
方法思路:使用Mesh模型,对每一个表面进行表面重建。借助OpenCV Mat类型对投影平面进行内点判断,对内点位置进行插值。
OpenCV cv::polylines 和lines 进行画图的时候都会出现问题,因此在某些时刻无法使用连通域查找的方法进行内点检测,应该重写line方法。
1.使用Mesh载入ply模型,和同步载入点云,也可以从mesh直接Copy点云。pcl::PolygonMesh cloudMesh;
pcl::io::loadPolygonFileOBJ(ViewPath, cloudMesh);
pcl::fromPCLPointCloud2(cloudMesh.cloud, *cloud);
ViewPath = "D:/DataSet/RGB_data/teapot.pcd";
pcl::io::savePCDFileASCII(ViewPath, *cloud);//一定要注意高和宽进行赋值
pcl::visualization::PCLVisualizer Viewer;//pcl::visualization::PCLVisualizer ViewerMesh;
Viewer.addPolygonMesh(cloudMesh);
int FrameX = 1000;
int FrameY = 1000;
int FrameZ = 1000;
int Centroid = 0;
int num = 12;
float gap = 3.141592653/num;
Eigen::Vector4f ViewPoint( 0.0, 0.0, 0.0, 1);//使用弧度
ViewPoint[0] = gap*i;
cv::Mat imgGray = viewEx->getCloudViewByEdge(
cloud, cloudView, cloudMesh, ViewPath, FrameX, FrameY, FrameZ, Centroid, ViewPoint);
2. 使用平面填充方法进行投影...//使用多边形填充的方法进行投影
//获取点云侧面投影
//输入:点云的点集、边集
cv::Mat CViewExtract::getCloudViewByEdge(
pcl::PointCloud<:pointxyz>::Ptr cloud,
pcl::PointCloud<:pointxyz>::Ptr cloudView,
pcl::PolygonMesh &cloudMesh,
std::string ViewPath,
int FrameX, int FrameY, int FrameZ,
int Centroid,
Eigen::Vector4f &ViewPoint)
{
int BbxSize = FrameX;
pcl::PointCloud<:pointxyz>::Ptr cloudTrans(new pcl::PointCloud<:pointxyz>);
this->viewTrans(cloud, cloudTrans, ViewPoint);
//对点云进行侧面投影
std::vector<:pointcloud>> surfaces;
pcl::PointCloud<:pointxyz>::Ptr surface(new pcl::PointCloud<:pointxyz>);
//计算平面
genSurfaceFromVertices(cloudMesh.polygons, cloudTrans, surface);//由cloud替换cloudtrans,mesh只是一个索引
cv::Mat imgGray = getViewer(surface, cloudTrans, cloudView);
return imgGray;
}
3. 子函数
视点变换float CViewExtract::viewTrans(
pcl::PointCloud<:pointxyz>::Ptr cloudSrc,
pcl::PointCloud<:pointxyz>::Ptr cloudTrans,
Eigen::Vector4f &AngleTrans)
{
//1. Trans the VIew...
float AngleA, AngleB, AngleC;//声明视角//初始化 作为原始角度
AngleA = AngleTrans[0];//49.0/pi;
AngleB = AngleTrans[1];//78.9/pi;
AngleC = AngleTrans[2];//34.8/pi;
int size = cloudSrc->points.size();
cloudTrans->resize(0);
cloudTrans->reserve(size);
//位姿识别角度变换矩阵/
Eigen::Matrix4f TransX, TransY, TransZ;
//初始化三个矩阵!变换!
TransX << 1, 0, 0, 0,
0, cos(AngleA), -sin(AngleA), 0,
0, sin(AngleA), cos(AngleA), 0,
0, 0, 0, 1;//
TransY << cos(AngleB), 0, sin(AngleB), 0,
0, 1, 0, 0,
-sin(AngleB), 0, cos(AngleB), 0,
0, 0, 0, 1;
TransZ << cos(AngleC), -sin(AngleC), 0, 0,
sin(AngleC), cos(AngleC), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1;
//点云模型角度变换
Eigen::Vector4f Centroid;
Centroid <