ROS は Image トピックをサブスクライブし、それを OpenCV イメージに変換します

要件: Realsense カメラによってリリースされたトピックから rgb 画像と深度画像を取得し、後続の処理を実行します。cv_bridge クラスは、ROS と OpenCV 画像形式間の変換を支援するために ROS で提供されています。

サブスクライバーは、image_transport を使用してオブジェクトを定義し、次に 2 つのサブスクライバー オブジェクトを定義する必要があります。これらのオブジェクトは、それぞれ rgb トピックと深度トピックをコールバックするために使用されます。

	// 初始化ros节点
    ros::init(argc, argv, "RGBD");
    // 创建ros节点句柄
    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    // 回调函数队列长度为x,因此spinOnce每次执行完队列函数,相当于每x帧取1帧
    image_transport::Subscriber rgb_sub = it.subscribe("rgb", 1, rgbCallback);
    image_transport::Subscriber depth_sub = it.subscribe("depth", 1, depthCallback);

cv_bridge が ROS イメージ メッセージを OpenCV イメージ形式に変換するとき、それは CvImage クラスを通じて実装されます。一般に、cv_bridge は CvImage クラスに変換する 2 つの方法、つまりコピーと共有を提供します。

  • toCvCopy 関数は、ROS メッセージから画像データをコピーします。CvImage クラスの内容がどのように変更されても、ソース データは影響を受けません。
  • toCvShare 関数は、ソースとエンコーディングの両方が一致する場合、返された OpenCV ポインターを ROS のメッセージ、つまり共有ポインターにポイントします。その特徴は、返された CvImage クラスのコピーを保持している限り、ROS メッセージ タイプは解放されないことです。

CvBridge で一般的に使用されるエンコーディングは次のとおりです。

  • mono8: CV_8UC1、グレースケール画像

  • mono16: CV_16UC1、16 ビット グレースケール画像

  • bgr8: CV_8UC3、青、緑、赤の色の順序を持​​つカラー画像

  • rgb8: CV_8UC3、赤、緑、青の色の順序を持​​つカラー画像

  • bgra8: CV_8UC4、アルファ チャネル付き BGR カラー イメージ

  • rgba8: CV_8UC4、アルファ チャネル付きの RGB カラー イメージ

cv_bridge::toCvShare(msg, "bgr8")msg を CV_8UC3 イメージに変換し、msg への共有ポインタを取得します。->imageつまり、イメージを取得します。形式は cv::Mat です。浅いコピーとして理解できます。

rgb = cv_bridge::toCvShare(msg, "bgr8")->image;

cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)また、msg を CV_8UC3 イメージに変換しますが、cv::Mat 形式の変換されたイメージのみを指します。ディープコピーとして理解できます。

cv::Mat rgb;
cv::Mat depth;

// rgb图像的回调函数,当有图像消息到达rgb时,就会被调用
void rgbCallback(const sensor_msgs::ImageConstPtr& msg) {
    
    
    try {
    
               
        // ROS图像消息——>OpenCV图像
        rgb = cv_bridge::toCvShare(msg, "bgr8")->image;
        // cv::imshow("image", rgb);
        // cv::waitKey(50);
        // cout << "I have received rgb image!" << endl;
        // rgb = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8)->image;
        
    } catch(cv_bridge::Exception& e) {
    
    
        ROS_ERROR("Could not convert from '%s' to 'bgr8'.", msg->encoding.c_str());
    }
}

// depth深度图像的回调函数
void depthCallback(const sensor_msgs::ImageConstPtr& msg) {
    
    
    try {
    
               
        // ROS图像消息——>OpenCV图像
        depth = cv_bridge::toCvShare(msg, "mono16")->image;
        // cout << "I have received depth image!" << endl;
    } catch(cv_bridge::Exception& e) {
    
    
        ROS_ERROR("Could not convert from '%s' to 'mono16'.", msg->encoding.c_str());
    }
}

人は牡丹だと言いますが、お釈迦様は花矢だと言います。人を骨の髄まで撃ち抜き、文句も言わずに死ぬ。

おすすめ

転載: blog.csdn.net/qq_42257666/article/details/131492112