ros下使用源码安装的pcl与opencv可视化出现“段错误,核心已转储”

背景 :

这个代码解决的是一个的接收外部节点发布的图片与点云消息并将他们可视化的问题,本文使用的环境是ubuntu18.04 opencv4.5.4 pcl1.12 vtk8.2
具体代码如下

#include <ros/ros.h>
#include <iostream>
#include <image_transport/image_transport.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgcodecs.hpp>
#include <cv_bridge/cv_bridge.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/conversions.h> 
#include <pcl/visualization/cloud_viewer.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>

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<PointXYZ>::Ptr cloud(new PointCloud<PointXYZ>);
    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<PointXYZRGB>::Ptr cloud(new PointCloud<PointXYZRGB>);
    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<pcl::PointXYZRGB>::Ptr cloud_xyz(new pcl::PointCloud<pcl::PointXYZRGB>());
     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查看栈帧,发现了一个奇怪的现象。

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值