00001 #include <ros/ros.h>
00002 #include <nodelet/nodelet.h>
00003 #include <sensor_msgs/image_encodings.h>
00004 #include <stereo_msgs/DisparityImage.h>
00005 #include <opencv2/highgui/highgui.hpp>
00006 #include "window_thread.h"
00007
00008 #ifdef HAVE_GTK
00009 #include <gtk/gtk.h>
00010
00011
00012
00013
00014 static void destroyNode(GtkWidget *widget, gpointer data)
00015 {
00016 exit(0);
00017 }
00018
00019 static void destroyNodelet(GtkWidget *widget, gpointer data)
00020 {
00021
00022
00023 reinterpret_cast<ros::Subscriber*>(data)->shutdown();
00024 }
00025 #endif
00026
00027
00028 namespace image_view {
00029
00030 class DisparityNodelet : public nodelet::Nodelet
00031 {
00032
00033 static unsigned char colormap[];
00034
00035 std::string window_name_;
00036 ros::Subscriber sub_;
00037 cv::Mat_<cv::Vec3b> disparity_color_;
00038
00039 virtual void onInit();
00040
00041 void imageCb(const stereo_msgs::DisparityImageConstPtr& msg);
00042
00043 public:
00044 ~DisparityNodelet();
00045 };
00046
00047 DisparityNodelet::~DisparityNodelet()
00048 {
00049 cv::destroyWindow(window_name_);
00050 }
00051
00052 void DisparityNodelet::onInit()
00053 {
00054 ros::NodeHandle nh = getNodeHandle();
00055 ros::NodeHandle local_nh = getPrivateNodeHandle();
00056 const std::vector<std::string>& argv = getMyArgv();
00057
00058
00059 bool shutdown_on_close = std::find(argv.begin(), argv.end(),
00060 "--shutdown-on-close") != argv.end();
00061
00062
00063 std::string topic = nh.resolveName("image");
00064 local_nh.param("window_name", window_name_, topic);
00065
00066 bool autosize;
00067 local_nh.param("autosize", autosize, false);
00068
00069 cv::namedWindow(window_name_, autosize ? CV_WINDOW_AUTOSIZE : 0);
00070
00071 #ifdef HAVE_GTK
00072
00073 GtkWidget *widget = GTK_WIDGET( cvGetWindowHandle(window_name_.c_str()) );
00074 if (shutdown_on_close)
00075 g_signal_connect(widget, "destroy", G_CALLBACK(destroyNode), NULL);
00076 else
00077 g_signal_connect(widget, "destroy", G_CALLBACK(destroyNodelet), &sub_);
00078 #endif
00079
00080
00081 startWindowThread();
00082
00083 sub_ = nh.subscribe<stereo_msgs::DisparityImage>(topic, 1, &DisparityNodelet::imageCb, this);
00084 }
00085
00086 void DisparityNodelet::imageCb(const stereo_msgs::DisparityImageConstPtr& msg)
00087 {
00088
00089 if (msg->min_disparity == 0.0 && msg->max_disparity == 0.0)
00090 {
00091 NODELET_ERROR_THROTTLE(30, "Disparity image fields min_disparity and "
00092 "max_disparity are not set");
00093 return;
00094 }
00095 if (msg->image.encoding != sensor_msgs::image_encodings::TYPE_32FC1)
00096 {
00097 NODELET_ERROR_THROTTLE(30, "Disparity image must be 32-bit floating point "
00098 "(encoding '32FC1'), but has encoding '%s'",
00099 msg->image.encoding.c_str());
00100 return;
00101 }
00102
00103
00104 float min_disparity = msg->min_disparity;
00105 float max_disparity = msg->max_disparity;
00106 float multiplier = 255.0f / (max_disparity - min_disparity);
00107
00108 const cv::Mat_<float> dmat(msg->image.height, msg->image.width,
00109 (float*)&msg->image.data[0], msg->image.step);
00110 disparity_color_.create(msg->image.height, msg->image.width);
00111
00112 for (int row = 0; row < disparity_color_.rows; ++row) {
00113 const float* d = dmat[row];
00114 for (int col = 0; col < disparity_color_.cols; ++col) {
00115 int index = (d[col] - min_disparity) * multiplier + 0.5;
00116 index = std::min(255, std::max(0, index));
00117
00118 disparity_color_(row, col)[2] = colormap[3*index + 0];
00119 disparity_color_(row, col)[1] = colormap[3*index + 1];
00120 disparity_color_(row, col)[0] = colormap[3*index + 2];
00121 }
00122 }
00123
00125 #if 0
00126 sensor_msgs::RegionOfInterest valid = msg->valid_window;
00127 cv::Point tl(valid.x_offset, valid.y_offset), br(valid.x_offset + valid.width, valid.y_offset + valid.height);
00128 cv::rectangle(disparity_color_, tl, br, CV_RGB(255,0,0), 1);
00129 #endif
00130
00131 cv::imshow(window_name_, disparity_color_);
00132 }
00133
00134 unsigned char DisparityNodelet::colormap[768] =
00135 { 150, 150, 150,
00136 107, 0, 12,
00137 106, 0, 18,
00138 105, 0, 24,
00139 103, 0, 30,
00140 102, 0, 36,
00141 101, 0, 42,
00142 99, 0, 48,
00143 98, 0, 54,
00144 97, 0, 60,
00145 96, 0, 66,
00146 94, 0, 72,
00147 93, 0, 78,
00148 92, 0, 84,
00149 91, 0, 90,
00150 89, 0, 96,
00151 88, 0, 102,
00152 87, 0, 108,
00153 85, 0, 114,
00154 84, 0, 120,
00155 83, 0, 126,
00156 82, 0, 131,
00157 80, 0, 137,
00158 79, 0, 143,
00159 78, 0, 149,
00160 77, 0, 155,
00161 75, 0, 161,
00162 74, 0, 167,
00163 73, 0, 173,
00164 71, 0, 179,
00165 70, 0, 185,
00166 69, 0, 191,
00167 68, 0, 197,
00168 66, 0, 203,
00169 65, 0, 209,
00170 64, 0, 215,
00171 62, 0, 221,
00172 61, 0, 227,
00173 60, 0, 233,
00174 59, 0, 239,
00175 57, 0, 245,
00176 56, 0, 251,
00177 55, 0, 255,
00178 54, 0, 255,
00179 52, 0, 255,
00180 51, 0, 255,
00181 50, 0, 255,
00182 48, 0, 255,
00183 47, 0, 255,
00184 46, 0, 255,
00185 45, 0, 255,
00186 43, 0, 255,
00187 42, 0, 255,
00188 41, 0, 255,
00189 40, 0, 255,
00190 38, 0, 255,
00191 37, 0, 255,
00192 36, 0, 255,
00193 34, 0, 255,
00194 33, 0, 255,
00195 32, 0, 255,
00196 31, 0, 255,
00197 29, 0, 255,
00198 28, 0, 255,
00199 27, 0, 255,
00200 26, 0, 255,
00201 24, 0, 255,
00202 23, 0, 255,
00203 22, 0, 255,
00204 20, 0, 255,
00205 19, 0, 255,
00206 18, 0, 255,
00207 17, 0, 255,
00208 15, 0, 255,
00209 14, 0, 255,
00210 13, 0, 255,
00211 11, 0, 255,
00212 10, 0, 255,
00213 9, 0, 255,
00214 8, 0, 255,
00215 6, 0, 255,
00216 5, 0, 255,
00217 4, 0, 255,
00218 3, 0, 255,
00219 1, 0, 255,
00220 0, 4, 255,
00221 0, 10, 255,
00222 0, 16, 255,
00223 0, 22, 255,
00224 0, 28, 255,
00225 0, 34, 255,
00226 0, 40, 255,
00227 0, 46, 255,
00228 0, 52, 255,
00229 0, 58, 255,
00230 0, 64, 255,
00231 0, 70, 255,
00232 0, 76, 255,
00233 0, 82, 255,
00234 0, 88, 255,
00235 0, 94, 255,
00236 0, 100, 255,
00237 0, 106, 255,
00238 0, 112, 255,
00239 0, 118, 255,
00240 0, 124, 255,
00241 0, 129, 255,
00242 0, 135, 255,
00243 0, 141, 255,
00244 0, 147, 255,
00245 0, 153, 255,
00246 0, 159, 255,
00247 0, 165, 255,
00248 0, 171, 255,
00249 0, 177, 255,
00250 0, 183, 255,
00251 0, 189, 255,
00252 0, 195, 255,
00253 0, 201, 255,
00254 0, 207, 255,
00255 0, 213, 255,
00256 0, 219, 255,
00257 0, 225, 255,
00258 0, 231, 255,
00259 0, 237, 255,
00260 0, 243, 255,
00261 0, 249, 255,
00262 0, 255, 255,
00263 0, 255, 249,
00264 0, 255, 243,
00265 0, 255, 237,
00266 0, 255, 231,
00267 0, 255, 225,
00268 0, 255, 219,
00269 0, 255, 213,
00270 0, 255, 207,
00271 0, 255, 201,
00272 0, 255, 195,
00273 0, 255, 189,
00274 0, 255, 183,
00275 0, 255, 177,
00276 0, 255, 171,
00277 0, 255, 165,
00278 0, 255, 159,
00279 0, 255, 153,
00280 0, 255, 147,
00281 0, 255, 141,
00282 0, 255, 135,
00283 0, 255, 129,
00284 0, 255, 124,
00285 0, 255, 118,
00286 0, 255, 112,
00287 0, 255, 106,
00288 0, 255, 100,
00289 0, 255, 94,
00290 0, 255, 88,
00291 0, 255, 82,
00292 0, 255, 76,
00293 0, 255, 70,
00294 0, 255, 64,
00295 0, 255, 58,
00296 0, 255, 52,
00297 0, 255, 46,
00298 0, 255, 40,
00299 0, 255, 34,
00300 0, 255, 28,
00301 0, 255, 22,
00302 0, 255, 16,
00303 0, 255, 10,
00304 0, 255, 4,
00305 2, 255, 0,
00306 8, 255, 0,
00307 14, 255, 0,
00308 20, 255, 0,
00309 26, 255, 0,
00310 32, 255, 0,
00311 38, 255, 0,
00312 44, 255, 0,
00313 50, 255, 0,
00314 56, 255, 0,
00315 62, 255, 0,
00316 68, 255, 0,
00317 74, 255, 0,
00318 80, 255, 0,
00319 86, 255, 0,
00320 92, 255, 0,
00321 98, 255, 0,
00322 104, 255, 0,
00323 110, 255, 0,
00324 116, 255, 0,
00325 122, 255, 0,
00326 128, 255, 0,
00327 133, 255, 0,
00328 139, 255, 0,
00329 145, 255, 0,
00330 151, 255, 0,
00331 157, 255, 0,
00332 163, 255, 0,
00333 169, 255, 0,
00334 175, 255, 0,
00335 181, 255, 0,
00336 187, 255, 0,
00337 193, 255, 0,
00338 199, 255, 0,
00339 205, 255, 0,
00340 211, 255, 0,
00341 217, 255, 0,
00342 223, 255, 0,
00343 229, 255, 0,
00344 235, 255, 0,
00345 241, 255, 0,
00346 247, 255, 0,
00347 253, 255, 0,
00348 255, 251, 0,
00349 255, 245, 0,
00350 255, 239, 0,
00351 255, 233, 0,
00352 255, 227, 0,
00353 255, 221, 0,
00354 255, 215, 0,
00355 255, 209, 0,
00356 255, 203, 0,
00357 255, 197, 0,
00358 255, 191, 0,
00359 255, 185, 0,
00360 255, 179, 0,
00361 255, 173, 0,
00362 255, 167, 0,
00363 255, 161, 0,
00364 255, 155, 0,
00365 255, 149, 0,
00366 255, 143, 0,
00367 255, 137, 0,
00368 255, 131, 0,
00369 255, 126, 0,
00370 255, 120, 0,
00371 255, 114, 0,
00372 255, 108, 0,
00373 255, 102, 0,
00374 255, 96, 0,
00375 255, 90, 0,
00376 255, 84, 0,
00377 255, 78, 0,
00378 255, 72, 0,
00379 255, 66, 0,
00380 255, 60, 0,
00381 255, 54, 0,
00382 255, 48, 0,
00383 255, 42, 0,
00384 255, 36, 0,
00385 255, 30, 0,
00386 255, 24, 0,
00387 255, 18, 0,
00388 255, 12, 0,
00389 255, 6, 0,
00390 255, 0, 0,
00391 };
00392
00393 }
00394
00395
00396 #include <pluginlib/class_list_macros.h>
00397 PLUGINLIB_DECLARE_CLASS(image_view, disparity, image_view::DisparityNodelet, nodelet::Nodelet)