1.在这里采用的是pcl点云库。pcl点云库可能存在配置问题,用cmake时候默认支持的是32位的处理,所以建议安装pcl 32位的all-in-one。这样不容易产生错误。
2. 下面试cmake的内容。
cmake_minimum_required(VERSION 2.6 FATAL_ERROR)
project(MY_NORMAL_PROJECT)
find_package(PCL 1.3 REQUIRED )
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
add_executable(normaltest normaltest.cpp)
target_link_libraries(normaltest ${PCL_LIBRARIES})
3.下面是 normaltest.cpp 的内容
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/surface/mls.h>
#include <pcl/common/centroid.h>
#include <pcl/common/transforms.h>
#include<iostream>
#include<fstream>
#include<vector>
typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloudT;
//using namespace std;
int
main (int argc,
char *argv[])
{
//read file
std::vector<double> X_vector;
std::vector<double> Y_vector;
std::vector<double> Z_vector;
std::vector<double> R_vector;
std::vector<double> G_vector;
std::vector<double> B_vector;
double x_temp, y_temp, z_temp, r_temp, g_temp, b_temp,U,V;
//std::fstream in;
for (int jj=0; jj < 1;jj++)
{
std::fstream in;
char filename[30] = {0};
sprintf(filename, "Data%d.txt", jj);
/*fstream in(filename);*/
in.open(filename, fstream::in);
cout<<"process "<<filename<<endl;
//in.open("Data0.txt", fstream::in);
in.seekg(0);
int NumPoint;
//int nnnn=10000;
while (!in.eof())// while(nnnn--)
{
//cout<<x_temp<<"\t";
in >> x_temp >> y_temp >> z_temp >> r_temp >> g_temp >> b_temp>>U>>V;
//cout<<x_temp<<"\t";
X_vector.push_back(x_temp);
Y_vector.push_back(y_temp);
Z_vector.push_back(z_temp);
R_vector.push_back(r_temp);
G_vector.push_back(g_temp);
B_vector.push_back(b_temp);
}
cout<<"read done"<<filename<<endl;
NumPoint =X_vector.size();
cout<<NumPoint<<endl;
cout<<"begin!\n";
// Load point cloud from disk
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZRGB>);
// Fill in the cloud data
cloud->width = NumPoint;
cloud->height = 1;
cloud->points.resize (cloud->width * cloud->height);
cout<<"cloud->points.size ()"<<cloud->points.size ()<<endl;
//for (size_t i = 0; i < cloud->points.size (); ++i)
for (size_t i = 0; i < cloud->points.size (); ++i)
{
//cout<<i<<endl;
cloud->points[i].x = X_vector.at(i) ;
cloud->points[i].y = Y_vector.at(i) ;
cloud->points[i].z = Z_vector.at(i) ;
cloud->points[i].r = (int)R_vector.at(i) ;
cloud->points[i].g = (int)G_vector.at(i) ;
cloud->points[i].b = (int)B_vector.at(i) ;
//cout<<i<<endl;
}
//PointCloudT::Ptr cloud (new PointCloudT);
PointCloudT::Ptr cloud_centered (new PointCloudT);
// Compute 3D centroid of the point cloud
Eigen::Vector4f centroid;
pcl::compute3DCentroid (*cloud, centroid);
std::cout << "Centroid\n" << centroid.head<3>() << std::endl;
// Translate point cloud centroid to origin
Eigen::Affine3f transformation (Eigen::Affine3f::Identity());
transformation.translation() << -centroid.head<3>();
pcl::transformPointCloud(*cloud, *cloud_centered, transformation);
// Normal estimation
pcl::PointCloud<pcl::Normal>::Ptr cloud_normals (new pcl::PointCloud<pcl::Normal>);
pcl::PointCloud<pcl::Normal>::Ptr cloud_centered_normals (new pcl::PointCloud<pcl::Normal>);
pcl::search::KdTree<PointT>::Ptr tree (new pcl::search::KdTree<PointT> ());
pcl::NormalEstimation<PointT, pcl::Normal> ne;
ne.setSearchMethod (tree);
ne.setRadiusSearch (0.0072);
ne.setViewPoint (0, 0, 1.0);
// Compute normals on original cloud
ne.setInputCloud (cloud);
ne.compute (*cloud_normals);
// Compute normals on centered cloud
ne.setInputCloud (cloud_centered);
ne.compute (*cloud_centered_normals);
//write file
char filename1[30] = {0};
sprintf(filename1, "Normal%d.asc", jj);
/*fstream in(filename);*/
std::fstream out1;
out1.open(filename1, fstream::out);
for (size_t i = 0; i < cloud->points.size (); ++i)
{
//cout<<i<<endl;
out1<<cloud->points[i].x<<"\t"
<<cloud->points[i].y<<"\t"
<<cloud->points[i].z<<"\t"
<<(int)cloud->points[i].r<<"\t"
<<(int)cloud->points[i].g<<"\t"
<<(int)cloud->points[i].b<<"\t"
<<cloud_normals->points[i].normal_x<<"\t"
<<cloud_normals->points[i].normal_y<<"\t"
<<cloud_normals->points[i].normal_z<<"\n";
//cout<<i<<endl;
}
out1.close();
char filename2[50] = {0};
sprintf(filename2, "NormalCenter%d.asc", jj);
/*fstream in(filename);*/
std::fstream out2;
out2.open(filename2, fstream::out);
for (size_t i = 0; i < cloud->points.size (); ++i)
{
//cout<<i<<endl;
out2<<cloud->points[i].x<<"\t"
<<cloud->points[i].y<<"\t"
<<cloud->points[i].z<<"\t"
<<(int)R_vector.at(i)<<"\t"
<<(int)G_vector.at(i)<<"\t"
<<(int)B_vector.at(i)<<"\t"
<<cloud_centered_normals->points[i].normal_x<<"\t"
<<cloud_centered_normals->points[i].normal_y<<"\t"
<<cloud_centered_normals->points[i].normal_z<<"\n";
//cout<<i<<endl;
}
out2.close();
X_vector.clear();
Y_vector.clear();
Z_vector.clear();
R_vector.clear();
G_vector.clear();
B_vector.clear();
cout<<"finish "<<jj<<endl<<endl;
// Visualization
pcl::visualization::PCLVisualizer viewer ("Normals visualizer");
int v1(0); int v2(1);
viewer.createViewPort (0.0, 0.0, 0.5, 1.0, v1);
viewer.createViewPort (0.5, 0.0, 1.0, 1.0, v2);
viewer.setBackgroundColor(0.1, 0.1, 0.1, v2);
// Add point clouds
viewer.addPointCloud (cloud, "cloud", v1);
viewer.addPointCloudNormals<PointT, pcl::Normal> (cloud, cloud_normals, 1, 0.05, "normals", v1);
viewer.addPointCloud (cloud_centered, "cloud_centered", v2);
viewer.addPointCloudNormals<PointT, pcl::Normal> (cloud_centered, cloud_centered_normals, 1, 0.05, "centered_normals", v2);
while (!viewer.wasStopped ())
viewer.spinOnce ();
}
return 0;
}
4.这是输入点云的文件
本人的点云数据中一行包括了
XYZRGBUV
其实估算法向向量只要用到
XYZ
5.通过cmake编译了程序之后,在利用vs生成之后在debug文件下,直接运行exe文件就可以得到点云的方向量
6.可视化的结果