1.建立ROS工作環境
mkdir -p ~/catkin_ws/src //建立項目目錄,同時生成src文件夾
cd ~/catkin_ws/ //進入項目目錄
catkin_make //編譯項目,即使什么文件也沒有也可以編譯
2.建立包
本例中包名為“opencvExercise”
cd ~/catkin_ws/src
catkin_create_pkg opencvExercise std_msgs rospy roscpp cv_bridge sensor_msgs image_transport
3.源代碼封裝
#include <ros/ros.h>
#include<image_transport/image_transport.h>
#include<cv_bridge/cv_bridge.h>
#include<sensor_msgs/image_encodings.h>
#include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
#include<stdio.h>
#include<math.h>
#include<vector>
using namespace std;
cv_bridge::CvImagePtr cv_ptr;
using namespace cv;
class ImageConverter
{
private:
ros::NodeHandle nh_;
//用於將msg信息轉換為openCV中的Mat數據
image_transport::ImageTransport it_;
//訂閱攝像頭發布的信息
image_transport::Subscriber image_sub_;
public:
ImageConverter()
: it_(nh_)
{
//設置訂閱攝像機
image_sub_ = it_.subscribe("/usb_cam/image_raw", 1, &ImageConverter::imageCb, this);
}
~ImageConverter(){
}
//收到攝像機后的回調函數
void imageCb(const sensor_msgs::ImageConstPtr& msg){
try{
//將收到的消息使用cv_bridge轉移到全局變量圖像指針cv_ptr中,其成員變量image就是Mat型的圖片
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e){
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
//處理圖片信息
myCode();
}
//你的代碼可以移植在此處
int myCode(){
Mat img=cv_ptr->image;
cv::imshow("win",img);
return 0;
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_converter");
ImageConverter ic;
//循環等待
ros::spin();
return 0;
}
需要注意的是ROS中發布的消息是不支持圖片的,所以需要image_transport的支持。但是這個包和openCV的格式不兼容,所以需要cv_bridge做格式變換。最后照相機發布的消息類型是sensor_msgs包中的。
4.CMakeLists.txt
添加在文件末尾
FIND_PACKAGE( OpenCV REQUIRED )
AUX_SOURCE_DIRECTORY(src/. DIR_SRCS)
ADD_EXECUTABLE(cylinder ${DIR_SRCS} )
target_link_libraries(cylinder ${catkin_LIBRARIES})
target_link_libraries(cylinder ${OpenCV_LIBRARIES} )