depth.cpp
Go to the documentation of this file.
00001 
00005 #include "depth.hpp"
00006 
00007 int main(int argc, char** argv) {
00008         
00009         printf("%s::%s << Node launched.\n", __PROGRAM__, __FUNCTION__);
00010         
00011         ros::init(argc, argv, "depth");
00012         
00013         ros::NodeHandle private_node_handle("~");
00014         
00015         stereoData startupData;
00016         
00017         startupData.read_addr = argv[0];
00018         
00019         
00020         
00021         printf("%s::%s << startupData.read_addr = %s\n", __PROGRAM__, __FUNCTION__, startupData.read_addr.c_str());
00022                 
00023         bool inputIsValid = startupData.obtainStartingData(private_node_handle);
00024         
00025         if (!inputIsValid) {
00026                 printf("%s << Configuration invalid.\n", __FUNCTION__);
00027         }
00028                 
00029         printf("%s::%s << Startup data processed.\n", __PROGRAM__, __FUNCTION__);
00030         
00031         //ros::Rate loop_rate(25);
00032         
00033         
00034         ros::NodeHandle nh;
00035         
00036         stereoDepthNode stereo_node(nh, startupData);
00037         
00038         printf("%s::%s << Node configured.\n", __PROGRAM__, __FUNCTION__);
00039         
00040         ros::spin();
00041         return 0;
00042         
00043 }
00044 
00045 stereoDepthNode::stereoDepthNode(ros::NodeHandle& nh, stereoData startupData) {
00046         
00047         alphaChanged = true;
00048         
00049         configData = startupData;
00050         
00051         
00052         printf("%s << Initializing 'stereoDepthNode'...\n", __FUNCTION__);
00053         
00054         // look for "left" and "right" cameras in video_stream
00055         
00056         std::string topic_info_1 = nh.resolveName(configData.video_stream + "left/camera_info");
00057         std::string topic_info_2 = nh.resolveName(configData.video_stream + "right/camera_info");
00058         
00059         std::string topic_1 = nh.resolveName(configData.video_stream + "left/image_raw");
00060         std::string topic_2 = nh.resolveName(configData.video_stream + "right/image_raw");
00061         
00062         printf("%s << topic_1 = %s; topic_2 = %s\n", __FUNCTION__, topic_1.c_str(), topic_2.c_str());
00063         
00064         image_transport::ImageTransport it(nh);
00065         camera_sub_1 = it.subscribeCamera(topic_1, 1, &stereoDepthNode::handle_image_1, this);
00066         camera_sub_2 = it.subscribeCamera(topic_2, 1, &stereoDepthNode::handle_image_2, this);
00067         
00068         timer = nh.createTimer(ros::Duration(0.01), &stereoDepthNode::timed_loop, this);
00069         
00070         infoProcessed_1 = false;
00071         infoProcessed_2 = false;
00072         
00073         frameCount_1 = 0;
00074         frameCount_2 = 0;
00075         frameCount = 0;
00076         
00077         firstPair = true;
00078         
00079         firstImProcessed_1 = false;
00080         firstImProcessed_2 = false;
00081         firstPairProcessed = false;
00082         
00083         // Set up stereo
00084         
00085         enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2 };
00086         int alg = STEREO_HH; //STEREO_SGBM;
00087                 
00088         SADWindowSize = 5;
00089         numberOfDisparities = 0;
00090         sgbm.preFilterCap = 31; //63;
00091     sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
00092         
00093         
00094     int cn = 1; //img1.channels();
00095 
00096         unsigned int width = 640;
00097     numberOfDisparities = 128;
00098     numberOfDisparities = numberOfDisparities > 0 ? numberOfDisparities : width/8;
00099     
00100     bm.state->roi1 = roi1;
00101     bm.state->roi2 = roi2;
00102     bm.state->preFilterSize = 41;
00103     bm.state->preFilterCap = 31;
00104     bm.state->SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 41;
00105     bm.state->minDisparity = -64;
00106     bm.state->numberOfDisparities = numberOfDisparities;
00107     bm.state->textureThreshold = 10;
00108     bm.state->uniquenessRatio = 15;
00109     bm.state->speckleWindowSize = 100;
00110     bm.state->speckleRange = 32;
00111     bm.state->disp12MaxDiff = 1;
00112     
00113     sgbm.P1 = 32*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
00114     sgbm.P2 = 128*cn*sgbm.SADWindowSize*sgbm.SADWindowSize;
00115     sgbm.minDisparity = 0;
00116     sgbm.numberOfDisparities = numberOfDisparities;
00117     sgbm.uniquenessRatio = 10;
00118     sgbm.speckleWindowSize = bm.state->speckleWindowSize;
00119     sgbm.speckleRange = bm.state->speckleRange;
00120     sgbm.disp12MaxDiff = 1;
00121     sgbm.fullDP = alg == STEREO_HH;
00122     
00123     
00124     disparityPublisher = nh.advertise<stereo_msgs::DisparityImage>( "thermalvis/disparity", 1);
00125     
00126     printf("%s << read_addr = %s\n", __FUNCTION__, configData.read_addr.c_str());
00127     printf("%s << extrinsics = %s\n", __FUNCTION__, configData.extrinsics.c_str());
00128 
00129         if ((configData.extrinsics.at(0) == '.') && (configData.extrinsics.at(1) == '.')) {
00130                 configData.read_addr.replace(configData.read_addr.end()-5, configData.read_addr.end(), configData.extrinsics);
00131                 //configData.read_addr = configData.read_addr + "/" + configData.extrinsics;
00132         } else {
00133                 configData.read_addr = configData.extrinsics;
00134         }
00135         
00136         printf("%s << read_addr = %s\n", __FUNCTION__, configData.read_addr.c_str());
00137         
00138         FileStorage fs(configData.read_addr, FileStorage::READ);
00139         fs["R_0"] >> R0;
00140         fs["R_1"] >> R1;
00141         fs["P_0"] >> P0;
00142         fs["P_1"] >> P1;
00143         fs["F"] >> F;
00144         fs["Q1"] >> Q1;
00145         fs["Q2"] >> Q2;
00146         fs["T1"] >> t;
00147         fs.release();
00148         
00149         cout << "R0 = " << R0 << endl;
00150         cout << "R1 = " << R1 << endl;
00151         cout << "t = " << t << endl;
00152         // cout << "P0 = " << P0 << endl;
00153         // cout << "P1 = " << P1 << endl;
00154         
00155         sprintf(cam_pub_name_1, "thermalvis/left/image_rect_color");
00156         sprintf(cam_pub_name_2, "thermalvis/right/image_rect_color");
00157         
00158         cam_pub_1 = it.advertiseCamera(cam_pub_name_1, 1);
00159         cam_pub_2 = it.advertiseCamera(cam_pub_name_2, 1);
00160         
00161         ROS_INFO("Establishing server callback...");
00162         f = boost::bind (&stereoDepthNode::serverCallback, this, _1, _2);
00163     server.setCallback (f);
00164 
00165 }
00166 
00167 bool stereoData::obtainStartingData(ros::NodeHandle& nh) {
00168         
00169         nh.param<std::string>("video_stream", video_stream, "video_stream");
00170         
00171         if (video_stream != "video_stream") {
00172                 printf("%s << Video stream (%s) selected.\n", __FUNCTION__, video_stream.c_str());
00173         } else {
00174                 printf("%s << ERROR! No video stream specified.\n", __FUNCTION__);
00175                 return false;
00176         }
00177         
00178         nh.param<std::string>("extrinsics", extrinsics, "extrinsics");
00179         
00180         printf("%s << Extrinsics at %s selected.\n", __FUNCTION__, extrinsics.c_str());
00181         
00182         
00183         nh.param<bool>("debug_mode", debugMode, false);
00184         
00185         if (debugMode) {
00186                 printf("%s << Running in DEBUG mode.\n", __FUNCTION__);
00187         } else {
00188                 printf("%s << Running in OPTIMIZED mode.\n", __FUNCTION__);
00189         }
00190         
00191         nh.param<bool>("autoAlpha", autoAlpha, false);
00192         
00193         nh.param<double>("alpha", alpha, 0.0);
00194         
00195         maxTimeDiff = 0.02;
00196 
00197         
00198         return true;
00199 }
00200 
00201 void stereoDepthNode::handle_image_1(const sensor_msgs::ImageConstPtr& msg_ptr, const sensor_msgs::CameraInfoConstPtr& info_msg) {
00202         
00203         ROS_INFO("Entered (handle_image_1)...");
00204         
00205         while (!infoProcessed_1) {
00206                 
00207                 printf("%s::%s << Trying to process info (1) ... \n", __PROGRAM__, __FUNCTION__);
00208                 
00209                 try     {
00210                         // Read in camera matrix
00211                         configData.cameraData1.K = Mat::eye(3, 3, CV_64FC1);
00212                         
00213                         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00214                                 for (unsigned int nnn = 0; nnn < 3; nnn++) {
00215                                         configData.cameraData1.K.at<double>(mmm, nnn) = info_msg->K[3*mmm + nnn];
00216                                 }
00217                         }
00218                         
00219                         cout << configData.cameraData1.K << endl;
00220                         
00221                         configData.cameraData1.cameraSize.width = info_msg->width;
00222                         configData.cameraData1.cameraSize.height = info_msg->height;
00223                         
00224                                                 
00225                         printf("%s << (%d, %d)\n", __FUNCTION__, configData.cameraData1.cameraSize.width, configData.cameraData1.cameraSize.height);
00226                         
00227                         unsigned int maxDistortionIndex;
00228                         if (info_msg->distortion_model == "rational_polynomial") {
00229                                 maxDistortionIndex = 8;
00230                         } else {
00231                                 maxDistortionIndex = 5;
00232                                 if (info_msg->distortion_model != "plumb_bob") {
00233                                         ROS_WARN("Unrecognized distortion model (%s)", info_msg->distortion_model.c_str());
00234                                 }
00235                         }
00236                         
00237                         configData.cameraData1.distCoeffs = Mat::zeros(1, maxDistortionIndex, CV_64FC1);
00238                         
00239                         for (unsigned int iii = 0; iii < maxDistortionIndex; iii++) {
00240                                 configData.cameraData1.distCoeffs.at<double>(0, iii) = info_msg->D[iii];
00241                         }
00242                         
00243                         cout << configData.cameraData1.distCoeffs << endl;
00244                         
00245                         configData.cameraData1.newCamMat = Mat::zeros(3, 3, CV_64FC1);
00246                                         
00247                         
00248                         // bool centerPrincipalPoint = false;
00249                         
00250                         
00251                         
00252                         configData.cameraData1.P = Mat::zeros(3, 4, CV_64FC1);
00253                         
00254                         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00255                                 for (unsigned int nnn = 0; nnn < 4; nnn++) {
00256                                         configData.cameraData1.P.at<double>(mmm, nnn) = info_msg->P[4*mmm + nnn];
00257                                         //cout << "P[" << (3*mmm + nnn) << "] = " << info_msg->P[3*mmm + nnn] << endl;
00258                                 }
00259                         }
00260                         
00261                         cout << "P1 = " << configData.cameraData1.P << endl;
00262                         
00263                         /*
00264                         struct cameraParameters {
00265                                 Mat cameraMatrix;
00266                                 Mat distCoeffs;
00267                                 Mat blankCoeffs;
00268                                 Mat newCamMat;
00269                                 Mat imageSize;
00270                                 Size cameraSize;
00271                                 
00272                                 Mat K, K_inv;
00273                                 
00274                                 bool getCameraParameters(string intrinsics);
00275                                 
00276                         };
00277                         */
00278                 
00279                         //ROS_INFO("Initializing map (1)...");
00280                         
00281                         cout << "R0 = " << R0 << endl;
00282                         
00283                         //configData.cameraData1.newCamMat = getOptimalNewCameraMatrix(configData.cameraData1.K, configData.cameraData1.distCoeffs, configData.cameraData1.cameraSize, configData.alpha, configData.cameraData1.cameraSize, &roi1, centerPrincipalPoint);
00284                         
00285                         //cout << configData.cameraData1.newCamMat << endl;
00286                         //initUndistortRectifyMap(configData.cameraData1.K, configData.cameraData1.distCoeffs, R0, configData.cameraData1.newCamMat, configData.cameraData1.cameraSize, CV_32FC1, map11, map12);
00287                         
00288                         //ROS_INFO("Map (1) initialized.");
00289                         
00290                         //assignDebugCameraInfo();
00291                         
00292                         //printf("%s::%s << Debug data assigned.\n", __PROGRAM__, __FUNCTION__);
00293                         
00294                         /*
00295                         msg_debug.width = configData.cameraData1.cameraSize.width; 
00296                         msg_debug.height = configData.cameraData1.cameraSize.height;
00297                         msg_debug.encoding = "bgr8";
00298                         msg_debug.is_bigendian = false;
00299                         msg_debug.step = configData.cameraData1.cameraSize.width*3;
00300                         msg_debug.data.resize(configData.cameraData1.cameraSize.width*configData.cameraData1.cameraSize.height*3);
00301                         */
00302                         
00303                         //minVal = configData.minLimit;
00304                         //maxVal = configData.maxLimit;
00305                         
00306                         infoProcessed_1 = true;
00307                         
00308                 } catch (...) { // (sensor_msgs::CvBridgeException& e) {
00309                         ROS_ERROR("Some failure in reading in the camera parameters...");
00310                 } 
00311                 
00312         }
00313         
00314         // ROS_WARN("Camera (1) : %f", info_msg->header.stamp.toSec());
00315         
00316         cam_info_1 = *info_msg;
00317         
00318         // Update P matrix:
00319         
00320         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00321                 for (unsigned int nnn = 0; nnn < 4; nnn++) {
00322                         //info_msg->P[4*mmm + nnn] = P0.at<double>(mmm, nnn); 
00323                 }
00324         }
00325         
00326         if (infoProcessed_1) {
00327 
00328                 cv_ptr_1 = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);                                     // For some reason it reads as BGR, not gray
00329 
00330                 //printf("%s << Processing camera 1 image...\n", __FUNCTION__);
00331                 
00332                 Mat newImage(cv_ptr_1->image);
00333                 
00334                 Mat image16, imageDown, greyImX, undistIm;
00335                 cvtColor(newImage, greyImX, CV_RGB2GRAY);
00336                 
00337                 
00338                 //unsigned int lastFrameCount = frameCount_1;
00339                 
00340                 
00341                 if (!matricesAreEqual(greyImX, lastImage_1)) {
00342                         
00343                         //printf("%s::%s << New image (%d)\n", __PROGRAM__, __FUNCTION__, frameCount_1);
00344                         
00345                         elapsedTime = timeElapsedMS(cycle_timer);
00346                         
00347                         greyImX.copyTo(grayImageBuffer_1[frameCount_1 % MAXIMUM_FRAMES_TO_STORE]);
00348 
00349                         if (configData.debugMode) {
00350                                 
00351                                 //imshow("image_1", undistIm);
00352                                 //waitKey(1);
00353                                 
00354                         }
00355                         
00356                         lastImage_1.copyTo(olderImage_1);
00357                         greyImX.copyTo(lastImage_1);
00358                         
00359                         time_buffer_1[frameCount_1 % MAXIMUM_FRAMES_TO_STORE] = info_msg->header.stamp;
00360                         frameCount_1++;
00361                         
00362                         if (_access.try_lock()) {
00363                                 updatePairs();
00364                                 _access.unlock();
00365                         }
00366                         
00367                         if (!firstImProcessed_1) {
00368                                 firstImProcessed_1 = true;
00369                         }
00370                         
00371                         if (firstImProcessed_1 && firstImProcessed_2) {
00372                                 firstPairProcessed = true;
00373                         }
00374 
00375                 } else {
00376                         //printf("%s::%s << Matrices are equal.\n", __PROGRAM__, __FUNCTION__);
00377                         elapsedTime = timeElapsedMS(cycle_timer, false);
00378                 }
00379         }
00380 
00381 }
00382 
00383 void stereoDepthNode::handle_image_2(const sensor_msgs::ImageConstPtr& msg_ptr, const sensor_msgs::CameraInfoConstPtr& info_msg) {
00384                         
00385         while (!infoProcessed_2) {
00386                 
00387                 printf("%s::%s << Trying to process info (1) ... \n", __PROGRAM__, __FUNCTION__);
00388                 
00389                 try     {
00390                         // Read in camera matrix
00391                         configData.cameraData2.K = Mat::eye(3, 3, CV_64FC1);
00392                         
00393                         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00394                                 for (unsigned int nnn = 0; nnn < 3; nnn++) {
00395                                         configData.cameraData2.K.at<double>(mmm, nnn) = info_msg->K[3*mmm + nnn];
00396                                 }
00397                         }
00398                         
00399                         cout << configData.cameraData2.K << endl;
00400                         
00401                         configData.cameraData2.cameraSize.width = info_msg->width;
00402                         configData.cameraData2.cameraSize.height = info_msg->height;
00403                         
00404                                                 
00405                         printf("%s << (%d, %d)\n", __FUNCTION__, configData.cameraData2.cameraSize.width, configData.cameraData2.cameraSize.height);
00406                         
00407                         unsigned int maxDistortionIndex;
00408                         if (info_msg->distortion_model == "rational_polynomial") {
00409                                 maxDistortionIndex = 8;
00410                         } else {
00411                                 maxDistortionIndex = 5;
00412                                 if (info_msg->distortion_model != "plumb_bob") {
00413                                         ROS_WARN("Do not recognize distortion model (%s)", info_msg->distortion_model.c_str());
00414                                 }
00415                         }
00416                         
00417                         configData.cameraData2.distCoeffs = Mat::zeros(1, maxDistortionIndex, CV_64FC1);
00418                         
00419                         for (unsigned int iii = 0; iii < maxDistortionIndex; iii++) {
00420                                 configData.cameraData2.distCoeffs.at<double>(0, iii) = info_msg->D[iii];
00421                         }
00422                         
00423                         cout << configData.cameraData2.distCoeffs << endl;
00424                         
00425                         configData.cameraData2.newCamMat = Mat::zeros(3, 3, CV_64FC1);
00426                         
00427                         //Rect* validPixROI = 0;
00428                         
00429                         //bool centerPrincipalPoint = true;
00430                         
00431                         
00432                         
00433                         configData.cameraData2.P = Mat::zeros(3, 4, CV_64FC1);
00434                         
00435                         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00436                                 for (unsigned int nnn = 0; nnn < 4; nnn++) {
00437                                         configData.cameraData2.P.at<double>(mmm, nnn) = info_msg->P[4*mmm + nnn];
00438                                 }
00439                         }
00440                         
00441                         cout << "P2 = " << configData.cameraData2.P << endl;
00442                         
00443                         /*
00444                         struct cameraParameters {
00445                                 Mat cameraMatrix;
00446                                 Mat distCoeffs;
00447                                 Mat blankCoeffs;
00448                                 Mat newCamMat;
00449                                 Mat imageSize;
00450                                 Size cameraSize;
00451                                 
00452                                 Mat K, K_inv;
00453                                 
00454                                 bool getCameraParameters(string intrinsics);
00455                                 
00456                         };
00457                         */
00458                 
00459                         //ROS_INFO("Initializing map (2)...");
00460                         
00461                         //configData.cameraData2.newCamMat = getOptimalNewCameraMatrix(configData.cameraData2.K, configData.cameraData2.distCoeffs, configData.cameraData2.cameraSize, configData.alpha, configData.cameraData2.cameraSize, &roi2, centerPrincipalPoint);
00462                         
00463                         //cout << configData.cameraData2.newCamMat << endl;
00464                         
00465                         //initUndistortRectifyMap(configData.cameraData2.K, configData.cameraData2.distCoeffs, R1, configData.cameraData2.newCamMat, configData.cameraData2.cameraSize, CV_32FC1, map21, map22);
00466                         
00467                         //ROS_INFO("Map (2) initialized.");
00468                         
00469                         //assignDebugCameraInfo();
00470                         
00471                         //printf("%s::%s << Debug data assigned.\n", __PROGRAM__, __FUNCTION__);
00472                         
00473                         /*
00474                         msg_debug.width = configData.cameraData2.cameraSize.width; 
00475                         msg_debug.height = configData.cameraData2.cameraSize.height;
00476                         msg_debug.encoding = "bgr8";
00477                         msg_debug.is_bigendian = false;
00478                         msg_debug.step = configData.cameraData2.cameraSize.width*3;
00479                         msg_debug.data.resize(configData.cameraData2.cameraSize.width*configData.cameraData2.cameraSize.height*3);
00480                         */
00481                         
00482                         //minVal = configData.minLimit;
00483                         //maxVal = configData.maxLimit;
00484                         
00485                         infoProcessed_2 = true;
00486                         
00487                 } catch (...) { // (sensor_msgs::CvBridgeException& e) {
00488                         ROS_ERROR("Some failure in reading in the camera parameters...");
00489                 }
00490                 
00491         }
00492         
00493         // ROS_WARN("Camera (2) : %f", info_msg->header.stamp.toSec());
00494         
00495         cam_info_2 = *info_msg;
00496         
00497         for (unsigned int mmm = 0; mmm < 3; mmm++) {
00498                 for (unsigned int nnn = 0; nnn < 4; nnn++) {
00499                         //info_msg->P[4*mmm + nnn] = P1.at<double>(mmm, nnn); 
00500                 }
00501         }
00502         
00503         if (infoProcessed_2) {
00504 
00505                 cv_ptr_2 = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);                                     // For some reason it reads as BGR, not gray
00506 
00507                 //printf("%s << Processing camera 2 image...\n", __FUNCTION__);
00508 
00509                 Mat newImage(cv_ptr_2->image);
00510                 
00511                 Mat image16, imageDown, greyImX, undistIm;
00512                 cvtColor(newImage, greyImX, CV_RGB2GRAY);
00513                 
00514                 //unsigned int lastFrameCount = frameCount_2;
00515                 
00516                 if (!matricesAreEqual(greyImX, lastImage_2)) {
00517                         
00518                         //printf("%s::%s << New image (%d)\n", __PROGRAM__, __FUNCTION__, frameCount_2);
00519                         
00520                         elapsedTime = timeElapsedMS(cycle_timer);
00521                         
00522                         greyImX.copyTo(grayImageBuffer_2[frameCount_2 % MAXIMUM_FRAMES_TO_STORE]);
00523 
00524                         if (configData.debugMode) {
00525                                 
00526                                 //imshow("image_2", undistIm);
00527                                 //waitKey(1);
00528                                 
00529                         }
00530                         
00531                         lastImage_2.copyTo(olderImage_2);
00532                         greyImX.copyTo(lastImage_2);
00533                         
00534                         time_buffer_2[frameCount_2 % MAXIMUM_FRAMES_TO_STORE] = info_msg->header.stamp;
00535                         frameCount_2++;
00536                         
00537                         if (_access.try_lock()) {
00538                                 updatePairs();
00539                                 _access.unlock();
00540                         }
00541                         
00542                         if (!firstImProcessed_2) {
00543                                 firstImProcessed_2 = true;
00544                         }
00545                         
00546                         if (firstImProcessed_1 && firstImProcessed_2) {
00547                                 firstPairProcessed = true;
00548                         }
00549 
00550                 } else {
00551                         printf("%s::%s << Matrices are equal.\n", __PROGRAM__, __FUNCTION__);
00552                         elapsedTime = timeElapsedMS(cycle_timer, false);
00553                 }
00554                 
00555         }
00556 
00557 }
00558 
00559 void stereoDepthNode::updatePairs() {
00560         
00561         //ROS_INFO("Entered (updatePairs)...");
00562         
00563         unsigned int maxCam1 = frameCount_1;
00564         unsigned int maxCam2 = frameCount_2;
00565         
00566         if ((checkIndex_1 >= maxCam1) && (checkIndex_2 >= maxCam2)) {
00567                 return;
00568         }
00569         
00570         if ((maxCam1 == 0) || (maxCam2 == 0)) {
00571                 return;
00572         }
00573         
00574         //ROS_INFO("Continuing (updatePairs)...");
00575         
00576         ros::Time time_1 = time_buffer_1[(maxCam1-1) % MAXIMUM_FRAMES_TO_STORE];
00577         ros::Time time_2 = time_buffer_2[(maxCam2-1) % MAXIMUM_FRAMES_TO_STORE];
00578         
00579         // ROS_INFO("maxCam1 = (%d); maxCam2 = (%d) - [%d.%d] [%d.%d]", maxCam1, maxCam2, time_1.sec, time_1.nsec, time_2.sec, time_2.nsec);
00580         
00581         while (checkIndex_1 < maxCam1) {
00582                 
00583                 //ROS_INFO("Looping (1)...");
00584                 
00585                 /*
00586                 if  (duplicateFlags_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE] == 1) {
00587                         checkIndex_1++;
00588                         continue;
00589                 }
00590                 */
00591                 
00592                 double leastDiff = 9e99;
00593                 int bestMatch = -1;
00594                 
00595                 bool candidatesExhausted = false;
00596         
00597                 while ((timeDiff(time_buffer_2[checkIndex_2 % MAXIMUM_FRAMES_TO_STORE], time_buffer_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE]) < configData.maxTimeDiff)) {
00598                         
00599                         //ROS_INFO("Looping (2)...");
00600                         
00601                         if (checkIndex_2 >= (maxCam2-1)) {
00602                                 break;
00603                                 
00604                         }
00605                         
00606                         /*
00607                         if  (duplicateFlags_2[checkIndex_2 % MAXIMUM_FRAMES_TO_STORE] == 1) {
00608                                 checkIndex_2++;
00609                                 continue;
00610                         }
00611                         */
00612                         
00613                         double diff = abs(timeDiff(time_buffer_2[checkIndex_2 % MAXIMUM_FRAMES_TO_STORE], time_buffer_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE]));
00614                         
00615                         if (diff < leastDiff) {
00616                                 leastDiff = diff;
00617                                 bestMatch = checkIndex_2;
00618                         }
00619                         
00620                         checkIndex_2++;
00621                 }
00622                 
00623                 if ((timeDiff(time_buffer_2[checkIndex_2 % MAXIMUM_FRAMES_TO_STORE], time_buffer_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE]) >= configData.maxTimeDiff)) {
00624                         candidatesExhausted = true;
00625                 }
00626                 
00627                 //checkIndex_2 = bestMatch;
00628                 
00629                 if ((leastDiff < configData.maxTimeDiff) && (bestMatch >= 0)) {
00630                         
00631                         //ROS_WARN("Pushing back match (%f)  (%d) [%02d.%04d] and (%d) [%02d.%04d]...", leastDiff, checkIndex_1, times_1.at(checkIndex_1).sec, times_1.at(checkIndex_1).nsec, bestMatch, times_2.at(bestMatch).sec, times_2.at(bestMatch).nsec);
00632                         
00633                         ROS_WARN("Adding pair (%d) & (%d) (%f) [%d.%d] & [%d.%d]", checkIndex_1, bestMatch, leastDiff, time_buffer_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE].sec, time_buffer_1[checkIndex_1 % MAXIMUM_FRAMES_TO_STORE].nsec, time_buffer_2[bestMatch % MAXIMUM_FRAMES_TO_STORE].sec, time_buffer_2[bestMatch % MAXIMUM_FRAMES_TO_STORE].nsec);
00634                         
00635                         validPairs[0].push_back(checkIndex_1);
00636                         checkIndex_1++;
00637                         validPairs[1].push_back(bestMatch);
00638                         
00639                 } else if (candidatesExhausted) { // (checkIndex_2 < (maxCam2-1)) {
00640                         checkIndex_1++;
00641                 } else {
00642                         break;
00643                 }
00644                 
00645         }
00646         
00647         //ROS_INFO("Leaving (updatePairs)...");
00648         
00649 }
00650 
00651 void stereoDepthNode::timed_loop(const ros::TimerEvent& event) {
00652         
00653         //ROS_INFO("Entered (timed_loop)...");
00654         
00655         if (pairsProcessed == validPairs[1].size()) {
00656                 return;
00657         }
00658         
00659         if (infoProcessed_1 && infoProcessed_2) {
00660                 if (alphaChanged) {
00661                         updateMaps();
00662                 }
00663         }
00664         
00665         //printf("%s::%s << Entered...\n", __PROGRAM__, __FUNCTION__);
00666         
00667         stereo_msgs::DisparityImagePtr disp_msg = boost::make_shared<stereo_msgs::DisparityImage>();
00668         
00669         if (firstPairProcessed) {
00670                 
00671                 // printf("%s::%s << 
00672                 
00673                 //stereo_model.fromCameraInfo(cam_info_1, cam_info_2);
00674                 
00675                 
00676                 
00677                 // Prepare disparity message
00678                 disp_msg->header = cam_info_1.header;
00679                 disp_msg->image.header = cam_info_1.header;
00680                 disp_msg->image.height = cam_info_1.height;
00681                 disp_msg->image.width = cam_info_1.width;
00682                 disp_msg->image.encoding = sensor_msgs::image_encodings::TYPE_32FC1;
00683                 disp_msg->image.step = disp_msg->image.width * sizeof(float);
00684                 disp_msg->image.data.resize(disp_msg->image.height * disp_msg->image.step);
00685                 
00686                 int border = sgbm.SADWindowSize / 2;
00687                 int left   = sgbm.numberOfDisparities + sgbm.minDisparity + border - 1;
00688                 int wtf = (sgbm.minDisparity >= 0) ? border + sgbm.minDisparity : std::max(border, -sgbm.minDisparity);
00689                 int right  = disp_msg->image.width - 1 - wtf;
00690                 int top    = border;
00691                 int bottom = disp_msg->image.height - 1 - border;
00692                 
00693                 disp_msg->valid_window.x_offset = left;
00694                 disp_msg->valid_window.y_offset = top;
00695                 disp_msg->valid_window.width    = right - left;
00696                 disp_msg->valid_window.height   = bottom - top;
00697                 
00698                 disp_msg->min_disparity = sgbm.minDisparity;
00699                 disp_msg->max_disparity = sgbm.minDisparity + sgbm.numberOfDisparities - 1;
00700                 disp_msg->delta_d = 1.0 / 16;
00701                 
00702                 //disp_msg->f = stereo_model.right().fx();
00703                 
00704                 disp_msg->f = P0.at<double>(0,0);
00705                 // disp_msg->T = stereo_model.baseline();
00706                 
00707                 disp_msg->T = P0.at<double>(0,3) - P1.at<double>(0,3);
00708                 
00709                 
00710                 
00711                 //firstPair = false;
00712                 
00713                 cv::Mat_<float> disp_image(disp_msg->image.height, disp_msg->image.width, reinterpret_cast<float*>(&disp_msg->image.data[0]), disp_msg->image.step);
00714                 //printf("%s << Processing image pair: (%d, %d)\n", __FUNCTION__, frameCount_1, frameCount_2);
00715         
00716                 elapsedTime = timeElapsedMS(cycle_timer, false);
00717                 
00718                 // Mat imCpy1, imCpy2;
00719                 
00720                 
00721                 
00722                 // Mat image16_1, image16_2, imageDown_1, imageDown_2, undistIm;
00723                 
00724                 //normalize_16(image16_1, grayImageBuffer_1[(frameCount_1-1) % MAXIMUM_FRAMES_TO_STORE], minVal, maxVal);
00725                 //down_level(imageDown_1, image16_1);
00726                 
00727         
00728         //normalize_16(image16_2, grayImageBuffer_2[(frameCount_2-1) % MAXIMUM_FRAMES_TO_STORE], minVal, maxVal);
00729                 //down_level(imageDown_2, image16_2);
00730                 
00731         
00732         //double grad, shift;
00733         
00734         Mat _8bit1, _8bit2;
00735         
00736         //relevelImages(grayImageBuffer_1[(frameCount_1-1) % MAXIMUM_FRAMES_TO_STORE], grayImageBuffer_2[(frameCount_2-1) % MAXIMUM_FRAMES_TO_STORE], disp16, Q, _8bit1, _8bit2, map11, map12, map21, map22);
00737         
00738         ROS_INFO("About to relevel...");
00739         relevelImages(grayImageBuffer_1[(validPairs[0].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE], grayImageBuffer_2[(validPairs[1].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE], disp16, R0, R1, t, Q1, Q2, _8bit1, _8bit2, map11, map12, map21, map22);
00740         
00741         
00742         /*
00743         adaptiveDownsample(grayImageBuffer_1[(frameCount_1-1) % MAXIMUM_FRAMES_TO_STORE], _8bit1);
00744         adaptiveDownsample(grayImageBuffer_2[(frameCount_2-1) % MAXIMUM_FRAMES_TO_STORE], _8bit2);
00745         
00746         remap(_8bit1, undistIm, map11, map12, INTER_LINEAR);
00747                 GaussianBlur(undistIm, imCpy1, Size(7,7), 0.5, 0.5);
00748                 
00749                 remap(_8bit2, undistIm, map21, map22, INTER_LINEAR);
00750         GaussianBlur(undistIm, imCpy2, Size(7,7), 0.5, 0.5);
00751         */
00752         //findRadiometricMapping(grayImageBuffer_1[(frameCount_1-1) % MAXIMUM_FRAMES_TO_STORE], grayImageBuffer_2[(frameCount_2-1) % MAXIMUM_FRAMES_TO_STORE], grad, shift, imCpy1, imCpy2);
00753         
00754         // ROS_INFO("Radiometric mapping: (%f) (%f)", grad, shift);
00755         
00756         
00757                 
00758                 
00759                 
00760                 /*
00761                 imshow("disparity1", image16_1);
00762                 waitKey(1);
00763                 
00764                 imshow("disparity2", image16_2);
00765                 waitKey(1);
00766                 */
00767                 
00768                 sgbm(_8bit1, _8bit2, disp16);
00769                 
00770                 // filterSpeckles(disp16, 1.0, 5, 16.0);
00771                 
00772                 disp16.convertTo(disp_image, CV_32F);
00773                 
00774                 //ros::Time currTime = ros::Time::now();
00775                 
00776                 //ROS_INFO("Publishing disparity message...");
00777                 
00778                 // This time should actually be the average of the two times corresponding to the frame pair...
00779                 //disp_msg->header.stamp = currTime;
00780                 
00781                 ros::Time currTime = findAverageTime(time_buffer_1[(validPairs[0].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE], time_buffer_2[(validPairs[1].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE]);
00782                 disp_msg->header.stamp = currTime;
00783                 
00784                 ROS_ERROR("AveTime = (%d.%d); time_1 = (%d.%d); time_2 = (%d.%d)", currTime.sec, currTime.nsec, time_buffer_1[(validPairs[0].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE].sec, time_buffer_1[(validPairs[0].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE].nsec, time_buffer_2[(validPairs[1].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE].sec, time_buffer_2[(validPairs[1].at(pairsProcessed)) % MAXIMUM_FRAMES_TO_STORE].nsec);
00785                 
00786                 disparityPublisher.publish(disp_msg);
00787                 
00788                 Mat cam1mat, cam2mat;
00789                 
00790                 cvtColor(_8bit1, cam1mat, CV_GRAY2RGB);
00791                 cvtColor(_8bit2, cam2mat, CV_GRAY2RGB);
00792                 
00793                 vector<vector<vector<Point> > > c1, c2;
00794                 
00795                 getContours(_8bit1, c1);
00796                 getContours(_8bit2, c2);
00797                 
00798                 Mat contourDisp(480, 640, CV_16UC1);
00799                 
00800                 depthFromContours(c1, c2, contourDisp);
00801                 
00802                 //imshow("contourDisp", contourDisp);
00803                 //waitKey(1);
00804                 
00805                 printf("%s << contours: (%d, %d)\n", __FUNCTION__, ((int)c1.size()), ((int)c2.size()));
00806                 
00807                 //drawContours(_8bit1, cam1mat);
00808                 //drawContours(_8bit2, cam2mat);
00809                 //drawEpipolarLines(cam1mat, cam2mat, F);
00810                 
00811                 
00812                 
00813                 if (msg_1.width == 0) {
00814                         msg_1.width = cam1mat.cols; 
00815                         msg_1.height = cam1mat.rows;
00816                         msg_1.encoding = "bgr8";
00817                         msg_1.is_bigendian = false;
00818                         msg_1.step = cam1mat.cols*3;
00819                         msg_1.data.resize(cam1mat.cols*cam1mat.rows*cam1mat.channels());
00820                 }
00821                 
00822                 if (msg_2.width == 0) {
00823                         msg_2.width = cam2mat.cols; 
00824                         msg_2.height = cam2mat.rows;
00825                         msg_2.encoding = "bgr8";
00826                         msg_2.is_bigendian = false;
00827                         msg_2.step = cam2mat.cols*3;
00828                         msg_2.data.resize(cam2mat.cols*cam2mat.rows*cam2mat.channels());
00829                 }
00830                 
00831                 //ROS_INFO("Publishing rectified images...");
00832                 msg_1.header.stamp = currTime;
00833                 camera_info_1.header.stamp = currTime;
00834                 std::copy(&(cam1mat.at<Vec3b>(0,0)[0]), &(cam1mat.at<Vec3b>(0,0)[0])+(cam1mat.cols*cam1mat.rows*cam1mat.channels()), msg_1.data.begin());
00835                 cam_pub_1.publish(msg_1, camera_info_1);
00836                 
00837                 msg_2.header.stamp = currTime;
00838                 camera_info_2.header.stamp = currTime;
00839                 std::copy(&(cam2mat.at<Vec3b>(0,0)[0]), &(cam2mat.at<Vec3b>(0,0)[0])+(cam2mat.cols*cam2mat.rows*cam2mat.channels()), msg_2.data.begin());
00840                 cam_pub_2.publish(msg_2, camera_info_2);
00841                 
00842                 //ROS_INFO("Rectified images published.");
00843                 
00844                 /*
00845                 disp16.convertTo(disp8, CV_8U, 255/(numberOfDisparities*16.));
00846                 resize(disp8, disparityImage, cvSize(640, 480));
00847                 imshow("disparityImage", disparityImage);
00848                 waitKey(1);
00849                 */
00850                 
00851                 //publishMaps();
00852                 
00853                 pairsProcessed++;
00854         }
00855         
00856         
00857         
00858         
00859 }
00860 
00861 void stereoDepthNode::publishMaps() {
00862         
00863         if (disp.rows > 0) {
00864                 
00865                 //disp.convertTo(dispFloat, CV_32F);
00866                 
00867                 //dispFloat /= 16.0; 
00868                 
00869                 if (0) { // (firstPair) {
00870         
00871                         //disp_msg->header         = l_info_msg->header;
00872                         //disp_msg->image.header   = l_info_msg->header;
00873                         /*
00874                         disp_msg->image.height   = disp.rows; // disp_msg->image.height   = l_image_msg->height;
00875                         disp_msg->image.width    = disp.cols;
00876                 
00877                         disp_msg->image.encoding = sensor_msgs::image_encodings::TYPE_32FC1;
00878                         disp_msg->image.step     = disp_msg->image.width * sizeof(float);
00879                         disp_msg->image.data.resize(disp_msg->image.height * disp_msg->image.step);
00880                         
00881                         disp_msg->delta_d = 1.0 / 16;
00882                         */
00883                         /*
00884                         printf("%s::%s << Setting up disparity outputs...\n", __PROGRAM__, __FUNCTION__);
00885                         disp_image.height = dispFloat.rows;
00886                         disp_image.width = dispFloat.cols;
00887                         disp_image.encoding = "float32";
00888                         disp_image.is_bigendian = false;
00889                         disp_image.step = dispFloat.cols*sizeof(float);
00890                         disp_image.data.resize(dispFloat.cols*dispFloat.rows*sizeof(float));
00891                         
00892                         disp_object.image = disp_image;
00893                         */
00894                         
00895                         
00896                         // disp_object.f = ...;
00897                         // disp_object.T = ...;
00898                         // disp_object.valid_window = ...;
00899                         // disp_object.min_disparity = ...;
00900                         // disp_object.max_disparity = ...;
00901                         // disp_object.delta_d = ...;
00902                         
00903                         firstPair = false;
00904         
00905         
00906         
00907                 }
00908         }
00909         
00910                 
00911         
00912         if (!firstPair) {
00913                 
00914                 printf("%s::%s << Entering publishing segment...\n", __PROGRAM__, __FUNCTION__);
00915                 
00916                 
00917                 //cv::Mat_<float> disp_image(disp_msg->image.height, disp_msg->image.width, reinterpret_cast<float*>(&disp_msg->image.data[0]), disp_msg->image.step);
00918                 
00919                 // disp_image.header
00920                 // disp_image.data
00921                 
00922                 //std::copy(&(disparityImage.at<float>(0,0)), &(disparityImage.at<float>(0,0))+(disparityImage.cols*disparityImage.rows*3), disp_image.data.begin());
00923                 
00924                 //std::copy(&(dispFloat.at<float>(0,0)), &(dispFloat.at<float>(0,0))+(dispFloat.cols*dispFloat.rows*sizeof(float)), disp_image.data.begin());
00925                 
00926                 //disp_object.image = disp_image;
00927                 
00928                 /*
00929                 unsigned int bytesCopied = 0;
00930                 float val = 0.0;
00931                 for (unsigned int iii = 0; iii < disp.rows; iii++) {
00932                         for (unsigned int jjj = 0; jjj < disp.cols; jjj++) {
00933                                 val = ((float) disparityImage.at<unsigned short>(iii,jjj)) / 16.0;
00934                                 std::copy(&val, &val + 4, disp_object.image.data.begin() + bytesCopied);
00935                                 bytesCopied += 4;
00936                         }
00937                 }
00938                 */
00939                 //std::copy(&(disparityImage.at<float>(0,0)), &(disparityImage.at<float>(0,0))+(disparityImage.cols*disparityImage.rows*3), disp_image.data.begin());
00940                 
00941                 printf("%s::%s << disp_object info: (%d, %d)\n", __PROGRAM__, __FUNCTION__, disp_object.image.height, disp_object.image.width);
00942                 
00943                 //disp_object.image.height = 480;
00944                 //disp_object.image.width = 640;
00945                 // disp_object.header = ...
00946                 
00947                 
00948                 
00949                 // disparityImage
00950                 // std::copy(&(newImage.at<Vec3b>(0,0)[0]), &(newImage.at<Vec3b>(0,0)[0])+(newImage.cols*newImage.rows*3), msg_color.data.begin());
00951                                 
00952                 printf("%s::%s << Publishing depth map...\n", __PROGRAM__, __FUNCTION__);
00953                 //imshow("disp", disp);
00954                 //waitKey(1);
00955                 //disparityPublisher.publish(disp_msg);
00956                 //pub_color.publish(msg_color, camera_info);
00957         }
00958         
00959         
00960         
00961 }
00962 
00963 void stereoDepthNode::updateMaps() {
00964         
00965         ROS_INFO("Updating maps...");
00966         
00967         if (configData.autoAlpha) {
00968                 configData.alpha = findBestAlpha(configData.cameraData1.K, configData.cameraData2.K, configData.cameraData1.distCoeffs, configData.cameraData2.distCoeffs, configData.cameraData1.cameraSize, R0, R1);
00969         }
00970         
00971         //Rect* validPixROI = 0;
00972         bool centerPrincipalPoint = true;
00973         
00974         configData.cameraData1.newCamMat = getOptimalNewCameraMatrix(configData.cameraData1.K, configData.cameraData1.distCoeffs, configData.cameraData1.cameraSize, configData.alpha, configData.cameraData1.cameraSize, &roi1, centerPrincipalPoint);
00975         configData.cameraData2.newCamMat = getOptimalNewCameraMatrix(configData.cameraData2.K, configData.cameraData2.distCoeffs, configData.cameraData2.cameraSize, configData.alpha, configData.cameraData2.cameraSize, &roi2, centerPrincipalPoint);
00976         
00977         ROS_WARN("Adjusting undistortion mappings...");
00978         initUndistortRectifyMap(configData.cameraData1.K, configData.cameraData1.distCoeffs, R0, configData.cameraData1.newCamMat, configData.cameraData1.cameraSize, CV_32FC1, map11, map12);
00979         initUndistortRectifyMap(configData.cameraData2.K, configData.cameraData2.distCoeffs, R1, configData.cameraData2.newCamMat, configData.cameraData2.cameraSize, CV_32FC1, map21, map22);  
00980         
00981         alphaChanged = false;
00982         
00983 }
00984 
00985 
00986 void stereoDepthNode::serverCallback(thermalvis::depthConfig &config, uint32_t level) {
00987         
00988   ROS_INFO("Reconfigure Request: (%1.2f | [%d])", 
00989         config.alpha,
00990         config.autoAlpha);
00991 
00992         
00993         if ((config.autoAlpha != configData.autoAlpha) || ((!config.autoAlpha) && (config.alpha != configData.alpha))) {
00994   
00995                 configData.autoAlpha = config.autoAlpha;
00996                 configData.alpha = config.alpha;
00997                 
00998                 alphaChanged = true;
00999                 
01000                 ROS_WARN("About to try and update maps...");
01001                 if (infoProcessed_1 && infoProcessed_2) {
01002                         ROS_WARN("Updating maps...");
01003                         updateMaps();
01004                 }
01005                 
01006         } else {
01007                 configData.alpha = config.alpha;
01008         }
01009         
01010       
01011 
01012 }


thermalvis
Author(s): Stephen Vidas
autogenerated on Sun Jan 5 2014 11:38:44