在ROS发布与订阅显示Android相机图像消息1-test例程(Ubuntu 16.04+ROS_Kinetic+OpenCV 3)

最近一直尝试将ROS系统加入到各个项目当中,尝试自己来写出可供发布的Example

这篇博客也是对ROS工程编译的一次记录。

既然我们想要对相关图像进行显示和处理,那么OpenCV就是一个不可避免的强大助手。而ROS的图像消息格式和OpenCV之间的消息格式也是通过ROS的一个功能包cv_bridge来实现的

在ROS发布与订阅显示Android相机图像消息1-test例程(Ubuntu 16.04+ROS_Kinetic+OpenCV 3)

有关cv_bridge的相关简介可以参看ROS的官方文档.

1.首先创建工作空间并进入

cd mkdir_ws/src
catkin_create_pkg image_test image_transport cv_bridge

这里用catkin_create_pkg指令直接生成相关项目,并配置依赖项image_transport和cv_bridge。

然后编译该功能包image_test

cd ..
catkin_make

catkin_make 默认编译工作空间下的所有功能包,如果想要编译特定的功能包,可以用以下任一指令均可:

catkin_make -DCATKIN_WHITELIST_PACKAGES="package1;package2"

catkin_make --pkg package_name

设置环境源

source devel/setup.bash

2.编写测试源码

进入目录

catkin_ws/src/image_test
mkdir src
cd src

创建源码,my_sub.cpp

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


using namespace cv;
using namespace std;
 
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
  try
  {
    imshow("view", cv_bridge::toCvShare(msg, "bgr8")->image);
  }
  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;
  cvNamedWindow("view");
  //startWindowThread();
  image_transport::ImageTransport it(nh);
  image_transport::Subscriber sub = it.subscribe("camera/image", 1, imageCallback);
  ros::spin();
}

注意这里ROS中自带的OpenCV3.3.1 所以编写源码的时候要注意一下。

然后CMakeLists.txt

cmake_minimum_required(VERSION 2.8.3)
project(my_image_transport)


## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)

## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  cv_bridge
  image_transport

)

find_package(OpenCV REQUIRED)

catkin_package()


include_directories(
# include
  ${catkin_INCLUDE_DIRS}
  ${OpenCV_INCLUDE_DIRS}
)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})
add_executable(my_subscriber src/my_subscriber.cpp)
target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})


#build my_publisher and my_subscriber
add_executable(my_publisher src/my_publisher.cpp)
target_link_libraries(my_publisher ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})
 
#add_executable(my_subscriber my_subscriber.cpp)
#target_link_libraries(my_subscriber ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})


然后返回编译,就ok啦

这里有两个点

catkin_package()要在find_package()之后。

加入语句set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR})

这样编译生成的可执行文件会在image_test目录下

否则在我电脑上可执行文件生成在image_test/build/devel/lib/image_tst/下

执行rostun时路径制定非常不方便。

但是如果在image_test目录下 直接执行

rosrun my_image_transport my_subscriber

就完成啦