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 #include <ros/ros.h>
00026 #include <cv_bridge/CvBridge.h>
00027 #include <image_transport/image_transport.h>
00028 #include <image_transport/subscriber_filter.h>
00029 #include <message_filters/subscriber.h>
00030 #include <message_filters/time_synchronizer.h>
00031 #ifdef __ROS_1_1__
00032 #include <message_filters/sync_policies/approximate_time.h>
00033 #include <message_filters/synchronizer.h>
00034 #endif
00035
00036
00037 #include <sensor_msgs/Image.h>
00038 #include <sensor_msgs/CameraInfo.h>
00039 #include <sensor_msgs/fill_image.h>
00040
00041 #include <cob_camera_sensors/AcquireCalibrationImages.h>
00042
00043
00044 #include <cob_vision_utils/VisionUtils.h>
00045
00046 #include <opencv/highgui.h>
00047 #include <boost/thread/mutex.hpp>
00048
00049 using namespace message_filters;
00050
00051 #ifdef __ROS_1_1__
00052 typedef sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image, sensor_msgs::Image> ThreeImageSyncPolicy;
00053 typedef sync_policies::ApproximateTime<sensor_msgs::Image, sensor_msgs::Image> TwoImageSyncPolicy;
00054 #endif
00055
00061 class AllCameraViewer
00062 {
00063 private:
00064 ros::NodeHandle node_handle_;
00065
00066 image_transport::ImageTransport image_transport_;
00067
00068
00069 image_transport::SubscriberFilter left_color_camera_image_sub_;
00070 image_transport::SubscriberFilter right_color_camera_image_sub_;
00071 image_transport::SubscriberFilter tof_camera_grey_image_sub_;
00072 message_filters::Subscriber<sensor_msgs::CameraInfo> left_camera_info_sub_;
00073 message_filters::Subscriber<sensor_msgs::CameraInfo> right_camera_info_sub_;
00074 image_transport::Subscriber sub;
00075
00076 #ifdef __ROS_1_1__
00077 message_filters::Synchronizer<ThreeImageSyncPolicy> shared_sub_sync_;
00078 message_filters::Synchronizer<TwoImageSyncPolicy> stereo_sub_sync_;
00079 message_filters::Synchronizer<ThreeImageSyncPolicy> all_sub_sync_;
00080 #else
00081 message_filters::TimeSynchronizer<sensor_msgs::Image,
00082 sensor_msgs::Image, sensor_msgs::Image> shared_sub_sync_;
00083 message_filters::TimeSynchronizer<sensor_msgs::Image,
00084 sensor_msgs::Image> stereo_sub_sync_;
00085 message_filters::TimeSynchronizer<sensor_msgs::Image,
00086 sensor_msgs::Image, sensor_msgs::Image> all_sub_sync_;
00087 #endif
00088
00089 int sub_counter_;
00090 int tof_image_counter_;
00091
00092 sensor_msgs::Image color_image_msg_;
00093 sensor_msgs::Image xyz_image_msg_;
00094 sensor_msgs::Image confidence_mask_msg_;
00095
00096 IplImage* right_color_image_8U3_;
00097 IplImage* left_color_image_8U3_;
00098 IplImage* xyz_image_32F3_;
00099 IplImage* grey_image_32F1_;
00100
00101 cv::Mat right_color_mat_8U3_;
00102 cv::Mat left_color_mat_8U3_;
00103 cv::Mat xyz_mat_32F3_;
00104 cv::Mat grey_mat_32F1_;
00105 cv::Mat grey_mat_8U1_;
00106 std::vector<cv::Mat> vec_grey_mat_32F1_;
00107
00108 int image_counter_;
00109
00110 sensor_msgs::CvBridge cv_bridge_0_;
00111 sensor_msgs::CvBridge cv_bridge_1_;
00112 sensor_msgs::CvBridge cv_bridge_2_;
00113
00114 ros::ServiceServer save_camera_images_service_;
00115
00116 boost::mutex m_ServiceMutex;
00117
00118 std::string absolute_output_directory_path_;
00119
00120 bool use_tof_camera_;
00121 bool use_left_color_camera_;
00122 bool use_right_color_camera_;
00123 public:
00125 AllCameraViewer(const ros::NodeHandle& node_handle)
00126 : node_handle_(node_handle),
00127 image_transport_(node_handle),
00128 #ifdef __ROS_1_1__
00129 shared_sub_sync_(ThreeImageSyncPolicy(3)),
00130 stereo_sub_sync_(TwoImageSyncPolicy(3)),
00131 all_sub_sync_(ThreeImageSyncPolicy(3)),
00132 #else
00133 shared_sub_sync_(3),
00134 stereo_sub_sync_(3),
00135 all_sub_sync_(3),
00136 #endif
00137 sub_counter_(0),
00138 right_color_image_8U3_(0),
00139 left_color_image_8U3_(0),
00140 xyz_image_32F3_(0),
00141 grey_image_32F1_(0)
00142 {
00143 use_tof_camera_ = true;
00144 use_left_color_camera_ = true;
00145 use_right_color_camera_ = true;
00146 image_counter_ = 0;
00147 tof_image_counter_ = 0;
00148 }
00149
00151 ~AllCameraViewer()
00152 {
00153 }
00154
00159 bool init()
00160 {
00161 if (loadParameters() == false) return false;
00162
00163 image_transport::SubscriberStatusCallback imgConnect = boost::bind(&AllCameraViewer::connectCallback, this);
00164 image_transport::SubscriberStatusCallback imgDisconnect = boost::bind(&AllCameraViewer::disconnectCallback, this);
00165
00166 save_camera_images_service_ = node_handle_.advertiseService("save_camera_images", &AllCameraViewer::saveCameraImagesServiceCallback, this);
00167
00168
00169
00170
00171
00172
00173 if(use_right_color_camera_ && use_tof_camera_ && !use_left_color_camera_)
00174 {
00175 ROS_INFO("[all_camera_viewer] Setting up subscribers for right color and tof camera");
00176 shared_sub_sync_.connectInput(right_color_camera_image_sub_, tof_camera_grey_image_sub_);
00177 shared_sub_sync_.registerCallback(boost::bind(&AllCameraViewer::sharedModeSrvCallback, this, _1, _2));
00178 }
00179 else if(use_right_color_camera_ && !use_tof_camera_ && use_left_color_camera_)
00180 {
00181 ROS_INFO("[all_camera_viewer] Setting up subscribers left and right color camera");
00182 stereo_sub_sync_.connectInput(left_color_camera_image_sub_, right_color_camera_image_sub_);
00183 stereo_sub_sync_.registerCallback(boost::bind(&AllCameraViewer::stereoModeSrvCallback, this, _1, _2));
00184 }
00185 else if(use_right_color_camera_ && use_tof_camera_ && use_left_color_camera_)
00186 {
00187 ROS_INFO("[all_camera_viewer] Setting up subscribers for left color, right color and tof camera");
00188 all_sub_sync_.connectInput(left_color_camera_image_sub_, right_color_camera_image_sub_, tof_camera_grey_image_sub_);
00189 all_sub_sync_.registerCallback(boost::bind(&AllCameraViewer::allModeSrvCallback, this, _1, _2, _3));
00190 }
00191 else
00192 {
00193 ROS_ERROR("[all_camera_viewer] Specified camera configuration not available");
00194 return false;
00195 }
00196
00197
00198 connectCallback();
00199
00200 ROS_INFO("[all_camera_viewer] Initializing [OK]");
00201 return true;
00202 }
00203
00205 void connectCallback()
00206 {
00207 if (sub_counter_ == 0)
00208 {
00209 sub_counter_++;
00210 ROS_DEBUG("[all_camera_viewer] Subscribing to camera topics");
00211
00212 if (use_right_color_camera_)
00213 {
00214 right_color_camera_image_sub_.subscribe(image_transport_, "right/image_color", 1);
00215 right_camera_info_sub_.subscribe(node_handle_, "right/camera_info", 1);
00216 }
00217 if (use_left_color_camera_)
00218 {
00219 left_color_camera_image_sub_.subscribe(image_transport_, "left/image_color", 1);
00220 left_camera_info_sub_.subscribe(node_handle_, "left/camera_info", 1);
00221 }
00222 if (use_tof_camera_)
00223 {
00224 tof_camera_grey_image_sub_.subscribe(image_transport_, "image_grey", 1);
00225 }
00226 }
00227 }
00228
00230 void disconnectCallback()
00231 {
00232 sub_counter_--;
00233 if (sub_counter_ == 0)
00234 {
00235 ROS_DEBUG("[all_camera_viewer] Unsubscribing from camera topics");
00236
00237 if (use_right_color_camera_)
00238 {
00239 right_color_camera_image_sub_.unsubscribe();
00240 right_camera_info_sub_.unsubscribe();
00241 }
00242 if (use_left_color_camera_)
00243 {
00244 left_color_camera_image_sub_.unsubscribe();
00245 left_camera_info_sub_.unsubscribe();
00246 }
00247 if (use_tof_camera_)
00248 {
00249 tof_camera_grey_image_sub_.unsubscribe();
00250 }
00251 }
00252 }
00253
00254 void allModeSrvCallback(const sensor_msgs::ImageConstPtr& left_camera_data,
00255 const sensor_msgs::ImageConstPtr& right_camera_data,
00256 const sensor_msgs::ImageConstPtr& tof_camera_grey_data)
00257 {
00258 ROS_INFO("[all_camera_viewer] allModeSrvCallback");
00259 boost::mutex::scoped_lock lock(m_ServiceMutex);
00260
00261 try
00262 {
00263 right_color_image_8U3_ = cv_bridge_0_.imgMsgToCv(right_camera_data, "bgr8");
00264 left_color_image_8U3_ = cv_bridge_1_.imgMsgToCv(left_camera_data, "bgr8");
00265 grey_image_32F1_ = cv_bridge_2_.imgMsgToCv(tof_camera_grey_data, "passthrough");
00266
00267 cv::Mat tmp = right_color_image_8U3_;
00268 right_color_mat_8U3_ = tmp.clone();
00269
00270 tmp = left_color_image_8U3_;
00271 left_color_mat_8U3_ = tmp.clone();
00272
00273 tmp = grey_image_32F1_;
00274 grey_mat_32F1_ = tmp.clone();
00275 }
00276 catch (sensor_msgs::CvBridgeException& e)
00277 {
00278 ROS_ERROR("[all_camera_viewer] Could not convert stereo images with cv_bridge.");
00279 }
00280
00281
00282
00283 updateTofGreyscaleData();
00284
00285 cv::imshow("TOF grey data", grey_mat_8U1_);
00286
00287 cv::Mat right_color_8U3;
00288 cv::resize(right_color_mat_8U3_, right_color_8U3, cv::Size(), 0.5, 0.5);
00289 cv::imshow("Right color data", right_color_8U3);
00290
00291 cv::Mat left_color_8U3;
00292 cv::resize(left_color_mat_8U3_, left_color_8U3, cv::Size(), 0.5, 0.5);
00293 cv::imshow("Left color data", left_color_8U3);
00294 cv::waitKey(50);
00295
00296 ROS_INFO("[all_camera_viewer] allModeSrvCallback [OK]");
00297 }
00298
00301 void sharedModeSrvCallback(const sensor_msgs::ImageConstPtr& right_camera_data,
00302 const sensor_msgs::ImageConstPtr& tof_camera_grey_data)
00303 {
00304 boost::mutex::scoped_lock lock(m_ServiceMutex);
00305 ROS_INFO("[all_camera_viewer] sharedModeSrvCallback");
00306
00307 try
00308 {
00309 right_color_image_8U3_ = cv_bridge_0_.imgMsgToCv(right_camera_data, "passthrough");
00310 grey_image_32F1_ = cv_bridge_2_.imgMsgToCv(tof_camera_grey_data, "passthrough");
00311
00312 cv::Mat tmp = right_color_image_8U3_;
00313 right_color_mat_8U3_ = tmp.clone();
00314
00315 tmp = grey_image_32F1_;
00316 grey_mat_32F1_ = tmp.clone();
00317 }
00318 catch (sensor_msgs::CvBridgeException& e)
00319 {
00320 ROS_ERROR("[all_camera_viewer] Could not convert images with cv_bridge.");
00321 }
00322
00323
00324
00325 updateTofGreyscaleData();
00326
00327 cv::imshow("TOF grey data", grey_mat_8U1_);
00328
00329 cv::Mat right_color_8U3;
00330 cv::resize(right_color_mat_8U3_, right_color_8U3, cv::Size(), 0.5, 0.5);
00331 cv::imshow("Right color data", right_color_8U3);
00332 cv::waitKey(1000);
00333 }
00334
00338 void updateTofGreyscaleData()
00339 {
00340 cv::Mat filtered_grey_mat_32F1 = cv::Mat::zeros(grey_mat_32F1_.rows, grey_mat_32F1_.cols, CV_8UC1);
00341
00342
00343 if (vec_grey_mat_32F1_.size() <= (unsigned int) tof_image_counter_)
00344 vec_grey_mat_32F1_.push_back(grey_mat_32F1_);
00345 else
00346 vec_grey_mat_32F1_[tof_image_counter_] = grey_mat_32F1_;
00347
00348 tof_image_counter_ = (++tof_image_counter_)%5;
00349
00350
00351 for (unsigned int i=0; i<vec_grey_mat_32F1_.size(); i++)
00352 filtered_grey_mat_32F1 += vec_grey_mat_32F1_[i];
00353 filtered_grey_mat_32F1 * (1/vec_grey_mat_32F1_.size());
00354
00355
00356 cv::Mat temp0_grey_mat_8U1;
00357 cv::Mat temp1_grey_mat_8U1;
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 grey_mat_8U1_ = filtered_grey_mat_32F1;
00373
00374 }
00375
00378 void stereoModeSrvCallback(const sensor_msgs::ImageConstPtr& left_camera_data,
00379 const sensor_msgs::ImageConstPtr& right_camera_data)
00380 {
00381 ROS_INFO("[all_camera_viewer] stereoModeSrvCallback");
00382 boost::mutex::scoped_lock lock(m_ServiceMutex);
00383
00384 try
00385 {
00386 right_color_image_8U3_ = cv_bridge_0_.imgMsgToCv(right_camera_data, "passthrough");
00387 left_color_image_8U3_ = cv_bridge_1_.imgMsgToCv(left_camera_data, "passthrough");
00388
00389 cv::Mat tmp = right_color_image_8U3_;
00390 right_color_mat_8U3_ = tmp.clone();
00391
00392 tmp = left_color_image_8U3_;
00393 left_color_mat_8U3_ = tmp.clone();
00394 }
00395 catch (sensor_msgs::CvBridgeException& e)
00396 {
00397 ROS_ERROR("[all_camera_viewer] Could not convert stereo images with cv_bridge.");
00398 }
00399
00400 cv::Mat right_color_8U3;
00401 cv::resize(right_color_mat_8U3_, right_color_8U3, cv::Size(), 0.5, 0.5);
00402 cv::imshow("Right color data", right_color_8U3);
00403
00404 cv::Mat left_color_8U3;
00405 cv::resize(left_color_mat_8U3_, left_color_8U3, cv::Size(), 0.5, 0.5);
00406 cv::imshow("Left color data", left_color_8U3);
00407 cv::waitKey(1000);
00408
00409 ROS_INFO("[all_camera_viewer] stereoModeSrvCallback [OK]");
00410 }
00411
00412 bool saveCameraImagesServiceCallback(cob_camera_sensors::AcquireCalibrationImages::Request &req,
00413 cob_camera_sensors::AcquireCalibrationImages::Response &res)
00414 {
00415 ROS_INFO("[all_camera_viewer] Service Callback");
00416 boost::mutex::scoped_lock lock(m_ServiceMutex);
00417
00418 if (req.reset_image_counter) image_counter_ = 0;
00419
00420 char counterBuffer [50];
00421 sprintf(counterBuffer, "%04d", image_counter_);
00422
00423 if (use_right_color_camera_ && right_color_mat_8U3_.empty())
00424 {
00425 ROS_INFO("[all_camera_viewer] Right color image not available");
00426 return false;
00427 }
00428 else
00429 {
00430 std::stringstream ss;
00431 ss << "right_color_image_";
00432 ss << counterBuffer;
00433 ss << ".bmp";
00434 cv::imwrite(absolute_output_directory_path_ + ss.str(), right_color_mat_8U3_);
00435 ROS_INFO("[all_camera_viewer] Saved right color image %d to %s", image_counter_, ss.str().c_str());
00436 }
00437
00438 if (use_left_color_camera_ && left_color_mat_8U3_.empty())
00439 {
00440 ROS_INFO("[all_camera_viewer] Left color image not available");
00441 return false;
00442 }
00443 else
00444 {
00445 std::stringstream ss;
00446 ss << "left_color_image_";
00447 ss << counterBuffer;
00448 ss << ".bmp";
00449 cv::imwrite(absolute_output_directory_path_ + ss.str(), left_color_mat_8U3_);
00450 ROS_INFO("[all_camera_viewer] Saved left color image %d to %s", image_counter_, ss.str().c_str());
00451 }
00452
00453
00454 if (use_tof_camera_ && grey_mat_8U1_.empty())
00455 {
00456 ROS_INFO("[all_camera_viewer] Tof grayscale image not available");
00457 return false;
00458 }
00459 else
00460 {
00461 std::stringstream ss;
00462 ss << "tof_grey_image_";
00463 ss << counterBuffer;
00464 ss << ".bmp";
00465 cv::imwrite(absolute_output_directory_path_ + ss.str(), grey_mat_8U1_);
00466 ROS_INFO("[all_camera_viewer] Saved tof gray image %d to %s", image_counter_, ss.str().c_str());
00467 }
00468
00469 image_counter_++;
00470
00471 return true;
00472 }
00473
00474 unsigned long loadParameters()
00475 {
00476 std::string tmp_string;
00477
00479 if (node_handle_.getParam("all_camera_viewer/use_tof_camera", use_tof_camera_) == false)
00480 {
00481 ROS_ERROR("[all_camera_viewer] 'use_tof_camera' not specified");
00482 return false;
00483 }
00484 ROS_INFO("use tof camera: %d", use_tof_camera_);
00485
00486 if (node_handle_.getParam("all_camera_viewer/use_right_color_camera", use_right_color_camera_) == false)
00487 {
00488 ROS_ERROR("[all_camera_viewer] 'use_right_color_camera' not specified");
00489 return false;
00490 }
00491 ROS_INFO("use right color camera: %d", use_right_color_camera_);
00492
00493 if (node_handle_.getParam("all_camera_viewer/use_left_color_camera", use_left_color_camera_) == false)
00494 {
00495 ROS_ERROR("[all_camera_viewer] 'use_left_color_camera' not specified");
00496 return false;
00497 }
00498 ROS_INFO("use left color camera: %d", use_left_color_camera_);
00499
00500 if (node_handle_.getParam("all_camera_viewer/absolute_output_directory_path", absolute_output_directory_path_) == false)
00501 {
00502 ROS_ERROR("[all_camera_viewer] 'absolute_output_directory_path' not specified");
00503 return false;
00504 }
00505 ROS_INFO("use left color camera: %d", use_left_color_camera_);
00506
00507 return true;
00508 }
00509
00510 };
00511
00512
00513
00514 int main(int argc, char** argv)
00515 {
00517 ros::init(argc, argv, "all_camera_viewer");
00518
00520 ros::NodeHandle nh;
00521
00523 AllCameraViewer camera_node(nh);
00524
00526 if (!camera_node.init()) return 0;
00527
00528 ros::spin();
00529
00530 return 0;
00531 }