1. 程式人生 > >ROS-indigo釋出Mat影象以及解決cv_bridge與OpenCV3.3.1版本不相容問題

ROS-indigo釋出Mat影象以及解決cv_bridge與OpenCV3.3.1版本不相容問題

1、在ROS-indigo中釋出Mat型別的影象

本人近期開始在ROS上研究視覺定位與導航,過程中不免用要到OpenCV庫對影象進行採集和處理。如果我們想把OpenCV中採集或處理以後的Mat格式的影象利用ROS以topic的形式釋出出去,那麼我們就要藉助cv_bridge這個功能包。cv_bridge就像它的名字一樣,是ROS與OpenCV之間連線的橋樑。cv_bridge位於vision_opencv功能包集下的cv_bridge功能包內。

cv_bridge定義了一個CvImage資料類,該型別包括了OpenCV影象、編碼和一個ROS標頭檔案。CvImage準確包含了sensor_msgs/Image具有的資訊,因此可以在兩種表達方式之間切換。

ROS釋出Mat影象的兩種常用方法

(1)讀取本地圖片釋出

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;
  image_transport:
:ImageTransport it(nh); image_transport::Publisher pub = it.advertise("camera/image", 1); cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR); sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg(); ros::Rate loop_rate(5); while (nh.ok()) { pub.publish(msg); ros:
:spinOnce(); loop_rate.sleep(); } }

(2)獲取本地相機或視訊檔案釋出

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#include <cv_bridge/cv_bridge.h>

int main(int argc, char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;
  image_transport::ImageTransport it(nh);
  image_transport::Publisher pub = it.advertise("camera/image", 1);

  cv::VideoCapture TheVideoCapture;
  TheVideoCapture.open(0);
  cv::Mat image;
  char key;

  ros::Rate loop_rate(100);
  while (nh.ok() && key != 27) {
  if(TheVideoCapture.grab()){
    TheVideoCapture.retrieve(image);
    cv_bridge::CvImage out_msg;
    out_msg.header.stamp = ros::Time::now();
    out_msg.encoding = sensor_msgs::image_encodings::BGR8;
    out_msg.image = image;
    pub.publish(out_msg.toImageMsg());
    // cv::imshow("image", image);
    key = cv::waitKey(1);
  }
  loop_rate.sleep();
}

以上兩塊程式碼都需要新增依賴image_transport和cv_bridge(如何新增依賴這裡不再贅述,個人認為在Roboware_Studio裡面比較好操作),如果不出現OpenCV版本相容的問題,編譯完成後它們都是可以以ROS節點的形式正常執行的。但是不幸的是,博主在一開始用第二種方法釋出topic的時候就遇到了cv_bridge與OpenCV3不相容的問題,導致程式無法執行,下面介紹一種解決該問題的方法。

2、對ROS-indigo中OpenCV版本不相容問題的一種解決方法

由於某些原因,博主需要用到OpenCV3以上的版本,但據網上介紹說ROS-indigo版本中的cv_bridge好像預設是依賴OpenCV2.4.8編譯的,所以通常會與我們自己安裝的較高版本的OpenCV3產生一些衝突。但是我又不想換高版本的ROS,所以,在網上翻閱大神們的解決方案,說可以解除安裝預設安裝的cv_bridge,重新編譯安裝。鄙人試了一下,果然解決了我的問題,現將該方法總結一下,供大家參考。

  • Step1:

首先確保你的Ubuntu已正確安裝了OpenCV3某版本,並可以find到它的安裝路徑,不然 cv_bridge 是無法編譯的。你可以嘗試在終端執行以下命令來檢視當前系統安裝的OpenCV版本。

$ pkg-config --modversion opencv

正常情況下它會顯示你的OpenCV版本號,比如博主的執行結果為:

$ 3.3.1
  • Step2:

解除安裝ROS-indigo預設安裝的cv_bridge,在終端執行命令:

$ sudo apt-get remove ros-indigo-cv-bridge

敲完命令列回車輸入使用者密碼,我們會發現系統提示說要解除安裝好多軟體包,這是因為我們在解除安裝cv_bridge功能包時,其他所有依賴於它的功能包也要同時被解除安裝,不然cv_bridge沒了這些功能包也就沒法用了(我是這麼理解的)。不過不用擔心,卸完以後我們還可以再編譯安裝嘛,所以,輸入 y 敲回車狠心解除安裝。

  • Step3

解除安裝完cv_bridge我們就要去GitHub上下載原始碼自己編譯了(indigo版本的原始碼地址在這裡),我們也可以通過命令列下載。博主預設親們至少已經有了自己的一個ROS工作空間,我的 ~/catkin_ws 工作空間就是專門用來編譯重灌ROS原始碼的,所以我的命令列如下:

$ cd ~/catkin_ws/src
$ git clone https://github.com/ros-perception/vision_opencv.git --branch=indigo
$ cd ..
$ catkin_make

以上工作空間可自行修改,正常情況下編譯不會出現問題,除非你的OpenCV安裝有錯誤。如果沒有 source 過你的工作空間的要把工作空間中的 devel/setup.bash 新增到 ~/.bashrc 中,以我的為例:

$ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
  • Step4

因為前面在解除安裝 cv_bridge 時把依賴於它的其他很多功能包也同時解除安裝了,導致很多功能無法使用,比如我經常要用到的 image_view 功能包,所以,現在就要把其他的功能包用同樣的方法也裝上。我們可以通過在ROS官網查詢 image_view 來定位它的原始碼地址,在這裡可以發現,image_view其實是功能包集image_pipeline中的一個功能包,所以我們直接把 image_pipeline下載下來編譯安裝就行了(前面一併解除安裝的其他功能包大部分都在這個功能包集裡面)。

$ cd ~/catkin_ws/src
$ git clone https://github.com/ros-perception/image_pipeline --branch=indigo
$ cd ..
$ catkin_make
  • Step5

至此,cv_bridge 與 OpenCV3 的版本相容問題基本已經解決了,還有其他一些卸掉的功能包,用到的時候可以用上述同樣的方法再安裝。鄙人的方法可能不是太好,如果大神們有更好的解決方案,希望不吝賜教!

參考連結