要件: 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());
}
}
人は牡丹だと言いますが、お釈迦様は花矢だと言います。人を骨の髄まで撃ち抜き、文句も言わずに死ぬ。