video_capture_display.cpp
Go to the documentation of this file.
1 // -*- mode: c++ -*-
2 /*********************************************************************
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2014, JSK Lab
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/o2r other materials provided
17  * with the distribution.
18  * * Neither the name of the JSK Lab nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *********************************************************************/
35 
36 #include "video_capture_display.h"
37 #if CV_MAJOR_VERSION >= 4
38 #include <opencv2/videoio/legacy/constants_c.h>
39 #include <opencv2/imgproc/types_c.h>
40 #endif
41 #include <rviz/display_context.h>
42 #include <rviz/view_manager.h>
43 #include <rviz/display_group.h>
44 #include <rviz/display.h>
45 #include <rviz/render_panel.h>
46 #include <QImage>
47 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
48 #include <QScreen>
49 #include <QGuiApplication>
50 #endif
51 #include <boost/filesystem.hpp>
52 
53 namespace jsk_rviz_plugins
54 {
56  Display(), capturing_(false), first_time_(true)
57  {
59  "start capture", false, "start capture",
60  this, SLOT(updateStartCapture()));
62  "filename", "output.avi",
63  "filename", this, SLOT(updateFileName()));
65  "fps", 30.0,
66  "fps", this, SLOT(updateFps()));
67  fps_property_->setMin(0.1);
69  "use 3D viewer size", true,
70  "Use width and height of 3D viewer for output video or set them manually",
71  this, SLOT(updateUse3DViewerSize()));
73  "width", 1920,
74  "Width of video in pixels", this, SLOT(updateWidth()));
76  "height", 1080,
77  "Height of video in pixels", this, SLOT(updateHeight()));
78  }
79 
81  {
83  delete file_name_property_;
85  delete width_property_;
86  delete height_property_;
87  }
88 
90  {
92  updateFps();
94  updateWidth();
95  updateHeight();
96  //updateStartCapture();
97  start_capture_property_->setBool(false); // always false when starting up
99  }
100 
102  {
103  start_capture_property_->setBool(false); // always false when starting up
105  }
106 
108  {
109  if (capturing_) {
110  ROS_WARN("cannot change name wile recording");
112  }
113  else {
115  int exists_check = access(file_name_.c_str(), F_OK);
116  if (exists_check == 0) {
117  int access_result = access(file_name_.c_str(), W_OK);
118  ROS_INFO("access_result to %s: %d", file_name_.c_str(), access_result);
119  if (access_result != 0) {
120  setStatus(rviz::StatusProperty::Error, "File", "NOT Writable");
121  }
122  else {
123  setStatus(rviz::StatusProperty::Ok, "File", "Writable");
124  }
125  }
126  else { // do not exists, check directory permission
127  ROS_INFO("%s do not exists", file_name_.c_str());
128  boost::filesystem::path pathname(file_name_);
129  std::string dirname = pathname.parent_path().string();
130  if (dirname.length() == 0) { // Special case for without path
131  dirname = ".";
132  }
133  ROS_INFO("dirname: %s", dirname.c_str());
134  int directory_access_result = access(dirname.c_str(), W_OK);
135  if (directory_access_result != 0) {
136  setStatus(rviz::StatusProperty::Error, "File", "NOT Writable (direcotry)");
137  }
138  else {
139  setStatus(rviz::StatusProperty::Ok, "File", "Writable");
140  }
141  }
142  }
143  }
144 
146  {
147  ROS_INFO("updateStartCapture");
148  if (first_time_) {
149  ROS_WARN("ignore first time capture enabling");
150  }
151  else {
152  // start capture!
154  capturing_ = true;
155  startCapture();
156  }
157  else {
158  capturing_ = false;
159  stopCapture();
160  }
161  }
162  }
163 
165  {
167  }
168 
170  {
172  updateWidth();
173  updateHeight();
174  }
175 
177  if (use_3d_viewer_size_) {
180  }
181  else {
184  }
185  }
186 
188  {
190  }
191 
193  {
195  }
196 
198  {
199  ROS_INFO("start capturing");
200  frame_counter_ = 0;
201  if (use_3d_viewer_size_) {
203  width_ = panel->width();
204  height_ = panel->height();
205  }
206  writer_.open(file_name_, CV_FOURCC_DEFAULT, fps_, cv::Size(width_, height_));
207  }
208 
210  {
211  ROS_INFO("stop capturing");
212  writer_.release();
213  frame_counter_ = 0;
214  }
215 
216  void VideoCaptureDisplay::update(float wall_dt, float ros_dt)
217  {
218  if (first_time_) {
219  ROS_WARN("force to disable capturing");
220  start_capture_property_->setBool(false); // always false when starting up
221  first_time_ = false;
222  return;
223  }
224  if (capturing_) {
226 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
227  QPixmap screenshot
228  = QGuiApplication::primaryScreen()->grabWindow(context_->getViewManager()->getRenderPanel()->winId());
229 #else
230  QPixmap screenshot
231  = QPixmap::grabWindow(context_->getViewManager()->getRenderPanel()->winId());
232 #endif
233  QImage src = screenshot.toImage().convertToFormat(QImage::Format_RGB888); // RGB
234  cv::Mat image(src.height(), src.width(), CV_8UC3,
235  (uchar*)src.bits(), src.bytesPerLine()); // RGB
236  if (image.size().width != width_ || image.size().height != height_) {
237  cv::resize(image, image, cv::Size(width_, height_), 0, 0, cv::INTER_LINEAR);
238  }
239  cv::cvtColor(image, image, CV_RGB2BGR); // RGB -> BGR
240  writer_ << image;
241  ++frame_counter_;
242  if (frame_counter_ % 100 == 0) {
243  ROS_INFO("taking %d frames as video", frame_counter_);
244  }
245  }
246  // convert QPixmap into cv::Mat
247  }
248 }
249 
250 
253 
void setMin(float min)
PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::PictogramArrayDisplay, rviz::Display)
DisplayContext * context_
virtual ViewManager * getViewManager() const =0
virtual int getInt() const
virtual float getFloat() const
virtual void update(float wall_dt, float ros_dt)
#define ROS_WARN(...)
std::string getStdString()
virtual bool getBool() const
#define ROS_INFO(...)
virtual void queueRender()=0
RenderPanel * getRenderPanel() const
bool setStdString(const std::string &std_str)
bool setBool(bool value)
virtual void setStatus(StatusProperty::Level level, const QString &name, const QString &text)


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Sat Mar 20 2021 03:03:18