00001 #include "shape_reconstruction/SRUtils.h"
00002
00003 #include <opencv2/imgproc/imgproc.hpp>
00004 #include <opencv2/video/tracking.hpp>
00005 #include <opencv2/highgui/highgui.hpp>
00006 #include <opencv2/video/tracking.hpp>
00007
00008 #include "shape_reconstruction/RangeImagePlanar.hpp"
00009
00010 typedef unsigned char uint8_t;
00011
00012 namespace omip
00013 {
00014 void RangeImagePlanar2DepthMap(const pcl::RangeImagePlanar::Ptr& rip, cv::Mat& depth_map_mat)
00015 {
00016 for(int i=0; i<IMG_WIDTH; i++)
00017 {
00018 for(int j=0; j<IMG_HEIGHT; j++)
00019 {
00020 depth_map_mat.at< float >(j,i) = rip->points.at(j*IMG_WIDTH+i).z;
00021 }
00022 }
00023 }
00024
00025 void RangeImagePlanar2PointCloud(const pcl::RangeImagePlanar::Ptr& rip, SRPointCloud::Ptr& pc)
00026 {
00027 for(int i=0; i<IMG_WIDTH; i++)
00028 {
00029 for(int j=0; j<IMG_HEIGHT; j++)
00030 {
00031 pc->points.at(j*IMG_WIDTH+i).x = rip->points.at(j*IMG_WIDTH+i).x;
00032 pc->points.at(j*IMG_WIDTH+i).y = rip->points.at(j*IMG_WIDTH+i).y;
00033 pc->points.at(j*IMG_WIDTH+i).z = rip->points.at(j*IMG_WIDTH+i).z;
00034 }
00035 }
00036 }
00037
00038 void OrganizedPC2DepthMap(const SRPointCloud::Ptr organized_pc, cv::Mat& depth_map_mat)
00039 {
00040 float* data_ptr = (float*)depth_map_mat.data;
00041 size_t elem_step = depth_map_mat.step / sizeof(float);
00042
00043
00044
00045 for(int v=0; v< organized_pc->height; v++)
00046 {
00047 for(int u=0; u< organized_pc->width; u++)
00048 {
00049 if(pcl::isFinite(organized_pc->points[v*organized_pc->width + u]))
00050 data_ptr[v*elem_step + u] = organized_pc->points[v*organized_pc->width + u].z;
00051 else
00052 data_ptr[v*elem_step + u] = nanf("");
00053 }
00054 }
00055 }
00056
00057 void OrganizedPC2DepthMapAlternative(const SRPointCloud::Ptr organized_pc, const cv::Ptr<cv::Mat>& depth_map_mat_ptr)
00058 {
00059 float* data_ptr = (float*)depth_map_mat_ptr->data;
00060 size_t elem_step = depth_map_mat_ptr->step / sizeof(float);
00061
00062 for(int v=0; v< organized_pc->height; v++)
00063 {
00064 for(int u=0; u< organized_pc->width; u++)
00065 {
00066 if(pcl::isFinite(organized_pc->points[v*organized_pc->width + u]))
00067 data_ptr[v*elem_step + u] = organized_pc->points[v*organized_pc->width + u].z;
00068 else
00069 data_ptr[v*elem_step + u] = nanf("");
00070 }
00071 }
00072 }
00073
00074 void OrganizedPC2ColorMap(const SRPointCloud::Ptr organized_pc, cv::Mat& depth_map_mat)
00075 {
00076 for (int h=0; h<depth_map_mat.rows; h++) {
00077 for (int w=0; w<depth_map_mat.cols; w++) {
00078 pcl::PointXYZRGB point = organized_pc->at(w, h);
00079
00080 Eigen::Vector3i rgb = point.getRGBVector3i();
00081
00082 depth_map_mat.at<cv::Vec3b>(h,w)[0] = rgb[2];
00083 depth_map_mat.at<cv::Vec3b>(h,w)[1] = rgb[1];
00084 depth_map_mat.at<cv::Vec3b>(h,w)[2] = rgb[0];
00085 }
00086 }
00087 }
00088
00089 void UnorganizedPC2DepthMap(const SRPointCloud::Ptr& organized_pc,
00090 const int& width,
00091 const int& height,
00092 cv::Mat& depth_map,
00093 ::shape_reconstruction::RangeImagePlanar::Ptr& rip,
00094 const float& noiseLevel,
00095 const float& minRange) {
00096 Eigen::Affine3f sensor_pose;
00097 sensor_pose.matrix() = Eigen::Matrix4f::Identity();
00098 pcl::RangeImagePlanar::CoordinateFrame coordinate_frame = pcl::RangeImagePlanar::CAMERA_FRAME;
00099
00100 rip->createFromPointCloudWithFixedSizeAndStorePoints(*organized_pc,
00101 width,
00102 height,
00103 width/2 -0.5,
00104 height/2 - 0.5,
00105 525, 525,
00106 sensor_pose,
00107 coordinate_frame,
00108 noiseLevel,
00109 minRange);
00110
00111 RangeImagePlanar2DepthMap(rip, depth_map);
00112 }
00113
00114 void DepthImage2CvImage(const cv::Mat& depth_image_raw, sensor_msgs::ImagePtr& depth_msg) {
00115 cv::Mat depth_image(depth_image_raw.rows, depth_image_raw.cols, CV_8UC1);
00116 cv::convertScaleAbs(depth_image_raw, depth_image, 100, 0);
00117 depth_msg = cv_bridge::CvImage(std_msgs::Header(), "mono8", depth_image).toImageMsg();
00118 }
00119
00120 void Image8u2Indices(const cv::Mat& image_8u, pcl::PointIndices::Ptr indices_ptr)
00121 {
00122 int total_count = 0;
00123 int indices_count = 0;
00124 indices_ptr->indices.clear();
00125 for(int j=0; j<image_8u.rows; j++)
00126 {
00127 for(int i=0; i<image_8u.cols; i++)
00128 {
00129 if(image_8u.at<uchar>(j,i))
00130 {
00131 indices_ptr->indices.push_back(j*image_8u.cols + i);
00132 indices_count++;
00133 }
00134 total_count++;
00135 }
00136 }
00137
00138 }
00139
00140 void Indices2Image8u(const std::vector<int>& indices, cv::Mat& image_8u)
00141 {
00142 image_8u.setTo(0);
00143 for(int i=0; i<indices.size() ; i++)
00144 {
00145 image_8u.at<uchar>(floor(indices.at(i)/image_8u.cols),indices.at(i)%image_8u.cols) = 255;
00146 }
00147
00148 }
00149
00150 void drawOptFlowMap(const cv::Mat& flow, cv::Mat& cflowmap, int step,
00151 double scale, const cv::Scalar& color)
00152 {
00153 for(int y = 0; y < cflowmap.rows; y += step)
00154 for(int x = 0; x < cflowmap.cols; x += step)
00155 {
00156 const cv::Point2f& fxy = flow.at<cv::Point2f>(y, x);
00157 line(cflowmap, cv::Point(x,y), cv::Point(cvRound(x+fxy.x), cvRound(y+fxy.y)),
00158 color);
00159 circle(cflowmap, cv::Point(x,y), 2, color, -1);
00160 }
00161 }
00162
00163 void drawOpticalFlowModule(const cv::Mat& optical_flow, cv::Mat& optical_flow_module)
00164 {
00165 if((optical_flow_module.cols != optical_flow.cols) || (optical_flow_module.rows != optical_flow.rows))
00166 {
00167 ROS_ERROR_STREAM_NAMED("drawOpticalFlowModule", "The sizes of the optical flow and the optical flow module images are different!");
00168 return;
00169 }
00170
00171 for(int j = 0; j < optical_flow_module.rows; j++)
00172 {
00173 for(int i = 0; i < optical_flow_module.cols; i++)
00174 {
00175 const cv::Point2f& flow_ij = optical_flow.at<cv::Point2f>(j, i);
00176 optical_flow_module.at<float>(j, i) = std::sqrt(flow_ij.x*flow_ij.x + flow_ij.y*flow_ij.y);
00177 }
00178 }
00179 }
00180
00181 cv::Mat filled_img_full;
00182 ros::Time previous_query_time;
00183
00184 void fillNaNsCBF(const sensor_msgs::Image& color_img, const cv::Mat& depth_img, cv::Mat& filled_depth_img, ros::Time query_time)
00185 {
00186 if(query_time == previous_query_time)
00187 {
00188 filled_depth_img = filled_img_full;
00189 }else{
00190 cv_bridge::CvImagePtr cv_ptr;
00191 cv_ptr = cv_bridge::toCvCopy(color_img, color_img.encoding);
00192
00193 cv::Mat cv_gray;
00194 cv::cvtColor(cv_ptr->image, cv_gray, CV_RGB2GRAY);
00195
00196
00197
00198 filled_img_full = fill_depth_cbf(cv_gray, depth_img, 0, 0);
00199
00200 depth_img.copyTo(filled_depth_img);
00201 filled_img_full.copyTo(filled_depth_img, depth_img!=depth_img);
00202
00203 previous_query_time = query_time;
00204 }
00205 }
00206
00207 void removeDuplicateIndices(std::vector<int>& vec) {
00208 std::set<int> s;
00209 unsigned size = vec.size();
00210 for( unsigned i = 0; i < size; ++i ) s.insert( vec[i] );
00211 vec.assign( s.begin(), s.end() );
00212 }
00213
00214
00215
00216
00217 #define PI 3.14159
00218
00219 #define MAX_UCHAR 255
00220
00221
00222 #define FILTER_RAD 5
00223 #define FILTER_LEN 11
00224 #define FILTER_SIZE 121
00225
00226 void toc(const char* message, clock_t start) {
00227 #ifdef DEBUG
00228 double d = clock() - start;
00229 d = 1000 * d / CLOCKS_PER_SEC;
00230 printf("[%s] %10.0f\n", message, d);
00231 #endif
00232 }
00233
00234
00235
00236 void create_offset_array(int* offsets_h, int img_height) {
00237 int kk = 0;
00238 for (int yy = -FILTER_RAD; yy <= FILTER_RAD; ++yy) {
00239 for (int xx = -FILTER_RAD; xx <= FILTER_RAD; ++xx, ++kk) {
00240 offsets_h[kk] = yy + img_height * xx;
00241 }
00242 }
00243 }
00244
00245 void calc_pyr_sizes(int* heights, int* widths, int* pyr_offsets) {
00246 int offset = 0;
00247 for (int scale = 0; scale < NUM_SCALES; ++scale) {
00248 pyr_offsets[scale] = offset;
00249
00250
00251 heights[scale] = static_cast<int>(IMG_HEIGHT / pow((float)2, scale));
00252 widths[scale] = static_cast<int>(IMG_WIDTH / pow((float)2, scale));
00253 offset += heights[scale] * widths[scale];
00254 }
00255
00256 #ifdef DEBUG
00257 for (int ii = 0; ii < NUM_SCALES; ++ii) {
00258 printf("Scale %d: [%d x %d], offset=%d\n", ii, heights[ii], widths[ii], pyr_offsets[ii]);
00259 }
00260 #endif
00261 }
00262
00263 int get_pyr_size(int* heights, int* widths) {
00264 int total_pixels = 0;
00265 for (int ii = 0; ii < NUM_SCALES; ++ii) {
00266 total_pixels += heights[ii] * widths[ii];
00267 }
00268 return total_pixels;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 void upsample_cpu(float* depth_dst,
00280 bool* mask_dst,
00281 bool* valid_dst,
00282 float* depth_src,
00283 float* result_src,
00284 bool* mask_src,
00285 bool* valid_src,
00286 int height_src,
00287 int width_src,
00288 int height_dst,
00289 int width_dst,
00290 int dst_img_ind) {
00291
00292 int num_threads = height_dst * width_dst;
00293
00294
00295 if (!mask_dst[dst_img_ind]) {
00296 return;
00297 }
00298
00299 int x_dst = static_cast<int>(floorf((float) dst_img_ind / height_dst));
00300 int y_dst = static_cast<int>(fmodf(dst_img_ind, height_dst));
00301
00302 int y_src = static_cast<int>((float) y_dst * height_src / height_dst);
00303 int x_src = static_cast<int>((float) x_dst * width_src / width_dst);
00304
00305
00306 int src_img_ind = y_src + height_src * x_src;
00307
00308 if (!mask_src[src_img_ind]) {
00309 depth_dst[dst_img_ind] = depth_src[src_img_ind];
00310 } else {
00311 depth_dst[dst_img_ind] = result_src[src_img_ind];
00312 }
00313
00314 valid_dst[dst_img_ind] = valid_src[src_img_ind];
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 void cbf_cpu(const float* depth, const float* intensity, bool* is_missing,
00334 bool* valid_in, bool* valid_out, float* result,
00335 const int* abs_inds,
00336 const int* offsets,
00337 const float* gaussian_space,
00338 int height,
00339 int width,
00340 float sigma_s,
00341 float sigma_r,
00342 int numThreads,
00343 int idx) {
00344
00345 int abs_ind = abs_inds[idx];
00346
00347 int src_Y = abs_ind % height;
00348 int src_X = abs_ind / height;
00349
00350 float weight_sum = 0;
00351 float value_sum = 0;
00352
00353 float weight_intensity_sum = 0;
00354
00355 float gaussian_range[FILTER_SIZE];
00356 float gaussian_range_sum = 0;
00357
00358 for (int ii = 0; ii < FILTER_SIZE; ++ii) {
00359
00360
00361
00362 int abs_offset = abs_ind + offsets[ii];
00363
00364 int dst_Y = abs_offset % height;
00365 int dst_X = abs_offset / height;
00366
00367 if (abs_offset < 0 || abs_offset >= (height * width)
00368 || abs(src_Y-dst_Y) > FILTER_RAD || abs(src_X-dst_X) > FILTER_RAD) {
00369 continue;
00370
00371
00372
00373
00374 } else if (is_missing[abs_offset] && !valid_in[abs_offset]) {
00375 continue;
00376 }
00377
00378 float vv = intensity[abs_offset] - intensity[abs_ind];
00379
00380 gaussian_range[ii] = exp(-(vv * vv) / (2*sigma_r * sigma_r));
00381 gaussian_range_sum += gaussian_range[ii];
00382 }
00383
00384 int count = 0;
00385
00386 for (int ii = 0; ii < FILTER_SIZE; ++ii) {
00387
00388 int abs_offset = abs_ind + offsets[ii];
00389 int dst_Y = abs_offset % height;
00390 int dst_X = abs_offset / height;
00391 if (abs_offset < 0 || abs_offset >= (height * width)
00392 || abs(src_Y-dst_Y) > FILTER_RAD || abs(src_X-dst_X) > FILTER_RAD) {
00393 continue;
00394 } else if (is_missing[abs_offset] && !valid_in[abs_offset]) {
00395 continue;
00396 }
00397
00398 ++count;
00399
00400 weight_sum += gaussian_space[ii] * gaussian_range[ii];
00401 value_sum += depth[abs_offset] * gaussian_space[ii] * gaussian_range[ii];
00402 }
00403
00404 if (weight_sum == 0) {
00405 return;
00406 }
00407
00408 if (isnan(weight_sum)) {
00409 printf("*******************\n");
00410 printf(" Weight sum is NaN\n");
00411 printf("*******************\n");
00412 }
00413
00414 value_sum /= weight_sum;
00415 result[abs_ind] = value_sum;
00416 valid_out[abs_ind] = 1;
00417 }
00418
00419
00420
00421 void create_spatial_gaussian(float sigma_s, float* gaussian_h) {
00422 float sum = 0;
00423 int kk = 0;
00424 for (int yy = -FILTER_RAD; yy <= FILTER_RAD; ++yy) {
00425 for (int xx = -FILTER_RAD; xx <= FILTER_RAD; ++xx, ++kk) {
00426 gaussian_h[kk] = exp(-(xx*xx + yy*yy) / (2*sigma_s * sigma_s));
00427 sum += gaussian_h[kk];
00428 }
00429 }
00430
00431 for (int ff = 0; ff < FILTER_SIZE; ++ff) {
00432 gaussian_h[ff] /= sum;
00433 }
00434 }
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int get_missing_pixel_coords(int height, int width, bool* mask, int* abs_inds_to_filter_h) {
00446 int num_pixels = height * width;
00447
00448 int num_missing_pixels = 0;
00449 for (int nn = 0; nn < num_pixels; ++nn) {
00450 if (mask[nn]) {
00451 abs_inds_to_filter_h[num_missing_pixels] = nn;
00452 ++num_missing_pixels;
00453 }
00454 }
00455
00456 return num_missing_pixels;
00457 }
00458
00459 static void savePGM(bool* imf, const char *name, int height, int width) {
00460 uint8_t im[IMG_HEIGHT * IMG_WIDTH];
00461
00462 for (int nn = 0; nn < IMG_HEIGHT * IMG_HEIGHT; ++nn) {
00463
00464 int y = nn % height;
00465 int x = static_cast<int>(floor(nn / static_cast<double>(height)));
00466
00467
00468 int mm = y * width + x;
00469 im[mm] = uint8_t(255*imf[nn]);
00470 }
00471
00472 std::ofstream file(name, std::ios::out | std::ios::binary);
00473
00474 file << "P5\n" << width << " " << height << "\n" << MAX_UCHAR << "\n";
00475 file.write((char *)&im, width * height * sizeof(uint8_t));
00476 }
00477
00478 static void savePGM(float* imf, const char *name, int height, int width) {
00479 uint8_t im[IMG_HEIGHT * IMG_WIDTH];
00480
00481 for (int nn = 0; nn < IMG_HEIGHT * IMG_WIDTH; ++nn) {
00482
00483 int y = nn % height;
00484 int x = static_cast<int>(floor(nn / static_cast<double>(height)));
00485
00486
00487 int mm = y * width + x;
00488
00489 im[mm] = uint8_t(255*imf[nn]);
00490 }
00491
00492 std::ofstream file(name, std::ios::out | std::ios::binary);
00493
00494 file << "P5\n" << width << " " << height << "\n" << MAX_UCHAR << "\n";
00495 file.write((char *)&im, width * height * sizeof(uint8_t));
00496 }
00497
00498 void filter_at_scale(float* depth_h,
00499 float* intensity_h,
00500 bool* mask_h,
00501 bool* valid_h,
00502 float* result_h,
00503 int* abs_inds_to_filter_h,
00504 int height,
00505 int width,
00506 float sigma_s,
00507 float sigma_r) {
00508
00509
00510 int* offsets_h = (int*) malloc(FILTER_SIZE * sizeof(int));
00511 create_offset_array(offsets_h, height);
00512
00513
00514 float* gaussian_h = (float*) malloc(FILTER_SIZE * sizeof(float));
00515 create_spatial_gaussian(sigma_s, gaussian_h);
00516
00517
00518
00519
00520
00521
00522
00523 int num_missing_pixels = get_missing_pixel_coords(height, width, mask_h, abs_inds_to_filter_h);
00524 printf("[Depth filling with CBF. INFO] Num NaN depth values at this resolution scale: %d\n", num_missing_pixels);
00525
00526 clock_t start_filter = clock();
00527
00528
00529 bool* valid_in = (bool*) malloc(height * width * sizeof(bool));
00530 for (int i = 0; i < height * width; ++i) {
00531 valid_in[i] = valid_h[i];
00532 }
00533
00534 for (int i = 0; i < num_missing_pixels; ++i) {
00535 cbf_cpu(depth_h,
00536 intensity_h,
00537 mask_h,
00538 valid_in,
00539 valid_h,
00540 result_h,
00541 abs_inds_to_filter_h,
00542 offsets_h,
00543 gaussian_h,
00544 height,
00545 width,
00546 sigma_s,
00547 sigma_r,
00548 num_missing_pixels,
00549 i);
00550 }
00551
00552 toc("FILTER OP", start_filter);
00553
00554 free(valid_in);
00555 free(offsets_h);
00556 free(gaussian_h);
00557 }
00558
00559 void cbf(uint8_t* depth, uint8_t* intensity, bool* mask_h, uint8_t* result, double* sigma_s, double* sigma_r)
00560 {
00561
00562 clock_t start_func = clock();
00563
00564 int pyr_heights[NUM_SCALES];
00565 int pyr_widths[NUM_SCALES];
00566 int pyr_offsets[NUM_SCALES];
00567 calc_pyr_sizes(&pyr_heights[0], &pyr_widths[0], &pyr_offsets[0]);
00568
00569
00570
00571
00572 int N = IMG_HEIGHT * IMG_WIDTH;
00573 int* abs_inds_to_filter_h = (int*) malloc(N * sizeof(int));
00574
00575 int pyr_size = get_pyr_size(&pyr_heights[0], &pyr_widths[0]);
00576
00577
00578
00579
00580 clock_t start_pyr = clock();
00581
00582
00583 float* depth_ms_h = (float*) malloc(pyr_size * sizeof(float));
00584 float* intensity_ms_h = (float*) malloc(pyr_size * sizeof(float));
00585 bool* mask_ms_h = (bool*) malloc(pyr_size * sizeof(bool));
00586 float* result_ms_h = (float*) malloc(pyr_size * sizeof(float));
00587 bool* valid_ms_h = (bool*) malloc(pyr_size * sizeof(bool));
00588
00589 for (int nn = 0; nn < N; ++nn)
00590 {
00591 depth_ms_h[nn] = depth[nn] / 255.0f;
00592 intensity_ms_h[nn] = intensity[nn] / 255.0f;
00593 mask_ms_h[nn] = mask_h[nn];
00594 valid_ms_h[nn] = !mask_h[nn];
00595 result_ms_h[nn] = 0;
00596 }
00597
00598 float* depth_ms_h_p = depth_ms_h + pyr_offsets[1];
00599 float* intensity_ms_h_p = intensity_ms_h + pyr_offsets[1];
00600 bool* mask_ms_h_p = mask_ms_h + pyr_offsets[1];
00601 bool* valid_ms_h_p = valid_ms_h + pyr_offsets[1];
00602 float* result_ms_h_p = result_ms_h + pyr_offsets[1];
00603
00604 for (unsigned int scale = 1; scale < NUM_SCALES; ++scale) {
00605 for (int xx = 0; xx < pyr_widths[scale]; ++xx) {
00606 for (int yy = 0; yy < pyr_heights[scale]; ++yy, ++depth_ms_h_p, ++intensity_ms_h_p, ++mask_ms_h_p, ++result_ms_h_p, ++valid_ms_h_p) {
00607 int abs_yy = static_cast<int>(((float)yy / pyr_heights[scale]) * IMG_HEIGHT);
00608 int abs_xx = static_cast<int>(((float)xx / pyr_widths[scale]) * IMG_WIDTH);
00609 int img_offset = abs_yy + IMG_HEIGHT * abs_xx;
00610 *depth_ms_h_p = depth_ms_h[img_offset];
00611 *intensity_ms_h_p = intensity_ms_h[img_offset];
00612 *mask_ms_h_p = mask_h[img_offset];
00613 *valid_ms_h_p = !mask_h[img_offset];
00614 *result_ms_h_p = 0;
00615 }
00616 }
00617 }
00618
00619
00620
00621
00622
00623 for (int scale = NUM_SCALES - 1; scale >= 0; --scale) {
00624
00625
00626 #ifdef DEBUG
00627 char filename1[50];
00628 sprintf(filename1, "missing_pixels_before_filtering_scale%d.pgm", scale);
00629
00630 savePGM(mask_ms_h + pyr_offsets[scale], filename1, pyr_heights[scale], pyr_widths[scale]);
00631
00632 char filename2[50];
00633 sprintf(filename2, "valid_pixels_before_filtering_scale%d.pgm", scale);
00634
00635 savePGM(valid_ms_h + pyr_offsets[scale], filename2, pyr_heights[scale], pyr_widths[scale]);
00636
00637 sprintf(filename2, "valid_intensity_before_filtering_scale%d.pgm", scale);
00638
00639 savePGM(intensity_ms_h + pyr_offsets[scale], filename2, pyr_heights[scale], pyr_widths[scale]);
00640
00641 sprintf(filename2, "depth_before_filtering_scale%d.pgm", scale);
00642
00643 savePGM(depth_ms_h + pyr_offsets[scale], filename2, pyr_heights[scale], pyr_widths[scale]);
00644 #endif
00645
00646 filter_at_scale(depth_ms_h + pyr_offsets[scale],
00647 intensity_ms_h + pyr_offsets[scale],
00648 mask_ms_h + pyr_offsets[scale],
00649 valid_ms_h + pyr_offsets[scale],
00650 result_ms_h + pyr_offsets[scale],
00651 abs_inds_to_filter_h,
00652 pyr_heights[scale],
00653 pyr_widths[scale],
00654 sigma_s[scale],
00655 sigma_r[scale]);
00656
00657
00658 #ifdef DEBUG
00659 sprintf(filename2, "valid_pixels_after_filtering_scale%d.pgm", scale);
00660
00661 savePGM(valid_ms_h + pyr_offsets[scale], filename2, pyr_heights[scale], pyr_widths[scale]);
00662 #endif
00663
00664 #ifdef DEBUG
00665 char filename[50];
00666 sprintf(filename, "depth_after_filtering_scale%d.pgm", scale);
00667
00668 savePGM(result_ms_h + pyr_offsets[scale], filename, pyr_heights[scale], pyr_widths[scale]);
00669 #endif
00670
00671 if (scale == 0) {
00672 continue;
00673 }
00674
00675
00676
00677 int num_missing_pixels = pyr_heights[scale-1] * pyr_widths[scale-1];
00678
00679
00680 for (int i = 0; i < num_missing_pixels; ++i) {
00681 upsample_cpu(depth_ms_h + pyr_offsets[scale-1],
00682 mask_ms_h + pyr_offsets[scale-1],
00683 valid_ms_h + pyr_offsets[scale-1],
00684 depth_ms_h + pyr_offsets[scale],
00685 result_ms_h + pyr_offsets[scale],
00686 mask_ms_h + pyr_offsets[scale],
00687 valid_ms_h + pyr_offsets[scale],
00688 pyr_heights[scale],
00689 pyr_widths[scale],
00690 pyr_heights[scale-1],
00691 pyr_widths[scale-1],
00692 i);
00693 }
00694
00695
00696 #ifdef DEBUG
00697 sprintf(filename, "up_depth_after_filtering_scale%d.pgm", scale);
00698
00699 savePGM(depth_ms_h + pyr_offsets[scale-1], filename, pyr_heights[scale-1], pyr_widths[scale-1]);
00700
00701 sprintf(filename, "up_valid_after_filtering_scale%d.pgm", scale);
00702
00703 savePGM(valid_ms_h + pyr_offsets[scale-1], filename, pyr_heights[scale-1], pyr_widths[scale-1]);
00704 #endif
00705 }
00706
00707
00708 for (int nn = 0; nn < N; ++nn) {
00709 if (mask_ms_h[nn]) {
00710 result[nn] = static_cast<uint8_t>(result_ms_h[nn] * 255);
00711 } else {
00712 result[nn] = depth[nn];
00713 }
00714 }
00715
00716 free(depth_ms_h);
00717 free(intensity_ms_h);
00718 free(mask_ms_h);
00719 free(result_ms_h);
00720 free(valid_ms_h);
00721 free(abs_inds_to_filter_h);
00722
00723 toc("Entire Function", start_func);
00724 }
00725
00726 cv::Mat fill_depth_cbf(cv::Mat imgRgb, cv::Mat imgDepthAbs, double* spaceSigmas, double* rangeSigmas)
00727 {
00728 double spaceSigmas_default[3];
00729 spaceSigmas_default[0] = 12;
00730 spaceSigmas_default[1] = 5;
00731 spaceSigmas_default[2] = 8;
00732
00733 double rangeSigmas_default[3];
00734 rangeSigmas_default[0] = 0.2;
00735 rangeSigmas_default[1] = 0.08;
00736 rangeSigmas_default[2] = 0.02;
00737
00738
00739 cv::Mat imgIsNoise = imgDepthAbs != imgDepthAbs;
00740 cv::Mat imgIsNotNoise = imgDepthAbs == imgDepthAbs;
00741
00742 double min, max;
00743 cv::minMaxLoc(imgDepthAbs, &min, &max, 0, 0, imgIsNotNoise);
00744
00745
00746 cv::Mat imgDepth = (255/max) * imgDepthAbs;
00747 imgDepth.setTo(255, imgDepth >255);
00748
00749 cv::Mat img_depth_8u;
00750 imgDepth.convertTo(img_depth_8u, CV_8U);
00751
00752 cv::Mat result_8u;
00753 img_depth_8u.copyTo(result_8u);
00754
00755 bool* isnoise = (bool*) malloc(IMG_WIDTH*IMG_HEIGHT * sizeof(bool));
00756
00757 for(int k=0; k<imgIsNoise.cols; k++)
00758 {
00759 for(int j=0; j<imgIsNoise.rows; j++)
00760 {
00761 if(imgIsNoise.at<uchar>(j,k) == 0)
00762 {
00763 isnoise[j*imgIsNoise.cols + k] = false;
00764 }else{
00765 isnoise[j*imgIsNoise.cols + k] = true;
00766 }
00767 }
00768 }
00769
00770
00771 cbf(img_depth_8u.data, imgRgb.data, isnoise, result_8u.data, spaceSigmas_default, rangeSigmas_default);
00772
00773 cv::Mat result_double;
00774 result_8u.convertTo(result_double, CV_32FC1);
00775 result_double = result_double*(max/255.0);
00776
00777 return result_double;
00778 }
00779
00780 }