rgbd
record_to_video.cpp
Go to the documentation of this file.
1 // ROS
2 #include <ros/console.h>
3 #include <ros/duration.h>
4 #include <ros/init.h>
5 #include <ros/master.h>
6 #include <ros/node_handle.h>
7 #include <ros/rate.h>
8 #include <ros/subscriber.h>
9 #include <ros/time.h>
10 
11 // ROS image message
12 #include <sensor_msgs/Image.h>
13 
14 // For converting image messages to OpenCV
15 #include <cv_bridge/cv_bridge.h>
16 #include <sensor_msgs/image_encodings.h>
17 
18 // Writing video files
19 #include <opencv2/highgui/highgui.hpp>
20 
21 #include <opencv2/imgproc/imgproc.hpp>
22 
23 // Received RGB image
24 cv::Mat rgb_image;
25 
26 // ----------------------------------------------------------------------------------------
27 
28 void imageCallback(const sensor_msgs::ImageConstPtr& rgb_image_msg) {
29 
30  cv_bridge::CvImagePtr img_ptr;
31 
32  // Convert RGB image message to OpenCV mat
33  try {
34  img_ptr = cv_bridge::toCvCopy(rgb_image_msg, sensor_msgs::image_encodings::BGR8);
35  } catch (cv_bridge::Exception& e) {
36  ROS_ERROR("Could not deserialize rgb image: %s", e.what());
37  return;
38  }
39 
40  rgb_image = img_ptr->image;
41 }
42 
43 // ----------------------------------------------------------------------------------------
44 
45 int main(int argc, char **argv) {
46  ros::init(argc, argv, "rgbd_transport_server");
47 
48  // Read parameters
49  ros::NodeHandle nh_private("~");
50 
51  float rate = 30;
52  nh_private.getParam("rate", rate);
53 
54  std::string filename;
55  nh_private.getParam("filename", filename);
56 
57  std::string format = "DIVX";
58  nh_private.getParam("format", format);
59 
60  double size = 1;
61  nh_private.getParam("size", size);
62 
63  if (format.size() != 4)
64  {
65  ROS_ERROR("Parameter 'format' should be string of size 4 (e.g., MJPG, DIVX, MPG4, etc)");
66  return 1;
67  }
68 
69  // Subscriber to image topic
70  ros::NodeHandle nh;
71  ros::Subscriber sub = nh.subscribe("rgb", 1, imageCallback);
72 
73  cv::VideoWriter video_writer;
74  bool initialized = false;
75 
76  // video size
77  cv::Size2i video_size;
78 
79  ros::WallTime last_master_check = ros::WallTime::now();
80 
81  // Start loop at given frequency
82  ros::Rate r(rate);
83  while (ros::ok())
84  {
85  if (ros::WallTime::now() >= last_master_check + ros::WallDuration(1))
86  {
87  last_master_check = ros::WallTime::now();
88  if (!ros::master::check())
89  {
90  ROS_FATAL("Lost connection to master");
91  return 1;
92  }
93  }
94  ros::spinOnce();
95 
96  // Check if we already received an image
97  if (rgb_image.data)
98  {
99  // Check ik we already initialized the video writer
100  if (!initialized)
101  {
102  // If not, do so
103  video_size = cv::Size2i(static_cast<int>(size * rgb_image.cols),
104  static_cast<int>(size * rgb_image.rows));
105  video_writer.open(filename.c_str(), cv::VideoWriter::fourcc(format[0], format[1], format[2], format[3]), rate, video_size);
106 
107  if (!video_writer.isOpened())
108  {
109  // Could not create the video writer, so exit
110  std::cout << "Unable to create video writer" << std::endl;
111  return 1;
112  }
113 
114  initialized = true;
115  }
116 
117  if (size == 1)
118  {
119  // Write received image to the video
120  video_writer.write(rgb_image);
121  }
122  else
123  {
124  cv::Mat rgb_image_scaled;
125  cv::resize(rgb_image, rgb_image_scaled, video_size);
126 
127  // Write received image to the video
128  video_writer.write(rgb_image_scaled);
129  }
130  }
131 
132  // Sleep for remaining loop time
133  r.sleep();
134  }
135 
136  video_writer.release();
137 
138  return 0;
139 }
std::string
rgb_image
cv::Mat rgb_image
Definition: record_to_video.cpp:24
main
int main(int argc, char **argv)
Definition: record_to_video.cpp:45
std::cout
std::string::c_str
T c_str(T... args)
rgbd::ImageConstPtr
std::shared_ptr< const Image > ImageConstPtr
Definition: types.h:10
std::endl
T endl(T... args)
imageCallback
void imageCallback(const sensor_msgs::ImageConstPtr &rgb_image_msg)
Definition: record_to_video.cpp:28