ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
1

How to save video stream ?

asked 2018-12-25 14:43:11 -0500

earcz gravatar image

updated 2018-12-25 14:58:42 -0500

I want to record video with a usb webcam to process it later. To do that, I found limited info. One is to use rosbag to save published topics. Another way is to use opencv to write video. Which method would provide a simple solution to save video ? (maybe another alternative method beyond what I said) I have a source code ofimage_pubpackage to publish images as following;

#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;
}
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
1

answered 2018-12-26 12:18:40 -0500

CodeMade gravatar image

I would use OpenCV to write video and then use the recording to run simulations later. But we probably need more info on what kind of processing you want to do before solid advice can be given.

edit flag offensive delete link more

Comments

sorry for late response. I will apply odometry code onto saved video. I tried writing video using opencv into the code above but I could not make it work. Recording should be 1280 x 720.

earcz gravatar image earcz  ( 2018-12-28 09:39:32 -0500 )edit
0

answered 2018-12-26 15:39:52 -0500

ChriMo gravatar image

I'm not sure, what you mean with process later, but capture a camera view from the robot is easy.

run web_video_server node and connect with VLC to the stream. VLC can record the complete stream for later processing/viewing.

edit flag offensive delete link more

Comments

sorry for the late response (I am moving my home). Processing later means that I will apply an odometry code onto the saved video. Also, the code above is mandatory for my robotic system so that I need to modify it to save a video from published images. Also,I don't have internet connection on robot

earcz gravatar image earcz  ( 2018-12-28 09:30:34 -0500 )edit

Question Tools

1 follower

Stats

Asked: 2018-12-25 14:43:11 -0500

Seen: 1,712 times

Last updated: Dec 26 '18