PCL+VS2017+三维模型提取

一、环境搭建

(1)安装 Vs2017
(2)安装PCL-1.8.1-AllInOne-msvc2017-win64.exe
这步需要注意的是PCL下的OpenNI2是空的,可以把步骤里的OpenNI2.2里的内容复制进去
在这里插入图片描述
环境变量:
在这里插入图片描述

二、 error C2039: “seekpos”: 不是“std::fpos<_Mbstatet>”的成员这样的错误

只要将在positioning.hpp 中报错的这句return pos.seekpos();注释掉即可。

三、解决’fopen’:this function or variable may be unsafe先关问题的方法

点击参考

四、LNK110 无法打开文件“vtknetcdf_c++_gd.lib”

在这里插入图片描述
查看项目属性–链接器–输入里的附加依赖项是否存在这个依赖包,如果有删了即可。
在这里插入图片描述

五、找不到OpenNI2.dll

在这里插入图片描述
找到安装目录里的 OpenNI2.dll,将其复制到C:\Windows\System32

六、C3861 “pop_t”:找不到标识符

在这里插入图片描述
在这里插入图片描述

七、代码

#include<pcl/point_types.h>
#include<pcl/features/pfh.h>
#include<pcl/io/io.h>
#include<pcl/io/pcd_io.h>
#include<pcl/features/integral_image_normal.h>
#include<pcl/features/normal_3d.h>
#include<pcl/visualization/pcl_visualizer.h>
#include<pcl/visualization/histogram_visualizer.h>
#include<pcl/visualization/pcl_plotter.h>
#include<pcl/search/kdtree.h>
#include<pcl/filters/passthrough.h>
#include<pcl/filters/voxel_grid.h>
#include<pcl/features/fpfh.h>
#include<pcl/features/vfh.h>


using namespace std;

