00001
00005 #ifndef _THERMALVIS_CALIBRATOR_H_
00006 #define _THERMALVIS_CALIBRATOR_H_
00007
00008 #include "ros_resources.hpp"
00009 #include "general_resources.hpp"
00010 #include "opencv_resources.hpp"
00011
00012 #include <signal.h>
00013
00014 #include "improc.hpp"
00015 #include "video.hpp"
00016 #include "calibration.hpp"
00017 #include "intrinsics.hpp"
00018 #include "extrinsics.hpp"
00019 #include "features.hpp"
00020
00021
00022
00023 #include <ros/ros.h>
00024 #include <boost/thread/thread.hpp>
00025 #include <image_transport/image_transport.h>
00026 #include <opencv/cv.h>
00027 #include <opencv/highgui.h>
00028
00029
00030 #include <dynamic_reconfigure/server.h>
00031 #include "calibratorConfig.h"
00032
00033 #define MAX_ALLOWABLE_CAMS 2
00034 #define DEFAULT_SET_SIZE 10
00035 #define DEFAULT_GRID_SIZE 10 // (mm)
00036 #define DEFAULT_X_COUNT 12
00037 #define DEFAULT_Y_COUNT 8
00038 #define DEFAULT_TIMER_PERIOD 0.05
00039
00040 #define DEFAULT_MAX_TIME_DIFF 0.001
00041
00042
00043 #define PATTERN_CODE_INVALID -1
00044 #define PATTERN_CODE_FIND_TRACK 0
00045 #define PATTERN_CODE_TRACK_FIND 1
00046 #define PATTERN_CODE_FIND 2
00047
00048 const char __PROGRAM__[] = "thermalvis-calibrator";
00049
00050 bool wantsToShutdown = false;
00051 void mySigintHandler(int sig);
00052
00054 struct calibratorData {
00055
00056
00057 string read_addr;
00058 string video_stream, video_stream_secondary;
00059 string intrinsicsFiles[MAX_ALLOWABLE_CAMS];
00060
00061
00062 bool invert[MAX_ALLOWABLE_CAMS];
00063 string patternType, optMethod;
00064 double autoTimeout;
00065 bool trackingMode;
00066 string calibType;
00067 bool wantsIntrinsics;
00068 int pattType;
00069 int optimizationMethod;
00070 bool stopCapturing;
00071 string patternDetectionMode;
00072 bool useMutex;
00073 unsigned int numCams;
00074
00075 bool fixPrincipalPoint;
00076
00077 bool fixIntrinsics;
00078
00079 bool noConstraints;
00080
00081 bool ignoreDistortion, useRationalModel;
00082
00083 double maxInterpolationTimegap, maxInterpolationMotion;
00084
00085
00086 bool useUndistortedLocations;
00087 double alpha;
00088 bool autoAlpha;
00089 bool removeSpatialBias;
00090
00091
00092 double maxTimeDiff;
00093 int maxPatterns, maxFrames, setSize, maxCandidates, maxTests;
00094 double maxTime;
00095 double flowThreshold, errorThreshold, maxFrac;
00096
00097
00098 double gridSize;
00099 int xCount, yCount;
00100
00101
00102 bool drawGrids;
00103 bool generateFigures;
00104 string outputFolder;
00105 bool debugMode;
00106 bool verboseMode;
00107 bool undistortImages;
00108 bool rectifyImages;
00109
00110
00111 Mat K[MAX_ALLOWABLE_CAMS];
00112 Mat distCoeffs[MAX_ALLOWABLE_CAMS];
00113
00114
00115 bool adjustMSER[MAX_ALLOWABLE_CAMS];
00116 int delta[MAX_ALLOWABLE_CAMS];
00117 double maxVar[MAX_ALLOWABLE_CAMS], minDiv[MAX_ALLOWABLE_CAMS];
00118 double areaThreshold[MAX_ALLOWABLE_CAMS];
00119
00120
00121 bool obtainStartingData(ros::NodeHandle& nh);
00122
00123 };
00124
00126 struct validPattern {
00127 int validFrameID;
00128 int patternID;
00129 bool patternFound;
00130 bool isValidFrame;
00131 };
00132
00133
00134
00136 class calibratorNode {
00137 private:
00138
00139 ros::NodeHandle *ref;
00140
00141 Mat prevMat[MAX_ALLOWABLE_CAMS], grayMat[MAX_ALLOWABLE_CAMS];
00142
00143 struct timeval cycle_timer;
00144 double elapsedTime;
00145 double avgTime;
00146
00147 struct timeval tracking_timer;
00148 double elapsedTrackingTime;
00149 double frameTrackingTime;
00150
00151 unsigned int validSets;
00152
00153 struct timeval vacant_timer, elapsed_timer;
00154 double vacantInputTime, elapsedInputTime;
00155
00156 Mat map1[MAX_ALLOWABLE_CAMS], map2[MAX_ALLOWABLE_CAMS];
00157 int topValidHeight, botValidHeight, leftValid[MAX_ALLOWABLE_CAMS], rightValid[MAX_ALLOWABLE_CAMS];
00158
00159 ros::Timer timer;
00160
00161 vector<unsigned int> patternIndices[MAX_ALLOWABLE_CAMS];
00162 vector<Mat> displayImages[MAX_ALLOWABLE_CAMS];
00163
00164 vector<ros::Time> times[MAX_ALLOWABLE_CAMS];
00165
00166 vector<unsigned int> validPairs[MAX_ALLOWABLE_CAMS];
00167
00168
00169
00170 bool infoProcessed[MAX_ALLOWABLE_CAMS];
00171 bool stillCollecting;
00172
00173 double alpha;
00174
00175 Mat default_R;
00176
00177 Mat cameraMatrices[MAX_ALLOWABLE_CAMS];
00178 Mat distCoeffVecs[MAX_ALLOWABLE_CAMS];
00179
00180 Rect roi[MAX_ALLOWABLE_CAMS];
00181 vector<Point2f> rectangleBounds, newRecBounds;
00182 Mat rectCamMat[MAX_ALLOWABLE_CAMS];
00183 vector<Point2f> leftLinePoints, rightLinePoints;
00184
00185 Size imSize[MAX_ALLOWABLE_CAMS];
00186 Mat newCamMat[MAX_ALLOWABLE_CAMS];
00187
00188 double reprojectionError_intrinsics[MAX_ALLOWABLE_CAMS];
00189 double extendedReprojectionError_intrinsics[MAX_ALLOWABLE_CAMS];
00190
00191 vector<unsigned char> duplicateFlags[MAX_ALLOWABLE_CAMS];
00192
00193 vector<ros::Time> patternTimestamps[MAX_ALLOWABLE_CAMS];
00194
00195 vector<int> subselectedTags_intrinsics[MAX_ALLOWABLE_CAMS];
00196
00197 string topic[MAX_ALLOWABLE_CAMS];
00198
00199 unsigned int publishCount;
00200
00201
00202 Mat R_[MAX_ALLOWABLE_CAMS], P_[MAX_ALLOWABLE_CAMS];
00203 Mat E[MAX_ALLOWABLE_CAMS], F[MAX_ALLOWABLE_CAMS], Q[MAX_ALLOWABLE_CAMS];
00204 Mat R[MAX_ALLOWABLE_CAMS], Rv[MAX_ALLOWABLE_CAMS], T[MAX_ALLOWABLE_CAMS];
00205 Mat R2[MAX_ALLOWABLE_CAMS], T2[MAX_ALLOWABLE_CAMS];
00206
00207 double stereoError;
00208 double extendedExtrinsicReprojectionError;
00209
00210 bool alphaChanged;
00211
00212 calibratorData configData;
00213
00214 sensor_msgs::CameraInfo debug_camera_info[MAX_ALLOWABLE_CAMS];
00215
00216 image_transport::CameraPublisher debug_pub[MAX_ALLOWABLE_CAMS];
00217
00218 image_transport::CameraSubscriber camera_sub[MAX_ALLOWABLE_CAMS];
00219
00220
00221
00222
00223 cv_bridge::CvImagePtr cv_ptr[MAX_ALLOWABLE_CAMS];
00224
00225 char debug_pub_name[MAX_ALLOWABLE_CAMS][256];
00226
00227 sensor_msgs::Image msg_debug[MAX_ALLOWABLE_CAMS];
00228
00229 ros::NodeHandle private_node_handle;
00230
00231 char nodeName[256];
00232
00233 Mat newImage, lastImage;
00234
00235 unsigned int checkIndex[MAX_ALLOWABLE_CAMS];
00236 unsigned int frameCount[MAX_ALLOWABLE_CAMS], undistortionCount, rectificationCount, totalFrameCount[2];
00237
00238 cv::vector<Point3f> row;
00239
00240 vector<vector<Point2f> > pointSets[MAX_ALLOWABLE_CAMS], candidateSets[MAX_ALLOWABLE_CAMS], testingSets[MAX_ALLOWABLE_CAMS];
00241 vector<vector<Point2f> > extrinsicsPointSets[MAX_ALLOWABLE_CAMS], extrinsicCandidateSets[MAX_ALLOWABLE_CAMS], extrinsicTestingSets[MAX_ALLOWABLE_CAMS];
00242
00243
00244 Mat lastMat[MAX_ALLOWABLE_CAMS];
00245 vector<Point2f> cornerSets[MAX_ALLOWABLE_CAMS];
00246 vector<unsigned int> frameCounts[MAX_ALLOWABLE_CAMS];
00247 bool doVerify;
00248
00249
00250 boost::shared_mutex _access;
00251
00252 bool readyForOutput;
00253
00254 dynamic_reconfigure::Server<thermalvis::calibratorConfig> server;
00255 dynamic_reconfigure::Server<thermalvis::calibratorConfig>::CallbackType f;
00256
00257 vector<Point2f> cornerSet[MAX_ALLOWABLE_CAMS];
00258
00259
00260 void preprocessImage(Mat src, Mat &dst, double a, double b, bool normaliz, bool negative );
00261
00262
00263
00264 public:
00265 calibratorNode(ros::NodeHandle& nh, calibratorData startupData);
00266
00267 void performIntrinsicCalibration();
00268 void performExtrinsicCalibration();
00269
00270 void handle_image(const sensor_msgs::ImageConstPtr& msg_ptr, const sensor_msgs::CameraInfoConstPtr& info_msg, const unsigned int camera_index = 0);
00271
00272
00273 void create_virtual_pairs();
00274
00275 void assignDebugCameraInfo();
00276
00277 void imageCallback(const sensor_msgs::ImageConstPtr& msg);
00278
00279 void publishUndistorted(const ros::TimerEvent& event);
00280 void startUndistortionPublishing();
00281
00282 void publishRectified(const ros::TimerEvent& event);
00283 void startRectificationPublishing();
00284
00285 bool isStillCollecting();
00286 bool wantsToUndistort();
00287 bool wantsToRectify();
00288 void writeResults();
00289 bool wantsIntrinsics();
00290 bool wantsExtrinsics();
00291 void updatePairs();
00292
00293
00294 void determineValidPairs();
00295 void evaluateFrames();
00296
00297 void getAverageTime();
00298 void getFrameTrackingTime();
00299 void assignIntrinsics();
00300
00301 void preparePatternSubsets();
00302 void prepareExtrinsicPatternSubsets();
00303
00304 void serverCallback(thermalvis::calibratorConfig &config, uint32_t level);
00305 void updateMap();
00306
00307 bool findPattern(const Mat& im, vector<Point2f>& dst, Mat& prev, const int cameraNumber);
00308
00309 void updateIntrinsicMap(unsigned int idx);
00310 void set_ready_for_output();
00311
00312 void prepareForTermination();
00313
00314
00315 bool isVerifying();
00316
00317 void timerCallback(const ros::TimerEvent& e);
00318
00319 };
00320
00321 boost::shared_ptr < calibratorNode > *globalNodePtr;
00322
00323 #endif