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
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
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
00084
00085 enum { STEREO_BM=0, STEREO_SGBM=1, STEREO_HH=2 };
00086 int alg = STEREO_HH;
00087
00088 SADWindowSize = 5;
00089 numberOfDisparities = 0;
00090 sgbm.preFilterCap = 31;
00091 sgbm.SADWindowSize = SADWindowSize > 0 ? SADWindowSize : 3;
00092
00093
00094 int cn = 1;
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
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
00153
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
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
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
00258 }
00259 }
00260
00261 cout << "P1 = " << configData.cameraData1.P << endl;
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 cout << "R0 = " << R0 << endl;
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 infoProcessed_1 = true;
00307
00308 } catch (...) {
00309 ROS_ERROR("Some failure in reading in the camera parameters...");
00310 }
00311
00312 }
00313
00314
00315
00316 cam_info_1 = *info_msg;
00317
00318
00319
00320 for (unsigned int mmm = 0; mmm < 3; mmm++) {
00321 for (unsigned int nnn = 0; nnn < 4; nnn++) {
00322
00323 }
00324 }
00325
00326 if (infoProcessed_1) {
00327
00328 cv_ptr_1 = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);
00329
00330
00331
00332 Mat newImage(cv_ptr_1->image);
00333
00334 Mat image16, imageDown, greyImX, undistIm;
00335 cvtColor(newImage, greyImX, CV_RGB2GRAY);
00336
00337
00338
00339
00340
00341 if (!matricesAreEqual(greyImX, lastImage_1)) {
00342
00343
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
00352
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
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
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
00428
00429
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
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 infoProcessed_2 = true;
00486
00487 } catch (...) {
00488 ROS_ERROR("Some failure in reading in the camera parameters...");
00489 }
00490
00491 }
00492
00493
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
00500 }
00501 }
00502
00503 if (infoProcessed_2) {
00504
00505 cv_ptr_2 = cv_bridge::toCvCopy(msg_ptr, enc::BGR8);
00506
00507
00508
00509 Mat newImage(cv_ptr_2->image);
00510
00511 Mat image16, imageDown, greyImX, undistIm;
00512 cvtColor(newImage, greyImX, CV_RGB2GRAY);
00513
00514
00515
00516 if (!matricesAreEqual(greyImX, lastImage_2)) {
00517
00518
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
00527
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
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
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
00580
00581 while (checkIndex_1 < maxCam1) {
00582
00583
00584
00585
00586
00587
00588
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
00600
00601 if (checkIndex_2 >= (maxCam2-1)) {
00602 break;
00603
00604 }
00605
00606
00607
00608
00609
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
00628
00629 if ((leastDiff < configData.maxTimeDiff) && (bestMatch >= 0)) {
00630
00631
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) {
00640 checkIndex_1++;
00641 } else {
00642 break;
00643 }
00644
00645 }
00646
00647
00648
00649 }
00650
00651 void stereoDepthNode::timed_loop(const ros::TimerEvent& event) {
00652
00653
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
00666
00667 stereo_msgs::DisparityImagePtr disp_msg = boost::make_shared<stereo_msgs::DisparityImage>();
00668
00669 if (firstPairProcessed) {
00670
00671
00672
00673
00674
00675
00676
00677
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
00703
00704 disp_msg->f = P0.at<double>(0,0);
00705
00706
00707 disp_msg->T = P0.at<double>(0,3) - P1.at<double>(0,3);
00708
00709
00710
00711
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
00715
00716 elapsedTime = timeElapsedMS(cycle_timer, false);
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 Mat _8bit1, _8bit2;
00735
00736
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
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 sgbm(_8bit1, _8bit2, disp16);
00769
00770
00771
00772 disp16.convertTo(disp_image, CV_32F);
00773
00774
00775
00776
00777
00778
00779
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
00803
00804
00805 printf("%s << contours: (%d, %d)\n", __FUNCTION__, ((int)c1.size()), ((int)c2.size()));
00806
00807
00808
00809
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
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
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 pairsProcessed++;
00854 }
00855
00856
00857
00858
00859 }
00860
00861 void stereoDepthNode::publishMaps() {
00862
00863 if (disp.rows > 0) {
00864
00865
00866
00867
00868
00869 if (0) {
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
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
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941 printf("%s::%s << disp_object info: (%d, %d)\n", __PROGRAM__, __FUNCTION__, disp_object.image.height, disp_object.image.width);
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 printf("%s::%s << Publishing depth map...\n", __PROGRAM__, __FUNCTION__);
00953
00954
00955
00956
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
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 }