这个代码解决的是一个的接收外部节点发布的图片与点云消息并将他们可视化的问题,本文使用的环境是ubuntu18.04 opencv4.5.4 pcl1.12 vtk8.2
具体代码如下
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace pcl;
void sub1Callback(const sensor_msgs::Image::ConstPtr& msg){
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);
cv::namedWindow("彩色图片",0);
cv::resizeWindow("彩色图片", 900, 900);
cv::imshow("彩色图片",cv_ptr->image);
cv::waitKey(1000);
}
void sub2Callback(const sensor_msgs::Image::ConstPtr& msg){
cv_bridge::CvImagePtr cv_ptr;
cv_ptr = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::TYPE_32FC1);
cv::namedWindow("深度图片",0);
cv::resizeWindow("深度图片",900,900);
cv::imshow("深度图片",cv_ptr->image);
cv::waitKey(1000);
}
void sub3Callback(const sensor_msgs::PointCloud2ConstPtr& msg){
PointCloud::Ptr cloud(new PointCloud);
pcl::fromROSMsg(*msg,*cloud);
visualization::PCLVisualizer viewer("pointcloud");
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud(cloud);
viewer.spinOnce(10);
}
void sub4Callback(const sensor_msgs::PointCloud2ConstPtr& msg){
PointCloud::Ptr cloud(new PointCloud);
pcl::fromROSMsg(*msg,*cloud);
visualization::PCLVisualizer viewer("color_pointcloud");
viewer.setBackgroundColor(0, 0, 0);
viewer.addPointCloud(cloud);
viewer.spinOnce(10);
}
int main(int argc, char** argv) {
//接收相机service发布的信息
pcl::PointCloud::Ptr cloud_xyz(new pcl::PointCloud());
pcl::io::loadPCDFile("/home/hc/mechmind_camera/color_pointcloud.pcd", *cloud_xyz);
ros::init(argc, argv, "receive");
ros::NodeHandle n;
ros::Subscriber sub1 = n.subscribe("/mechmind/color_image", 1, sub1Callback);
ros::Subscriber sub2 = n.subscribe("/mechmind/depth_image",1,sub2Callback);
ros::Subscriber sub3 = n.subscribe("/mechmind/point_cloud",1,sub3Callback);
ros::Subscriber sub4 = n.subscribe("/mechmind/color_point_cloud",1,sub4Callback);
ros::Rate r(100);
while (ros::ok())
{
ros::spinOnce();
r.sleep();
}
return 0;
}
从代码逻辑上看,这段代码是没有任何问题的,但编译也能顺利通过,但一运行就会报段错误,核心已转储,这种bug一般是由于指针错误,数据越界或者别的奇奇怪怪的原因,下面解释debug的过程。
这里定位问题来源,发现是这一句代码的问题
visualization::PCLVisualizer viewer("color_pointcloud");
很奇怪,这是调用官方库进行实例化的语句,不可能会出这样的问题,另外在别的地方都是可以正常运行的,甚至这个功能包中的另一个程序用的就是这段代码,也能正常运行,所以,问题不在这里。用gdb查看栈帧,发现了一个奇怪的现象。
发现,在调用函数时,从源代码指向了pcl1.12的官方代码,又指向了vtk8.2的代码,最后调用了vtk6.3.这就很奇怪了,我没有使用vtk6.3啊,在cmakelist中指定vtk的路径也不对。这里由于vtk和pcl都是用的源码安装,所以如果是编译中漏了哪些包也说不准,但别的地方为什么又可以正常使用呢?
在查询这个问题时,我偶然发现opencv可视化也需要调用vtk库,但我编译安装opencv时从来没有指定vtk的路径,会不会是这个的问题
最后我回过头查询了编译opencv时的逻辑,发现在cmake-gui中确实有指定vtk的位置这一选项
这已经是修改后的结果了,修改前确实是ros自带的vtk6.3,这个问题就这么解决了
具体的操作很简单,就是zaicmake-gui中报这个参数改成你源码安装vtk后,vtk的位置,然后按下面操作在opencv/build目录中按顺序操作
sudo make -j12
sudo make install
这个bug虽然解决起来很简单,但实际上耗费了我三天的时间。主要是由于在这里报错只报一个段错误,更致命的是编译也能顺利通过,很难想到是依赖的问题。最后感谢霍师兄帮我定位到这个bug的原因。
https://blog.csdn.net/m0_59113065/article/details/120944322?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3-120944322-blog-124447952.pc_relevant_blogantidownloadv1&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3-120944322-blog-124447952.pc_relevant_blogantidownloadv1&utm_relevant_index=6
https://blog.csdn.net/m0_48919875/article/details/123863892