现在我们已经学会了如何在ros网络里发布图像消息.现在我们同样可以用类似的方法发布视频消息,下面我们以从摄像头获取视频数据为例进行简单的讲解,当然你也可以读取视频文件再发布出去.
3通过摄像头获取图像
3.1修改发布者程序
首先,我们先修改相应的头文件,
将my_publisher.cpp
中的#include "opencv2/highgui/highgui.hpp"
修改为#include <opencv2/opencv.hpp>
然后,在main函数中的前四行保持不变,
ros::init(argc, argv, "video_transp");
ros::NodeHandle nh;
image_transport::ImageTransport it(nh);
image_transport::Publisher pub = it.advertise("camera/image", 1);
接着,将读取图像文件改为从摄像头获取图像,这里我们默认读取第一个摄像头.
old
cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR);
new
cv::VideoCapture cap(0);
下面就有些复杂了,我们来详细地解释一下,下面是相应的代码,
old
sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", image).toImageMsg();
ros::Rate loop_rate(5);
while (nh.ok()) {
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
new
cv::Mat frame;
sensor_msgs::ImagePtr frame_msg;
ros::Rate loop_rate(5);
while(ros::ok())
{
cap >> frame;
if (!frame.empty())
{
frame_msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
pub.publish(frame_msg);
cv::waitKey(1);
}
ros::spinOnce();
loop_rate.sleep();
}
在传递图像时由于只是传递一幅图像,因此不必将图像转化那步放到循环中,只要转化一次就可以了;但是传递视频消息就不同了,我们必须将获取到的每一帧图像都通过一次cv_bride
转化.
NOTE:你可以在这里下载该代码。
3.2编译并运行
这一步请参考上一博客在ROS中传递图像消息(一)中的”2.3配置相关文件”一节.
4扩展
如果你对opencv比较熟悉的话,你完全可以对图像进行一些简单的处理.我这里有一个简单的练习程序,你可以在这里下载.
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。