生活随笔
收集整理的這篇文章主要介紹了
在ROS中使用USB网络摄像头传输图像
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
轉(zhuǎn)自:http://blog.csdn.net/yake827/article/details/44983093
在上節(jié)已經(jīng)實現(xiàn)了單張圖片的ROS實現(xiàn),而在現(xiàn)實中,我們一般是使用攝像頭來獲取圖像,這次要實現(xiàn)在ROS中使用攝像頭傳輸圖像,我使用的是羅技的usb網(wǎng)絡(luò)攝像頭,首先我們需要獲取攝像頭的型號,如下所示:
[plain]?view plaincopy
yake@yake-K42JE:~$?lsusb?? Bus?001?Device?001:?ID?1d6b:0002?Linux?Foundation?2.0?root?hub?? Bus?002?Device?001:?ID?1d6b:0002?Linux?Foundation?2.0?root?hub?? Bus?001?Device?002:?ID?8087:0020?Intel?Corp.?Integrated?Rate?Matching?Hub?? Bus?002?Device?002:?ID?8087:0020?Intel?Corp.?Integrated?Rate?Matching?Hub?? Bus?001?Device?003:?ID?04f2:b1e5?Chicony?Electronics?Co.,?Ltd??? Bus?002?Device?003:?ID?046d:c058?Logitech,?Inc.?M115?Mouse?? Bus?002?Device?008:?ID?046d:0825?Logitech,?Inc.?Webcam?C270??
我所使用的是羅技的C270網(wǎng)絡(luò)攝像頭.接下來我們要為攝像頭安裝驅(qū)動,我使用的是cheese點擊打開鏈接,這個驅(qū)動的好處是在ubuntu環(huán)境下直接apt-get獲得
[plain]?view plaincopy
yake@yake-K42JE:~$?sudo?apt-get?install?cheese??
安裝完成后,插上攝像頭可以發(fā)現(xiàn)在dev/目錄下多了一個viedo0的設(shè)備,這個說明攝像頭驅(qū)動已經(jīng)安裝完成.接下來開始在ROS中使用它.使用的方式是通過opencv函數(shù)來實現(xiàn).
首先還是要創(chuàng)建一個包,寫一個驅(qū)動攝像頭的文件,命名為my_publisher.cpp,作用是獲取圖像并打包成ros格式發(fā)送出去,創(chuàng)建包的方法與單張圖片一樣,my_publisher.cpp內(nèi)容如下:
[plain]?view plaincopy
#include?<ros/ros.h>?? #include?<image_transport/image_transport.h>?? #include?<opencv2/highgui/highgui.hpp>?? #include?<cv_bridge/cv_bridge.h>?? #include?<sstream>?//?for?converting?the?command?line?parameter?to?integer?? ?? int?main(int?argc,?char**?argv)?? {?? ??//?Check?if?video?source?has?been?passed?as?a?parameter?? ??if(argv[1]?==?NULL)??? ????{?? ????????????ROS_INFO("argv[1]=NULL\n");?? ????????return?1;?? ????}?? ?? ??ros::init(argc,?argv,?"image_publisher");?? ??ros::NodeHandle?nh;?? ??image_transport::ImageTransport?it(nh);?? ??image_transport::Publisher?pub?=?it.advertise("camera/image",?1);?? ?? ??//?Convert?the?passed?as?command?line?parameter?index?for?the?video?device?to?an?integer?? ??std::istringstream?video_sourceCmd(argv[1]);?? ??int?video_source;?? ??//?Check?if?it?is?indeed?a?number?? ??if(!(video_sourceCmd?>>?video_source))??? ??{?? ??????ROS_INFO("video_sourceCmd?is?%d\n",video_source);?? ??????return?1;?? ??}?? ?? ??cv::VideoCapture?cap(video_source);?? ??//?Check?if?video?device?can?be?opened?with?the?given?index?? ??if(!cap.isOpened())??? ??{?? ??????ROS_INFO("can?not?opencv?video?device\n");?? ??????return?1;?? ??}?? ??cv::Mat?frame;?? ??sensor_msgs::ImagePtr?msg;?? ?? ??ros::Rate?loop_rate(5);?? ??while?(nh.ok())?{?? ????cap?>>?frame;?? ????//?Check?if?grabbed?frame?is?actually?full?with?some?content?? ????if(!frame.empty())?{?? ??????msg?=?cv_bridge::CvImage(std_msgs::Header(),?"bgr8",?frame).toImageMsg();?? ??????pub.publish(msg);?? ??????//cv::Wait(1);?? ????}?? ?? ????ros::spinOnce();?? ????loop_rate.sleep();?? ??}?? }??
再寫一個my_subscriber.cpp,作用是獲取ROS圖像并顯示,內(nèi)容如下:
[plain]?view plaincopy
#include?<ros/ros.h>?? #include?<image_transport/image_transport.h>?? #include?<opencv2/highgui/highgui.hpp>?? #include?<cv_bridge/cv_bridge.h>?? ?? void?imageCallback(const?sensor_msgs::ImageConstPtr&?msg)?? {?? ??try?? ??{?? ????cv::imshow("view",?cv_bridge::toCvShare(msg,?"bgr8")->image);?? ???//?cv::WaitKey(30);?? ??}?? ??catch?(cv_bridge::Exception&?e)?? ??{?? ????ROS_ERROR("Could?not?convert?from?'%s'?to?'bgr8'.",?msg->encoding.c_str());?? ??}?? }?? ?? int?main(int?argc,?char?**argv)?? {?? ??ros::init(argc,?argv,?"image_listener");?? ??ros::NodeHandle?nh;?? ??cv::namedWindow("view");?? ??cv::startWindowThread();?? ??image_transport::ImageTransport?it(nh);?? ??image_transport::Subscriber?sub?=?it.subscribe("camera/image",?1,?imageCallback);?? ??ros::spin();?? ??cv::destroyWindow("view");?? }??
接下來要把設(shè)計到的各種包和opencv在CmakeList中聲明一下,添加以下語句
[plain]?view plaincopy
find_package(OpenCV?REQUIRED)?? #?add?the?publisher?example?? add_executable(my_publisher?src/my_publisher.cpp)?? ?? target_link_libraries(my_publisher?${catkin_LIBRARIES}?${OpenCV_LIBRARIES})?? ?? #?add?the?subscriber?example?? add_executable(my_subscriber?src/my_subscriber.cpp)?? target_link_libraries(my_subscriber?${catkin_LIBRARIES}?${OpenCV_LIBRARIES})??
將這個包進行編譯
[plain]?view plaincopy
yake@yake-K42JE:~/ros_ws$?catkin_make??
編譯過程可能會出現(xiàn)錯誤,其中一個就是cv::WaitKey不能識別,這個問題到最后依然沒有解決,我是直接把它注釋掉,這樣也沒什么影響.接下來開始運行程序,首先啟動ROS.
[plain]?view plaincopy
yake@yake-K42JE:~$?roscore??
運行my_publisher節(jié)點.(如果運行不起來,需要先source devel/setup.bash)
[plain]?view plaincopy
yake@yake-K42JE:~/video_ros$?rosrun?learning_image_transport?my_publisher?0??
這時候會看到我們的攝像頭燈已經(jīng)亮起來了,0代表默認(rèn)攝像頭,如果有多個攝像頭,則第二個是1,依次類推.
接下來運行my_subscriber節(jié)點來接收圖像
[plain]?view plaincopy
yake@yake-K42JE:~/video_ros$?rosrun?learning_image_transport?my_subscriber??
這時候如果沒有錯誤的話就會彈出圖像窗口
可以看到我們攝像頭傳輸出來的圖像,到此,整個程序結(jié)束!
總結(jié)
以上是生活随笔為你收集整理的在ROS中使用USB网络摄像头传输图像的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。