ros_camera_observer.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (Apache License)
00003  *
00004  * Copyright (c) 2014, Southwest Research Institute
00005  *
00006  * Licensed under the Apache License, Version 2.0 (the "License");
00007  * you may not use this file except in compliance with the License.
00008  * You may obtain a copy of the License at
00009  *
00010  * http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #include <industrial_extrinsic_cal/ros_camera_observer.h>
00020 
00021 namespace industrial_extrinsic_cal
00022 {
00023 
00024 ROSCameraObserver::ROSCameraObserver(const std::string &camera_topic) :
00025     sym_circle_(true), pattern_(pattern_options::Chessboard), pattern_rows_(0), pattern_cols_(0)
00026 {
00027   image_topic_ = camera_topic;
00028   //ROS_DEBUG_STREAM("ROSCameraObserver created with image topic: "<<image_topic_);
00029   results_pub_ = nh_.advertise<sensor_msgs::Image>("observer_results_image", 100);
00030 }
00031 
00032 bool ROSCameraObserver::addTarget(boost::shared_ptr<Target> targ, Roi &roi)
00033 {
00034   //set pattern based on target
00035   ROS_INFO_STREAM("Target type: "<<targ->target_type);
00036   instance_target_ = targ;
00037   switch (targ->target_type)
00038   {
00039     case pattern_options::Chessboard:
00040       pattern_ = pattern_options::Chessboard;
00041       break;
00042     case pattern_options::CircleGrid:
00043       pattern_ = pattern_options::CircleGrid;
00044       break;
00045     case pattern_options::ARtag:
00046       pattern_ = pattern_options::ARtag;
00047       break;
00048     default:
00049       ROS_ERROR_STREAM("target_type does not correlate to a known pattern option (Chessboard, CircleGrid or ARTag)");
00050       return false;
00051       break;
00052   }
00053 
00054   if (pattern_ != 0 && pattern_ != 1 && pattern_ != 2)
00055   {
00056     ROS_ERROR_STREAM("Unknown pattern, based on target_type");
00057     return false;
00058   }
00059 
00060   //set pattern rows/cols based on target
00061   switch (pattern_)
00062   {
00063     case pattern_options::Chessboard:
00064       pattern_rows_ = targ->checker_board_parameters.pattern_rows;
00065       pattern_cols_ = targ->checker_board_parameters.pattern_cols;
00066       break;
00067     case pattern_options::CircleGrid:
00068       pattern_rows_ = targ->circle_grid_parameters.pattern_rows;
00069       pattern_cols_ = targ->circle_grid_parameters.pattern_cols;
00070       sym_circle_ = targ->circle_grid_parameters.is_symmetric;
00071       break;
00072     case pattern_options::ARtag:
00073       ROS_ERROR_STREAM("AR Tag recognized but pattern not supported yet");
00074       return false;
00075       break;
00076     default:
00077       ROS_ERROR_STREAM("pattern_ does not correlate to a known pattern option (Chessboard, CircleGrid or ARTag)");
00078       return false;
00079       break;
00080   }
00081 
00082   input_roi_.x=roi.x_min;
00083   input_roi_.y= roi.y_min;
00084   input_roi_.width= roi.x_max - roi.x_min;
00085   input_roi_.height= roi.y_max - roi.y_min;
00086   ROS_INFO_STREAM("ROSCameraObserver added target and roi");
00087 
00088   return true;
00089 }
00090 
00091 void ROSCameraObserver::clearTargets()
00092 {
00093   instance_target_.reset();
00094   //ROS_INFO_STREAM("Targets cleared from observer");
00095 }
00096 
00097 void ROSCameraObserver::clearObservations()
00098 {
00099   camera_obs_.observations.clear();
00100   //ROS_INFO_STREAM("Observations cleared from observer");
00101 }
00102 
00103 int ROSCameraObserver::getObservations(CameraObservations &cam_obs)
00104 {
00105   bool successful_find = false;
00106 
00107   ROS_INFO_STREAM("image ROI region created: "<<input_roi_.x<<" "<<input_roi_.y<<" "<<input_roi_.width<<" "<<input_roi_.height);
00108   if (input_bridge_->image.cols < input_roi_.width || input_bridge_->image.rows < input_roi_.height)
00109   {
00110     ROS_ERROR_STREAM("ROI too big for image size");
00111     return 0;
00112   }
00113 
00114   image_roi_ = input_bridge_->image(input_roi_);
00115 
00116   output_bridge_->image = output_bridge_->image(input_roi_);
00117   out_bridge_->image = image_roi_;
00118   ROS_INFO_STREAM("output image size: " <<output_bridge_->image.rows<<" x "<<output_bridge_->image.cols);
00119   results_pub_.publish(out_bridge_->toImageMsg());
00120 
00121   switch (pattern_)
00122   {
00123     case pattern_options::Chessboard:
00124       ROS_INFO_STREAM("Finding Chessboard Corners...");
00125       successful_find = cv::findChessboardCorners(image_roi_, cv::Size(pattern_rows_, pattern_cols_), observation_pts_,
00126                                                   cv::CALIB_CB_ADAPTIVE_THRESH);
00127       break;
00128     case pattern_options::CircleGrid:
00129       if (sym_circle_)
00130       {
00131         ROS_INFO_STREAM("Finding Circles in grid, symmetric...");
00132         successful_find = cv::findCirclesGrid(image_roi_, cv::Size(pattern_rows_, pattern_cols_), observation_pts_,
00133                                               cv::CALIB_CB_SYMMETRIC_GRID);
00134       }
00135       else
00136       {
00137         ROS_INFO_STREAM("Finding Circles in grid, asymmetric...");
00138         successful_find = cv::findCirclesGrid(image_roi_, cv::Size(pattern_rows_, pattern_cols_), observation_pts_,
00139                                               cv::CALIB_CB_ASYMMETRIC_GRID | cv::CALIB_CB_CLUSTERING);
00140       }
00141       break;
00142   }
00143   if (!successful_find)
00144   {
00145     ROS_WARN_STREAM("Pattern not found for pattern: "<<pattern_ <<" with symmetry: "<< sym_circle_);
00146     return 0;
00147   }
00148 
00149   ROS_INFO_STREAM("Number of points found on board: "<<observation_pts_.size());
00150   camera_obs_.observations.resize(observation_pts_.size());
00151   for (int i = 0; i < observation_pts_.size(); i++)
00152   {
00153     camera_obs_.observations.at(i).target = instance_target_;
00154     camera_obs_.observations.at(i).point_id = i;
00155     camera_obs_.observations.at(i).image_loc_x = observation_pts_.at(i).x;
00156     camera_obs_.observations.at(i).image_loc_y = observation_pts_.at(i).y;
00157   }
00158 
00159   cam_obs = camera_obs_;
00160   return 1;
00161 }
00162 
00163 void ROSCameraObserver::triggerCamera()
00164 {
00165 
00166   sensor_msgs::ImageConstPtr recent_image = ros::topic::waitForMessage<sensor_msgs::Image>(image_topic_);
00167   //ROS_INFO_STREAM("Waiting for image on topic: "<<image_topic_);
00168   try
00169   {
00170     input_bridge_ = cv_bridge::toCvCopy(recent_image, "mono8");
00171     output_bridge_ = cv_bridge::toCvCopy(recent_image, "bgr8");
00172     out_bridge_ = cv_bridge::toCvCopy(recent_image, "mono8");
00173     ROS_INFO_STREAM("cv image created based on ros image");
00174   }
00175   catch (cv_bridge::Exception& ex)
00176   {
00177     ROS_ERROR("Failed to convert image");
00178     ROS_WARN_STREAM("cv_bridge exception: "<<ex.what());
00179     //return false;
00180     return;
00181   }
00182 
00183 }
00184 
00185 bool ROSCameraObserver::observationsDone()
00186 {
00187   //if (camera_obs_.observations.size() != 0)
00188   if(!input_bridge_)
00189   {
00190     return false;
00191   }
00192   return true;
00193 }
00194 } //industrial_extrinsic_cal


industrial_extrinsic_cal
Author(s): Chris Lewis
autogenerated on Wed Aug 26 2015 12:00:27