最近开始做口腔点云数据处理相关的工作,需要把CBCT数据中的结构转换为点云,因此选择了PCL,PCL在windows下环境的配置已经很简单了,直接安装配置即可使用,这里只对安装过程中遇到的问题和小技巧记录下来。
1、PCL1.12的安装过程可参考链接:(55条消息) PCL安装与配置(Windows10+VS2017 )_syz201558503103的博客-CSDN博客_pcl启动器。
2、安装完成后,需要去安装目录的 <PCL 1.12.0\3rdParty\OpenNI2> 里面确认下 是否只有一个 OpenNI-Windows-x64-2.2.msi 安装包(OpenNI 2 Downloads and Documentation | The Structure Sensor)。如果是就需要双击运行,卸载后,重新安装,且安装目录要和上面的一致<PCL 1.12.0\3rdParty\OpenNI2>;
3、建立VS2019控制台,进行测试的过程中,需要添加很多的lib文件,在这里可以用批处理命令把所有的lib文件名保存到txt中,这样不需要一个一个去手动添加,节省时间。
具体方法: 新建一个文件文件:list.txt. 在里面添加批处理命令: DIR *.* /B >list1.txt。
保存后关闭,将list.txt,的后缀txt,修改为bat。将list.bat,放到lib文件夹内,双击list.bat,运行完成后,在当前目录下就会有一个 list1.txt,里面即是lib文件。
如下图:
图1.快速获取lib文件列表
4、VS2019环境配置过程中lib文件添加方式 :两种方式,一种是在属性框中进行配置;另外一种是使用#pragma comment 进行添加,个人喜好后者,但在添加boost以后,编译一直提示:找不到 libboost_thread-vc142-mt-gd-x64-1_76.lib,最后采用属性框内配置后,解决。两种配置方式对比图如下:
5、编译通过后,把相关的DLL拷贝的可执行文件目录即可运行,有时会提示缺少OpenNI2.dll,解决方法是步骤2中,重新安装OpenNI2到 PCL的安装目录中即可在安装目录中找到。
6、PCD格式:(55条消息) 66.[PCL]PCD文件格式_Mars Loo的博客-CSDN博客
7、运行demo界面
demo 1
测试代码附录:
demo1:
#include <iostream>
#include <vector>
#include <ctime>
#include <pcl/point_cloud.h>
#include <pcl/octree/octree.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
using namespace std;
int main(int argc, char** argv)
{
srand((unsigned int)time(NULL));
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 创建点云数据
cloud->width = 1000;
cloud->height = 1;
cloud->points.resize(cloud->width * cloud->height);
for (size_t i = 0; i < cloud->points.size(); ++i)
{
cloud->points[i].x = 1024.0f * rand() / (RAND_MAX + 1.0f);
cloud->points[i].y = 1024.0f * rand() / (RAND_MAX + 1.0f);
cloud->points[i].z = 1024.0f * rand() / (RAND_MAX + 1.0f);
}
pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(0.1);
octree.setInputCloud(cloud);
octree.addPointsFromInputCloud();
pcl::PointXYZ searchPoint;
searchPoint.x = 1024.0f * rand() / (RAND_MAX + 1.0f);
searchPoint.y = 1024.0f * rand() / (RAND_MAX + 1.0f);
searchPoint.z = 1024.0f * rand() / (RAND_MAX + 1.0f);
//半径内近邻搜索
vector<int>pointIdxRadiusSearch;
vector<float>pointRadiussquaredDistance;
float radius = 256.0f * rand() / (RAND_MAX + 1.0f);
cout << "Neighbors within radius search at (" << searchPoint.x
<< " " << searchPoint.y
<< " " << searchPoint.z
<< ") with radius=" << radius << endl;
if (octree.radiusSearch(searchPoint, radius, pointIdxRadiusSearch, pointRadiussquaredDistance) > 0)
{
for (size_t i = 0; i < pointIdxRadiusSearch.size(); ++i)
cout << " " << cloud->points[pointIdxRadiusSearch[i]].x
<< " " << cloud->points[pointIdxRadiusSearch[i]].y
<< " " << cloud->points[pointIdxRadiusSearch[i]].z
<< " (squared distance: " << pointRadiussquaredDistance[i] << ")" << endl;
}
// 初始化点云可视化对象
boost::shared_ptr<pcl::visualization::PCLVisualizer>viewer(new pcl::visualization::PCLVisualizer("显示点云"));
viewer->setBackgroundColor(0, 0, 0);
// 对点云着色可视化 (red).
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>target_color(cloud, 255, 0, 0);
viewer->addPointCloud<pcl::PointXYZ>(cloud, target_color, "target cloud");
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "target cloud");
// 等待直到可视化窗口关闭
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(1000));
}
return (0);
}
demo2:
#include<pcl/visualization/cloud_viewer.h>
#include<iostream>//标准C++库中的输入输出类相关头文件。
#include<pcl/io/io.h>
#include<pcl/io/pcd_io.h>//pcd 读写类相关的头文件。
#include<pcl/io/ply_io.h>
#include<pcl/point_types.h> //PCL中支持的点类型头文件。
int user_data;
using std::cout;
void viewerOneOff(pcl::visualization::PCLVisualizer& viewer) {
viewer.setBackgroundColor(0.0, 0.0, 0.0); //设置背景颜色
}
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
char strfilepath[256] = "rabbit.pcd";
if (-1 == pcl::io::loadPCDFile(strfilepath, *cloud)) {
cout << "error input!" << endl;
return -1;
}
cout << cloud->points.size() << endl;
pcl::visualization::CloudViewer viewer("Cloud Viewer"); //创建viewer对象
viewer.showCloud(cloud);
viewer.runOnVisualizationThreadOnce(viewerOneOff);
system("pause");
return 0;
}