00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
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
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 )