int main() {
	// 加载点云
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
	// pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	//pcl::io::loadPCDFile("E:\\Firefox\\rabbit.pcd", *cloud);
	//pcl::io::loadPCDFile("D:\\test\\rabbit.pcd", *cloud);
	pcl::io::loadPCDFile("D:\\test\\table_scene_mug_stereo_textured.pcd", *cloud);
	

	// 打印点云信息
	cout << "cloud::  width: " << cloud->width << "  height: " << cloud->height << "  size: " << cloud->points.size() << endl;

	// ------过滤数据-------//
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_fillter(new pcl::PointCloud<pcl::PointXYZ>);
	// 过滤passthrough
	pcl::PassThrough<pcl::PointXYZ> filter;
	filter.setInputCloud(cloud);
	filter.setFilterFieldName("z");
	filter.setFilterLimits(0.0f, 1.0f);
	filter.filter(*cloud_fillter);

	// 再进行三角栅格过滤
	pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filter2(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::VoxelGrid<pcl::PointXYZ> voxel;
	voxel.setInputCloud(cloud_fillter);
	voxel.setLeafSize(0.01, 0.01, 0.01);
	voxel.filter(*cloud_filter2);

	// 估计法线
	pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
	ne.setInputCloud(cloud_filter2);
	// 定义查询树
	pcl::search::KdTree<pcl::PointXYZ>::Ptr kdtree(new pcl::search::KdTree<pcl::PointXYZ>());
	ne.setSearchMethod(kdtree);
	ne.setRadiusSearch(0.03);
	//存储输出数据
	pcl::PointCloud<pcl::Normal>::Ptr normals(new pcl::PointCloud<pcl::Normal>);
	//使用半径在查询点周围3厘米范围内的所有临近元素
	ne.setRadiusSearch(0.03);
	//计算特征值
	ne.compute(*normals);

	cout << "normal::  width:" << normals->width << "  height: " << normals->height << "  size: " << normals->points.size() << endl;

	//pcl::IntegralImageNormalEstimation<pcl::PointXYZ, pcl::Normal> normal_estimation;
	//normal_estimation.setNormalEstimationMethod(normal_estimation.AVERAGE_3D_GRADIENT);
	//normal_estimation.setMaxDepthChangeFactor(0.02F);
	//normal_estimation.setNormalSmoothingSize(10.0f);
	//normal_estimation.setInputCloud(cloud);
	//normal_estimation.compute(*normals);  // 计算法线

	// 设置搜索方法

	//pcl::KdTreeFLANN<pcl::PointXYZ>::Ptr tree(new pcl::KdTreeFLANN<pcl::PointXYZ>);


	// -----------PFH特征实例化--------- //
	pcl::PFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::PFHSignature125> pfhe;
	pfhe.setInputCloud(cloud_filter2);  // 传入点云
	pfhe.setInputNormals(normals);  // 传入法线
	pcl::search::KdTree<pcl::PointXYZ>::Ptr search_method(new pcl::search::KdTree<pcl::PointXYZ>());
	pfhe.setSearchMethod(search_method);  // 设置近邻搜索方法
	//使用半径在5厘米范围内的所有邻元素。
	//注意:此处使用的半径必须要大于估计表面法线时使用的半径!!!
	pfhe.setRadiusSearch(0.05);  // 设置查询半径

	// 设置输出集
	pcl::PointCloud<pcl::PFHSignature125>::Ptr pfhs(new pcl::PointCloud<pcl::PFHSignature125>);
	// 计算pfh的特征集
	pfhe.compute(*pfhs);

	cout << "PFH:: width: " << pfhs->width << "  height: " << pfhs->height << "  size: " << pfhs->points.size() << endl;

	//pfh可视化
   /*pcl::visualization::PCLHistogramVisualizer view;
   view.setBackgroundColor(0, 0, 0);
   view.addFeatureHistogram(*output, "output", 10);
   view.spinOnce();*/

   // ---------------FPFH实例化------------------//
	pcl::FPFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::FPFHSignature33> fpfh;
	fpfh.setInputCloud(cloud_filter2);
	fpfh.setInputNormals(normals);
	fpfh.setSearchMethod(search_method);
	fpfh.setRadiusSearch(0.05);

	// 设置输出集
	pcl::PointCloud<pcl::FPFHSignature33>::Ptr fpfhs(new pcl::PointCloud<pcl::FPFHSignature33>);
	fpfh.compute(*fpfhs);
	cout << "FPFH::  width:" << fpfhs->width << "  height: " << fpfhs->height << "  size: " << fpfhs->points.size() << endl;
	// -----------------VFH实例化-------------------//
	pcl::VFHEstimation<pcl::PointXYZ, pcl::Normal, pcl::VFHSignature308> vfh;
	vfh.setInputCloud(cloud_filter2);
	vfh.setInputNormals(normals);
	vfh.setSearchMethod(search_method);
	vfh.setRadiusSearch(0.05);

	// 设置VFH输出集
	pcl::PointCloud<pcl::VFHSignature308>::Ptr vfhs(new pcl::PointCloud<pcl::VFHSignature308>);
	vfh.compute(*vfhs);
	cout << "VFH::  width: " << vfhs->width << "  height: " << vfhs->height << "  size: " << vfhs->points.size() << endl;

	// -------------- 点云数据可视化------------- //
	pcl::visualization::PCLVisualizer viewer("可视化");
	viewer.setBackgroundColor(0, 0, 1);
	viewer.addPointCloud<pcl::PointXYZ>(cloud, "cloud");
	// viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "cloud");
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ>(cloud, 0, 1, 0);
	viewer.spinOnce();

	pcl::visualization::PCLPlotter plotter("pfh特征");
	plotter.setWindowName("pfh特征");
	plotter.addFeatureHistogram(*pfhs, 300); //设置的很坐标长度,该值越大,则显示的越细致
	plotter.plot();

	pcl::visualization::PCLPlotter fpfh_plotter("fpfh特征");
	fpfh_plotter.setWindowName("fpfh特征");
	fpfh_plotter.addFeatureHistogram(*fpfhs, 300); //设置的很坐标长度,该值越大,则显示的越细致
	fpfh_plotter.plot();

	pcl::visualization::PCLPlotter vfh_plotter("vfh特征");
	vfh_plotter.setWindowName("vfh特征");
	vfh_plotter.addFeatureHistogram(*vfhs, 300); //设置的很坐标长度,该值越大,则显示的越细致
	vfh_plotter.plot();

	return 0;
}

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 双目相机是利用两个摄像头分别拍摄同一场景,从而获取不同视角下的图像信息,以实现深度信息的获取。三维重建是指通过图像处理技术将拍摄得到的二维图像转化为三维模型的过程。 在实现双目相机三维重建的过程中,可以使用OpenCV和PCL这两个开源库。OpenCV是一款计算机视觉库,提供了许多图像处理和计算机视觉相关的函数和工具,比如图像读取和处理、特征提取和匹配等。PCL是一款点云处理库,能够处理三维点云数据,提供了点云滤波、分割、配准和特征提取等功能。 具体步骤如下: 1. 获取双目相机的图像,进行标定。标定可以校准摄像头对应的内参矩阵和外参矩阵,以保证匹配时的准确度。 2. 通过绝对/相对模板匹配获取左右匹配的特征点。之后可以使用立体匹配算法(例如SGBM算法)计算出匹配点的视差(即左右视图在深度方向上的偏差),根据视差反向计算出点的深度。 3. 将获取的深度点云数据使用PCL进行处理,如点云滤波、重采样、分割等。之后可以使用PCL提供的立体配准算法对左右图像进行配准,基于此获取的点云数据中的关键点,进行特征点匹配,从而实现三维重建。 总之,双目相机三维重建opencv-pcl结合使用能够高效地完成三维重建任务,这是一个较为复杂的过程,需要仔细设计,注意参数设置和优化算法。 ### 回答2: 双目相机三维重建是利用双目相机获取的两幅图像,通过计算机视觉算法对相机观察到的场景进行三维重建的技术。OpenCV是一种开源的计算机视觉库,提供了许多图像处理和计算机视觉算法,PCL(PointCloud Library)则是一种开源的点云处理库,提供了各种点云相关的处理算法。 通过结合OpenCV和PCL,我们可以实现双目相机的三维重建。首先,需要利用OpenCV对双目相机获取的两幅图像进行立体匹配,得到两幅图像中对应像素点的视差。然后,通过视差计算相机与场景物体之间的距离信息,并将其转化为点云数据。最后,利用PCL对点云数据进行处理,实现三维重建。 具体的步骤包括: 1.读取左右相机的图像并进行预处理,包括图像去畸变和校正,以及调整图像的大小和尺度等。 2.使用OpenCV的立体匹配算法对左右相机图像进行匹配,得到像素点的视差图像。 3.通过三角化算法将视差信息转化为深度信息,并将深度信息转换为点云数据。 4.利用PCL对点云数据进行后续处理,包括点云滤波、点云重建和点云配准等。 5.最终得到的结果是场景的三维模型,可以对其进行渲染和可视化等操作。 总之,双目相机的三维重建是一项复杂的技术,在实践过程中需要综合运用计算机视觉、图像处理和点云处理等多个领域的知识和算法,但是对于建模、制造等领域来说,这是一项非常重要的技术。 ### 回答3: 双目相机三维重建是一种利用双目相机获取的视差数据来进行三维物体建模的技术。这种技术可以被应用到多个领域,如机器人导航、自动驾驶、医疗影像等。OpenCV是一个强大的计算机视觉库,支持多种计算机视觉算法和工具,能够方便地进行图像处理、特征提取和目标跟踪。而PCL是点云库,提供了处理点云数据的算法、工具和可视化功能。 实现双目相机三维重建,需要使用OpenCV和PCL。首先,利用双目相机捕获的两幅图像计算出视差图。然后,使用OpenCV提供的函数或者自定义算法,将视差图转换为深度图。接着,利用PCL提供的点云算法,将深度图转换为点云数据。最后,利用PCL的可视化工具,对点云数据进行可视化展示或二次处理。 在使用OpenCV和PCL进行双目相机三维重建时,需要注意几个关键点。首先,在捕获图像前需要进行相机标定,获取相机内参和外参等参数。这是很重要的,因为只有相机准确校准后,才能保证三维建模的精度和稳定性。其次,在计算视差图和深度图时,需要选择适合的计算方法和参数。这些参数可能会受到图像分辨率、灰度分布和光照等因素的影响。最后,在进行点云处理和可视化时,需要选择合适的算法和工具,以免因数据量过大或算法不精确而影响计算效率和准确性。 总之,双目相机三维重建结合OpenCV和PCL,是一种强大的三维重建技术。它可以应用到多个领域,包括机器人导航、自动驾驶、医疗影像等。在实现过程中,需要根据具体实际情况进行合理选择和优化,以保证算法的精度、效率和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值