个人学习总结,留作日后参考,可能会有错误。
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;
}
参考: