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包
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文件
現在打開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之後文件結構
圖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: 編譯結束後工程目錄
這個節點不同於之前那個節點.上一個示例節點,可以通過Eclipse直接運行.並且可以在Console中看見輸出內容.這個節點編譯完成後,在Eclipse中運行總是會提示運行錯誤.但是在Terminal中運行就沒有任何錯誤.我也沒弄明白到底是爲什麼.錯誤輸出建圖6.嘗試很多方法均未能修復這個錯誤.所以也只有放棄,編譯完成後在Terminal中運行該節點.
圖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
選擇Image, 點擊確定.左邊工具欄出現Image條目.展開後如圖8展示.在Topic選項中選擇 /usb_camera/rgb8,就可看到當前Image窗口中顯示出當前攝像頭所採集到的畫面了.
圖8: 選擇Image後Rviz所示圖
5. 後期工作
或許你對上圖中圖像顏色有疑問.這是由於我們在轉換的時候是以rgb8的方式編碼.在源碼中可看到.而現在是以raw的方式顯示的.故有這樣的問題.後期再編輯自己的Subsciber接收圖像,然後顯示,就不會出現這樣的顏色問題了.
另外,從源碼中可以看到,當前是從運行該節點開始,我們就使用VideoCapture類獲得攝像頭控制權,然後獲取圖像開始Publish, 不管是否有節點訂閱了該Topic.這一點應該是可以再進行完善的.在有節點訂閱我們的Topic後開始開啓攝像頭,Publish圖像Message.