video_capture_display.cpp
Go to the documentation of this file.
00001 // -*- mode: c++ -*-
00002 /*********************************************************************
00003  * Software License Agreement (BSD License)
00004  *
00005  *  Copyright (c) 2014, JSK Lab
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/o2r other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the JSK Lab nor the names of its
00019  *     contributors may be used to endorse or promote products derived
00020  *     from this software without specific prior written permission.
00021  *
00022  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00026  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00028  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00032  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  *  POSSIBILITY OF SUCH DAMAGE.
00034  *********************************************************************/
00035 
00036 #include "video_capture_display.h"
00037 #include <rviz/display_context.h>
00038 #include <rviz/view_manager.h>
00039 #include <rviz/display_group.h>
00040 #include <rviz/display.h>
00041 #include <rviz/render_panel.h>
00042 #include <QImage>
00043 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
00044 #include <QScreen>
00045 #include <QGuiApplication>
00046 #endif
00047 #include <boost/filesystem.hpp>
00048 
00049 namespace jsk_rviz_plugins
00050 {
00051   VideoCaptureDisplay::VideoCaptureDisplay():
00052     Display(), capturing_(false), first_time_(true)
00053   {
00054     start_capture_property_ = new rviz::BoolProperty(
00055       "start capture", false, "start capture",
00056       this, SLOT(updateStartCapture()));
00057     file_name_property_ = new rviz::StringProperty(
00058       "filename", "output.avi",
00059       "filename", this, SLOT(updateFileName()));
00060     fps_property_ = new rviz::FloatProperty(
00061       "fps", 30.0,
00062       "fps", this, SLOT(updateFps()));
00063     fps_property_->setMin(0.1);
00064   }
00065 
00066   VideoCaptureDisplay::~VideoCaptureDisplay()
00067   {
00068     delete start_capture_property_;
00069     delete file_name_property_;
00070   }
00071 
00072   void VideoCaptureDisplay::onInitialize()
00073   {
00074     updateFileName();
00075     updateFps();
00076     //updateStartCapture();
00077     start_capture_property_->setBool(false); // always false when starting up
00078     context_->queueRender();
00079   }
00080 
00081   void VideoCaptureDisplay::onEnable()
00082   {
00083     start_capture_property_->setBool(false); // always false when starting up
00084     context_->queueRender();
00085   }
00086   
00087   void VideoCaptureDisplay::updateFileName()
00088   {
00089     if (capturing_) {
00090       ROS_WARN("cannot change name wile recording");
00091       file_name_property_->setStdString(file_name_);
00092     }
00093     else {
00094       file_name_ = file_name_property_->getStdString();
00095       int exists_check = access(file_name_.c_str(), F_OK);
00096       if (exists_check == 0) {
00097         int access_result = access(file_name_.c_str(), W_OK);
00098         ROS_INFO("access_result to %s: %d", file_name_.c_str(), access_result);
00099         if (access_result != 0) {
00100           setStatus(rviz::StatusProperty::Error, "File", "NOT Writable");
00101         }
00102         else {
00103           setStatus(rviz::StatusProperty::Ok, "File", "Writable");
00104         }
00105       }
00106       else {                    // do not exists, check directory permission
00107         ROS_INFO("%s do not exists", file_name_.c_str());
00108         boost::filesystem::path pathname(file_name_);
00109         std::string dirname  = pathname.parent_path().string();
00110         if (dirname.length() == 0) { // Special case for without path
00111           dirname = ".";
00112         }
00113         ROS_INFO("dirname: %s", dirname.c_str());
00114         int directory_access_result = access(dirname.c_str(), W_OK);
00115         if (directory_access_result != 0) {
00116           setStatus(rviz::StatusProperty::Error, "File", "NOT Writable (direcotry)");
00117         }
00118         else {
00119           setStatus(rviz::StatusProperty::Ok, "File", "Writable");
00120         }
00121       }
00122     }
00123   }
00124 
00125   void VideoCaptureDisplay::updateStartCapture()
00126   {
00127     ROS_INFO("updateStartCapture");
00128     if (first_time_) {
00129       ROS_WARN("ignore first time capture enabling");
00130     }
00131     else {
00132       // start capture!
00133       if (start_capture_property_->getBool()) {
00134         capturing_ = true;
00135         startCapture();
00136       }
00137       else {
00138         capturing_ = false;
00139         stopCapture();
00140       }
00141     }
00142   }
00143 
00144   void VideoCaptureDisplay::updateFps()
00145   {
00146     fps_ = fps_property_->getFloat();
00147   }
00148   
00149   void VideoCaptureDisplay::startCapture()
00150   {
00151     ROS_INFO("start capturing");
00152     frame_counter_ = 0;
00153     rviz::RenderPanel* panel = context_->getViewManager()->getRenderPanel();
00154     int width = panel->width();
00155     int height = panel->height();
00156     writer_.open(file_name_, CV_FOURCC_DEFAULT, fps_, cv::Size(width, height));
00157   }
00158   
00159   void VideoCaptureDisplay::stopCapture()
00160   {
00161     ROS_INFO("stop capturing");
00162     writer_.release();
00163     frame_counter_ = 0;
00164   }
00165 
00166   void VideoCaptureDisplay::update(float wall_dt, float ros_dt)
00167   {
00168     if (first_time_) {
00169       ROS_WARN("force to disable capturing");
00170       start_capture_property_->setBool(false); // always false when starting up
00171       first_time_ = false;
00172       return;
00173     }
00174     if (capturing_) {
00175       rviz::RenderPanel* panel = context_->getViewManager()->getRenderPanel();
00176 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
00177       QPixmap screenshot
00178         = QGuiApplication::primaryScreen()->grabWindow(context_->getViewManager()->getRenderPanel()->winId());
00179 #else
00180       QPixmap screenshot
00181         = QPixmap::grabWindow(context_->getViewManager()->getRenderPanel()->winId());
00182 #endif
00183       QImage src = screenshot.toImage().convertToFormat(QImage::Format_RGB888);  // RGB
00184       cv::Mat image(src.height(), src.width(), CV_8UC3,
00185                     (uchar*)src.bits(), src.bytesPerLine());  // RGB
00186       cv::cvtColor(image, image, CV_RGB2BGR);  // RGB -> BGR
00187       writer_ << image;
00188       ++frame_counter_;
00189       if (frame_counter_ % 100 == 0) {
00190         ROS_INFO("taking %d frames as video", frame_counter_);
00191       }
00192     }
00193     // convert QPixmap into cv::Mat
00194   }
00195 }
00196 
00197 
00198 #include <pluginlib/class_list_macros.h>
00199 PLUGINLIB_EXPORT_CLASS(jsk_rviz_plugins::VideoCaptureDisplay, rviz::Display)
00200 


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Wed May 1 2019 02:40:22