首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将VideoWriter代码集成到image_publisher代码中?

如何将VideoWriter代码集成到image_publisher代码中?
EN

Stack Overflow用户
提问于 2019-01-02 06:25:20
回答 1查看 326关注 0票数 0

我正在建立一个ros系统,用ros、c++和opencv-2发布我的无人机的图片。下面的代码是发布原始图像。在发布的时候,我想写一帧一帧的灰度图像,分辨率为1280 x 720来录制视频。我发现了一个随时可用的视频编写代码与opencv。但是,我无法将此代码合并到image_publisher代码中。以下是image_publisher代码:

代码语言:javascript
复制
#include <ros/ros.h>
#include <camera_info_manager/camera_info_manager.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/CameraInfo.h>
#include <opencv2/opencv.hpp>

int main(int argc, char **argv)
{
ROS_INFO("Starting image_pub ROS node...\n");

ros::init(argc, argv, "image_pub");
ros::NodeHandle nh("~");

std::string camera_topic;
std::string camera_info_topic;
std::string camera_info_url;
std::string img_path;
std::string frame_id;
float       pub_rate;
int         start_sec;
bool        repeat;
nh.param<std::string>("camera_topic",      camera_topic,      "/camera/image_raw");
nh.param<std::string>("camera_info_topic", camera_info_topic, "/camera/camera_info");
nh.param<std::string>("camera_info_url",   camera_info_url,   "");
nh.param<std::string>("img_path", img_path, "");
nh.param<std::string>("frame_id", frame_id, "");
nh.param("pub_rate",  pub_rate, 30.0f);
nh.param("start_sec", start_sec, 0);
nh.param("repeat",    repeat, false);

ROS_INFO("CTopic : %s", camera_topic.c_str());
ROS_INFO("ITopic : %s", camera_info_topic.c_str());
ROS_INFO("CI URL : %s", camera_info_url.c_str());
ROS_INFO("Source : %s", img_path.c_str());
ROS_INFO("Rate   : %.1f", pub_rate);
ROS_INFO("Start  : %d", start_sec);
ROS_INFO("Repeat : %s", repeat ? "yes" : "no");
ROS_INFO("FrameID: %s", frame_id.c_str());

camera_info_manager::CameraInfoManager camera_info_manager(nh);
if (camera_info_manager.validateURL(camera_info_url))
    camera_info_manager.loadCameraInfo(camera_info_url);

ros::Publisher img_pub  = nh.advertise<sensor_msgs::Image>(camera_topic, 1);
ros::Publisher info_pub = nh.advertise<sensor_msgs::CameraInfo>(camera_info_topic, 1);

cv::VideoCapture vid_cap(img_path.c_str());
if (start_sec > 0)
    vid_cap.set(CV_CAP_PROP_POS_MSEC, 1000.0 * start_sec);

ros::Rate rate(pub_rate);
while (ros::ok())
{
    cv::Mat img;
    if (!vid_cap.read(img))
    {
        if (repeat)
        {
            vid_cap.open(img_path.c_str());
            if (start_sec > 0)
                vid_cap.set(CV_CAP_PROP_POS_MSEC, 1000.0 * start_sec);
            continue;
        }
        ROS_ERROR("Failed to capture frame.");
        ros::shutdown();
    }
    else
    {
        //ROS_DEBUG("Image: %dx%dx%d, %zu, %d", img.rows, img.cols, img.channels(), img.elemSize(), img.type() == CV_8UC3);
        if (img.type() != CV_8UC3)
            img.convertTo(img, CV_8UC3);
        // Convert image from BGR format used by OpenCV to RGB.
        cv::cvtColor(img, img, CV_BGR2RGB);

        auto img_msg = boost::make_shared<sensor_msgs::Image>();
        img_msg->header.stamp    = ros::Time::now();
        img_msg->header.frame_id = frame_id;
        img_msg->encoding = "rgb8";
        img_msg->width = img.cols;
        img_msg->height = img.rows;
        img_msg->step = img_msg->width * img.channels();
        auto ptr = img.ptr<unsigned char>(0);
        img_msg->data = std::vector<unsigned char>(ptr, ptr + img_msg->step * img_msg->height);
        img_pub.publish(img_msg);

        if (camera_info_manager.isCalibrated())
        {
            auto info = boost::make_shared<sensor_msgs::CameraInfo>(camera_info_manager.getCameraInfo());
            info->header = img_msg->header;
            info_pub.publish(info);
        }
    }
    ros::spinOnce();
    rate.sleep();
}

return 0;
}

视频编写代码(提到这个链接):

代码语言:javascript
复制
#include "opencv2/opencv.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main(){

// Create a VideoCapture object and use camera to capture the video
VideoCapture cap(0); 

// Check if camera opened successfully
if(!cap.isOpened())
{
  cout << "Error opening video stream" << endl; 
  return -1; 
} 

// Default resolution of the frame is obtained.The default resolution is system dependent. 
int frame_width = cap.get(CV_CAP_PROP_FRAME_WIDTH); 
int frame_height = cap.get(CV_CAP_PROP_FRAME_HEIGHT); 

// Define the codec and create VideoWriter object.The output is stored in 'outcpp.avi' file. 
VideoWriter video("outcpp.avi",CV_FOURCC('M','J','P','G'),10, 
Size(frame_width,frame_height)); 
while(1)
{ 
Mat frame; 

// Capture frame-by-frame 
cap >> frame;

// If the frame is empty, break immediately
if (frame.empty())
  break;

// Write the frame into the file 'outcpp.avi'
video.write(frame);

// Display the resulting frame    
imshow( "Frame", frame );

// Press  ESC on keyboard to  exit
char c = (char)waitKey(1);
if( c == 27 ) 
  break;
}

// When everything done, release the video capture and write object
cap.release();
video.release();

// Closes all the windows
destroyAllWindows();
return 0;
  }

首先,我尝试将视频编写代码(没有灰度)合并到出版商代码中。但失败了。总之,image_publisher代码应该在完成任务后生成一个视频。怎样才是正确的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-04 12:47:00

您不能在ros主题系统中发送opencv,因为Image主题有另一个编码系统。

您需要使用cv_bridge将您从Opencv获得的图像转换为ROS-图像格式。

有一些细节和例子-- 这里

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54002104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档