overlay_image_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 Willow Garage 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 "overlay_image_display.h"
00037 
00038 #include <OGRE/OgreOverlayManager.h>
00039 #include <OGRE/OgreMaterialManager.h>
00040 #include <OGRE/OgreTextureManager.h>
00041 #include <OGRE/OgreTexture.h>
00042 #include <OGRE/OgreHardwarePixelBuffer.h>
00043 #include <OGRE/OgreTechnique.h>
00044 
00045 #include <rviz/uniform_string_stream.h>
00046 #include <cv_bridge/cv_bridge.h>
00047 #include <sensor_msgs/image_encodings.h>
00048 
00049 namespace jsk_rviz_plugin
00050 {
00051 
00052   OverlayImageDisplay::OverlayImageDisplay()
00053     : Display(), width_(128), height_(128), left_(128), top_(128), alpha_(0.8),
00054       require_update_(false)
00055   {
00056     // setup properties
00057     update_topic_property_ = new rviz::RosTopicProperty(
00058       "Topic", "",
00059       ros::message_traits::datatype<sensor_msgs::Image>(),
00060       "sensor_msgs::Image topic to subscribe to.",
00061       this, SLOT( updateTopic() ));
00062     width_property_ = new rviz::IntProperty("width", 128,
00063                                             "width of the image window",
00064                                             this, SLOT(updateWidth()));
00065     height_property_ = new rviz::IntProperty("height", 128,
00066                                              "height of the image window",
00067                                              this, SLOT(updateHeight()));
00068     left_property_ = new rviz::IntProperty("left", 128,
00069                                            "left of the image window",
00070                                            this, SLOT(updateLeft()));
00071     top_property_ = new rviz::IntProperty("top", 128,
00072                                           "top of the image window",
00073                                           this, SLOT(updateTop()));
00074     alpha_property_ = new rviz::FloatProperty("alpha", 0.8,
00075                                               "alpha belnding value",
00076                                               this, SLOT(updateAlpha()));
00077   }
00078 
00079   OverlayImageDisplay::~OverlayImageDisplay()
00080   {
00081     delete update_topic_property_;
00082     delete width_property_;
00083     delete height_property_;
00084     delete left_property_;
00085     delete top_property_;
00086     delete alpha_property_;
00087   }
00088   
00089   void OverlayImageDisplay::onInitialize()
00090   {
00091     ros::NodeHandle nh;
00092     it_ = boost::shared_ptr<image_transport::ImageTransport>(new image_transport::ImageTransport(nh));
00093     
00094     updateWidth();
00095     updateHeight();
00096     updateTop();
00097     updateLeft();
00098     updateAlpha();
00099     updateTopic();
00100   }
00101   
00102   void OverlayImageDisplay::onEnable()
00103   {
00104     if (overlay_) {
00105       overlay_->show();
00106     }
00107     subscribe();
00108   }
00109   void OverlayImageDisplay::onDisable()
00110   {
00111     if (overlay_) {
00112       overlay_->hide();
00113     }
00114     unsubscribe();
00115   }
00116 
00117   void OverlayImageDisplay::unsubscribe()
00118   {
00119     sub_.shutdown();
00120     // clear clear clear...
00121   }
00122 
00123   void OverlayImageDisplay::subscribe()
00124   {
00125     std::string topic_name = update_topic_property_->getTopicStd();
00126     
00127     if (topic_name.length() > 0 && topic_name != "/") {
00128       sub_ = it_->subscribe(topic_name, 1, &OverlayImageDisplay::processMessage, this);
00129     }
00130   }
00131 
00132   void OverlayImageDisplay::processMessage(
00133     const sensor_msgs::Image::ConstPtr& msg)
00134   {
00135     boost::mutex::scoped_lock(mutex_);
00136     msg_ = msg;
00137     require_update_ = true;
00138   }
00139   
00140 
00141   void OverlayImageDisplay::update(float wall_dt, float ros_dt)
00142   {
00143     boost::mutex::scoped_lock(mutex_);
00144 
00145     if (!isEnabled()) {
00146       return;
00147     }
00148     
00149     if (require_update_) {
00150       if (!overlay_) {
00151         static int count = 0;
00152         rviz::UniformStringStream ss;
00153         ss << "OverlayImageDisplayObject" << count++;
00154         overlay_.reset(new OverlayObject(ss.str()));
00155         overlay_->show();
00156       }
00157       overlay_->updateTextureSize(msg_->width, msg_->height);
00158       redraw();
00159       require_update_ = false;
00160     }
00161     if (overlay_) {
00162       overlay_->setDimensions(width_, height_);
00163       overlay_->setPosition(left_, top_);
00164     }
00165   }
00166 
00167   void OverlayImageDisplay::redraw()
00168   {
00169     cv_bridge::CvImagePtr cv_ptr;
00170     try
00171     {
00172       cv_ptr = cv_bridge::toCvCopy(msg_, sensor_msgs::image_encodings::RGB8);
00173       cv::Mat mat = cv_ptr->image;
00174       ScopedPixelBuffer buffer = overlay_->getBuffer();
00175       QImage Hud = buffer.getQImage(*overlay_);
00176       for (int i = 0; i < overlay_->getTextureWidth(); i++) {
00177         for (int j = 0; j < overlay_->getTextureHeight(); j++) {
00178           QColor color(mat.data[j * mat.step + i * mat.elemSize() + 0],
00179                        mat.data[j * mat.step + i * mat.elemSize() + 1],
00180                        mat.data[j * mat.step + i * mat.elemSize() + 2],
00181                        alpha_ * 255.0);
00182           Hud.setPixel(i, j, color.rgba());
00183         }
00184       }
00185     }
00186     catch (cv_bridge::Exception& e)
00187     {
00188       ROS_ERROR("cv_bridge exception: %s", e.what());
00189     }
00190   }
00191 
00192   void OverlayImageDisplay::updateTopic()
00193   {
00194     unsubscribe();
00195     subscribe();
00196   }
00197   
00198   void OverlayImageDisplay::updateWidth()
00199   {
00200     boost::mutex::scoped_lock lock(mutex_);
00201     width_ = width_property_->getInt();
00202   }
00203   
00204   void OverlayImageDisplay::updateHeight()
00205   {
00206     boost::mutex::scoped_lock lock(mutex_);
00207     height_ = height_property_->getInt();
00208   }
00209 
00210   void OverlayImageDisplay::updateTop()
00211   {
00212     boost::mutex::scoped_lock lock(mutex_);
00213     top_ = top_property_->getInt();
00214   }
00215 
00216   void OverlayImageDisplay::updateLeft()
00217   {
00218     boost::mutex::scoped_lock lock(mutex_);
00219     left_ = left_property_->getInt();
00220   }
00221   
00222   void OverlayImageDisplay::updateAlpha()
00223   {
00224     boost::mutex::scoped_lock lock(mutex_);
00225     alpha_ = alpha_property_->getFloat();
00226   }
00227   
00228 }
00229 
00230 #include <pluginlib/class_list_macros.h>
00231 PLUGINLIB_EXPORT_CLASS( jsk_rviz_plugin::OverlayImageDisplay, rviz::Display )


jsk_rviz_plugins
Author(s): Kei Okada , Yohei Kakiuchi , Shohei Fujii , Ryohei Ueda
autogenerated on Mon Oct 6 2014 01:18:44