all_camera_viewer.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *   http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 
00018 //##################
00019 //#### includes ####
00020 
00021 // standard includes
00022 //--
00023 
00024 // ROS includes
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 // ROS message includes
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 // external includes
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         // Subscriptions
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                 // Synchronize inputs of incoming image data.
00169                 // Topic subscriptions happen on demand in the connection callback.
00170 
00171                 // TODO: Dynamically determine, which cameras are available
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                 // Convert ROS image messages to openCV IplImages
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                 // Modifies <code>grey_mat_8U1_</code> and <code>vec_grey_mat_32F1_</code>
00282                 // using <code>grey_mat_32F1_</code>
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                 // Convert ROS image messages to openCV IplImages
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                 // Modifies <code>grey_mat_8U1_</code> and <code>vec_grey_mat_32F1_</code>
00324                 // using <code>grey_mat_32F1_</code>
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/*32FC1*/);
00341 
00342                 // Accumulate greyscale images to remove noise
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                 // Update counter
00348                 tof_image_counter_ = (++tof_image_counter_)%5;
00349 
00350                 // Compute average out of accumulated tof greyscale data
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                 // Update 8bit image
00356                 cv::Mat temp0_grey_mat_8U1;
00357                 cv::Mat temp1_grey_mat_8U1;
00358 
00359                 // Convert CV_32FC1 image to CV_8UC1
00360                 /*double m_scaleMin;
00361                 double m_scaleMax;
00362                 cv::minMaxLoc(filtered_grey_mat_32F1, &m_scaleMin, &m_scaleMax);
00363                 cv::Mat minmat(filtered_grey_mat_32F1.size(), 32FC1, cv::Scalar(m_scaleMin));
00364                 filtered_grey_mat_32F1 = cv::Mat(filtered_grey_mat_32F1 - minmat)/ m_scaleMax;
00365                 filtered_grey_mat_32F1.convertTo(temp0_grey_mat_8U1, CV_8U, 256);*/
00366 
00367                 // Perform histogram equalization on 8bit image
00368                 //cv::equalizeHist(temp0_grey_mat_8U1, temp1_grey_mat_8U1);
00369 
00370                 // Upsample image by a factor of 2 using bilinear interpolation
00371                 // and save result to member variable
00372                 grey_mat_8U1_ = filtered_grey_mat_32F1;//temp0_grey_mat_8U1;
00373                 //resize(temp0_grey_mat_8U1, grey_mat_8U1_, cv::Size(), 2, 2, cv::INTER_LINEAR);
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                 // Convert ROS image messages to openCV IplImages
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 //#### main programm ####
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 }


cob_camera_sensors
Author(s): Jan Fischer , Richard Bormann
autogenerated on Sat Jun 8 2019 21:02:02