序言
今天要学习的是在ros-melodic下点云的滤波方法,并使用点云库的可视化工具将其显示出来。
常见的过滤方法有:直通滤波、体素滤波、统计滤波和半径滤波,今天演示统计滤波的代码效果。
一、创建新的cpp文件"pcl_filter.cpp"
在功能包的src目录下新建一个cpp文件,命名为“pcl_filter.cpp”,将下面的代码复制进去。
#include <iostream>
#include <ros/ros.h>
#include <pcl/visualization/cloud_viewer.h>
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/filters/statistical_outlier_removal.h>
class cloudHandler
{
public:
cloudHandler()
: viewer("Cloud Viewer")
{
pcl::PointCloud<pcl::PointXYZ> cloud;
pcl::PointCloud<pcl::PointXYZ> cloud_filtered;
pcl::io::loadPCDFile ("write_pcd_test.pcd", cloud);
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> statFilter;//统计离群值算法
statFilter.setInputCloud(cloud.makeShared());//输入点云
statFilter.setMeanK(10);//均值滤波
statFilter.setStddevMulThresh(0.4);//方差0.4
statFilter.filter(cloud_filtered);//输出结果到点云
viewer.showCloud(cloud_filtered.makeShared());
viewer_timer = nh.createTimer(ros::Duration(0.1), &cloudHandler::timerCB, this);
}
void timerCB(const ros::TimerEvent&)
{
if (viewer.wasStopped())
{
ros::shutdown();
}
}
protected:
ros::NodeHandle nh;
pcl::visualization::CloudViewer viewer;
ros::Timer viewer_timer;
};
main (int argc, char **argv)
{
ros::init (argc, argv, "pcl_filter");
cloudHandler handler;
ros::spin();
return 0;
}
注意,这里我使用的点云文件是前面文章中生成的"write_pcd_test.pcd",路径在工作空间下,这里使用相对路径就可以找到。
二、修改CmakeLists.txt文件并编译
在CmakeLists.txt文件中新加上这些内容
add_executable(pcl_filter src/pcl_filter.cpp)
add_dependencies(pcl_filter ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
target_link_libraries(pcl_filter
${catkin_LIBRARIES}
)
修改后在vscode里面按“Ctrl+shift+b”编译整个功能包。
三、运行程序
启动一个终端,开启roscore
在在工作空间下打开一个终端,分别输入:
source ./devel/setup.bash
rosrun pcl_01 pcl_filter
程序运行起来后,会弹出点云可视化界面
这样就成功了,可以看到,与原始点云相比,现在的点云被过滤了一部分。
四、报错解决
我们按照上面的操作进行编译的时候,系统可能会报错:
pcl::visualization::CloudViewer::showCloud(boost::shared_ptr<pcl::PointCloud<pcl::PointXY...未定义的引用
解决办法就是,修改CmakeLists.txt内容:
target_link_libraries(pcl_filter
${catkin_LIBRARIES} ${PCL_LIBRARIES}
)
这样再编译就应该没问题了。
如果还不能解决,大概率是cmakelists的问题,尝试修改完善就好了