使用Eclipse實現USB Camera的ROS Publisher

USB Camera ROS Publisher

現在完成自己的第一個工程.由於之前在網上尋找過關於USB Camera在ROS中的數據採集方法.找了很久一直沒有找到一個比較有用的資料.所以想將其作爲自己的第一個程序.獲取USB Camera採集到的圖像,然後發佈出來.編寫一個數據採集的節點.

1. 創建ROS Package

依次執行下述命令:
        $ roscd
        $ cd camera
        $ roscreate-pkg usbcamera_pub sensor_msgs image_transport cv_bridge roscpp

這個時候完成package創建,並添加附加依賴項sensor_msgs, image_transport, cv_bridge.詳見圖1.
圖1:   創建usbcamera_pub包
圖1: 創建usbcamera_pub包

2. 導入ROS Package到Eclipse

(這部分內容與前一篇重複)現在ls可以看到我們新建的包文件夾 usbcamera_pub. cd到該文件夾內,然後執行下述命令.

        $ cd usbcamera_pub
        $ make eclipse-project
        $ cd ..
        $ rosmake --target=eclipse-project --specified-only *

圖2:   爲你的packages or stacks編譯一些Eclipse文件
圖2: 爲你的packages or stacks編譯一些Eclipse文件

現在打開Eclipse, 點擊 File → Import → Existing Projects into Workspace → Next → Browse,選擇上述我們新建的Package目錄,點擊Finish.現在可以在Eclipse中看到我們新建的Package了.詳見圖3.可以看見,現在src文件夾和bin文件夾均是空文件夾.

3. 編寫USB Camera節點代碼

首先,我們需要完成一些配置工作.首先打開CMakeList.txt, 在該文件的最後添加下述文字.

        find_package(OpenCV)
        include_directories(${OpenCV_INCLUDE_DIRS})

對於任何第三方package, 均需在CMakeList.txt中添加find_package.在這兒我們添加OpenCV的庫,不用自己配,加入這兩句話即可.OpenCV的庫在安裝ROS的時候已經安裝到Ubuntu上.其中還會用到ROS提供的另外一個工具cv_bridge.前面我們在新建Package的時候已經添加了該附加依賴項.cv_bridge所實現的功能很重要,從名字中就可以看出來,它就是提供一個ROS和OpenCV之間的一座橋樑.見圖4.如果你想了解更多,請參閱http://wiki.ros.org/vision_opencv

圖3:   導入Eclipse之後文件結構
圖3: 導入Eclipse之後文件結構

圖4:   cv_bridge的作用
圖4: cv_bridge的作用

現在鼠標右鍵點擊src → New → Source File, 輸入usb_cam_pub.cpp,點擊Finish.然後將下述代碼複製到文件中.代碼很簡單,我就步一一解釋了.該代碼原作者是一個大三的小學妹.大部分工作都是她完成的.我只是做了總結而已.

/*
 * usb_cam_pub.cpp
 *
 *  Created on: Apr 28, 2015
 *      Author: burial
 */
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

int main(int argc, char **argv )
{
  // 初始化,函數聲明
  ros::init(argc, argv, "usbcamer_pub" );
  ros::NodeHandle nodeHandler;
  image_transport::ImageTransport imageTransport(nodeHandler);

  std_msgs::Header header;
  cv::Mat frame;
  cv::VideoCapture videoCapture(0);

  image_transport::Publisher imgPub = imageTransport.advertise("/usb_camera/rgb8", 1);

  while (ros::ok())
  {
    if (videoCapture.isOpened()) // 如果攝像頭開啓,處理圖像轉化爲ros image message
    {
      videoCapture >> frame;
      cv_bridge::CvImage cvImage(header, sensor_msgs::image_encodings::RGB8, frame); // 利用cvbridge 將圖像信息轉化爲rosmessage
      imgPub.publish(cvImage.toImageMsg()); // 發佈消息
    }

    ros::spinOnce();
  }

  return 0;
}

現在打開CMakeList.txt將下述文字複製到文件的最後.

rosbuild_add_executable(usb_cam_pub src/usb_cam_pub.cpp)

然後,點擊 Project → Build All.編譯結束,你會發現bin文件夾裏多出來一個文件.這就是生成的可執行文件.見圖5.
圖5:   編譯結束後工程目錄
圖5: 編譯結束後工程目錄

這個節點不同於之前那個節點.上一個示例節點,可以通過Eclipse直接運行.並且可以在Console中看見輸出內容.這個節點編譯完成後,在Eclipse中運行總是會提示運行錯誤.但是在Terminal中運行就沒有任何錯誤.我也沒弄明白到底是爲什麼.錯誤輸出建圖6.嘗試很多方法均未能修復這個錯誤.所以也只有放棄,編譯完成後在Terminal中運行該節點.
圖6:   在Eclipse中運行所提示錯誤
圖6: 在Eclipse中運行所提示錯誤

4. 運行USB Camera節點

現在打開Terminal, 運行 $ roscore, 在打開一個Terminal, 執行 $ rosrun usbcamera_pub usb_cam_pub .如果提示未找到usbcamera_pub包的話,說明你沒有執行 $ source ~/workspace/ROS/setup.bash .在Terminal中輸入該命令,再運行節點.
現在是見證奇蹟的時刻了.再打開一個Terminal, 輸入 $ rosrun rviz rviz, 會彈出ROS 的一個可視化工具rviz.在左邊工具欄中點擊Add.
圖7:   ROS RVIZ工具點擊Add
圖7: ROS RVIZ工具點擊Add

選擇Image, 點擊確定.左邊工具欄出現Image條目.展開後如圖8展示.在Topic選項中選擇 /usb_camera/rgb8,就可看到當前Image窗口中顯示出當前攝像頭所採集到的畫面了.

圖8:   選擇Image後Rviz所示圖
圖8: 選擇Image後Rviz所示圖

5. 後期工作

或許你對上圖中圖像顏色有疑問.這是由於我們在轉換的時候是以rgb8的方式編碼.在源碼中可看到.而現在是以raw的方式顯示的.故有這樣的問題.後期再編輯自己的Subsciber接收圖像,然後顯示,就不會出現這樣的顏色問題了.
另外,從源碼中可以看到,當前是從運行該節點開始,我們就使用VideoCapture類獲得攝像頭控制權,然後獲取圖像開始Publish, 不管是否有節點訂閱了該Topic.這一點應該是可以再進行完善的.在有節點訂閱我們的Topic後開始開啓攝像頭,Publish圖像Message.

發佈了26 篇原創文章 · 獲贊 106 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章