ROS中利用OpenCV处理图像信息

个人学习总结,留作日后参考,可能会有错误。

1、 cv_bridge

在编译程序时提示

Could not find a package configuration file provided by "cv_bridge" with any of the following names:
	
    cv_bridgeConfig.cmake
    cv_bridge-config.cmake
 Add the installation prefix of "cv_bridge" to CMAKE_PREFIX_PATH or set"cv_bridge_DIR" to a directory containing one of the above files.  If
  "cv_bridge" provides a separate development package or SDK, be sure it has been installed.

安装 cv_bridge

sudo apt-get install ros-kinetic-cv-bridge

安装 cv_bridge 时会安装 ros-kinetic-opencv3

经粗略测试,ros-kinetic-opencv3与从官网下载OpenCV的源码经过编译生成的库 在imshow()上有一些不同,应该注意。

2 imshow()函数

参考:https://blog.csdn.net/a435262767/article/details/84490975

3、配置文件

CMakeLists.txt

find_package(catkin REQUIRED COMPONENTS
  cv_bridge
  image_transport
  roscpp
  sensor_msgs
  std_msgs
  OpenCV
)
include_directories(${catkin_INCLUDE_DIRS})

add_executable(publishImage src/pub_Image.cpp)
add_executable(subscribImage src/sub_Image.cpp)

add_dependencies(publishImage ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
add_dependencies(subscribImage ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})


target_link_libraries(publishImage ${catkin_LIBRARIES})
target_link_libraries(subscribImage ${catkin_LIBRARIES})

# make 编译时输出 OpenCV库 版本号及路径
message(STATUS "opencv version: ${OpenCV_VERSION}")
message(STATUS "opencv dir: ${OpenCV_INCLUDE_DIRS}")

 输出的 OpenCV库 版本号及路径为

 OpenCV为ros自带的opencv库,如果要使用自己编译生成的opencv库需要特别设置。

package.xml

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>cv_bridge</build_depend>
  <build_depend>image_transport</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>cv_bridge</build_export_depend>
  <build_export_depend>image_transport</build_export_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>cv_bridge</exec_depend>
  <exec_depend>image_transport</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>
  <exec_depend>std_msgs</exec_depend>

 4、源码

pub_Image.cpp

#include <ros/ros.h>  
#include<sensor_msgs/image_encodings.h> //ROS图象类型的编码函数
#include<image_transport/image_transport.h> //用来在ROS系统中的话题上发布和订阅图象消息

//OpenCV2标准头文件
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<cv_bridge/cv_bridge.h>     //cv_bridge中包含CvBridge库

#include<iostream> //C++标准输入输出库
using namespace std;

//图片存放路径 (绝对路径)
string filepath = "/work/catkin_ws/src/opcv_ros/src/1.png";

int main(int argc, char *argv[])
{
    ros::init(argc, argv, "publishImage");

    ros::NodeHandle nh;
    image_transport::ImageTransport it(nh);
    //设置发布主题 camera/image
    image_transport::Publisher pub = it.advertise("camera/image",1);
    //读取图片
    cv::Mat image = cv::imread(filepath,CV_LOAD_IMAGE_COLOR);
    //判断是否正确读取图片
    if (image.data == nullptr)
    {
         cerr << "文件" << filepath << "不存在。" << endl; 
         return -1;
    }
    //格式转换
    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(),"bgr8",image).toImageMsg();

    //1s 发布一次
    ros::Rate loop_rate(1);
    while (nh.ok())
    {
        pub.publish(msg);
        cout << "publishImage is runing !" << endl;
        loop_rate.sleep();
    }
    return 0;
}

sub_Image.cpp

#include <ros/ros.h>  
#include<sensor_msgs/image_encodings.h> //ROS图象类型的编码函数
#include<image_transport/image_transport.h> //用来在ROS系统中的话题上发布和订阅图象消息

//OpenCV2标准头文件
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<cv_bridge/cv_bridge.h>     //cv_bridge中包含CvBridge库

#include<iostream> //C++标准输入输出库
using namespace std;

//消息订阅回调函数
void subImage_cb(const sensor_msgs::ImageConstPtr& msg)
{
    try
    {
        cout << " receive success " << endl;
        cv::imshow("image",cv_bridge::toCvShare(msg,"bgr8")->image);
        cv::waitKey(10);//因为highgui处理来自cv::imshow()的绘制请求需要时间 10代表10ms
    }
    catch (cv_bridge::Exception& e)
    {
        cout << "Could not convert from " << msg->encoding.c_str() << "to 'brg8'." << endl;
    }
    
}

int main(int argc, char *argv[])
{
    ros::init(argc, argv, "subscribImage");

    ros::NodeHandle nh;//创建句柄
    image_transport::ImageTransport it(nh);

    //好像在 ros自带的opencv 中不起作用
    // cv::namedWindow("image");//新建一个显示窗口 窗口名字image。
    // cv::startWindowThread(); //开一个线程

    //设置订阅主题 camera/image
    image_transport::Subscriber sub = it.subscribe("camera/image",1,subImage_cb);

    ros::spin();

    //如果新建窗口image,则需要关闭窗口image
    // cv::destroyWindow("image");
    return 0;
}

参考:

https://blog.csdn.net/u010925447/article/details/80033288

https://blog.csdn.net/sansanjinli/article/details/102998069

发布了24 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/CSDNZSX/article/details/104206444