From 79c824e11b2e81f1bc3abe6890d4f542f8cd4dbe Mon Sep 17 00:00:00 2001 From: Oleg Alexandrov Date: Mon, 5 Aug 2024 18:07:57 -0700 Subject: [PATCH] Modularize code, add release note --- NEWS.rst | 1 + src/asp/Tools/parallel_stereo | 22 ----- src/asp/Tools/stereo_parse.cc | 170 +++++++++++++++++----------------- 3 files changed, 85 insertions(+), 108 deletions(-) diff --git a/NEWS.rst b/NEWS.rst index 1471b88cd..65cac2a41 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -36,6 +36,7 @@ parallel_stereo (:numref:`parallel_stereo`): * It is possible to mapproject either with ``dg`` and ``rpc`` cameras when using mapprojected images in stereo with DigitalGlobe / Maxar cameras (:numref:`dg-mapproj`). + * Skip tiles for which there is no valid low-resolution disparity. orbit_plot (:numref:`orbit_plot`): * Added the option ``--use-rmse``. diff --git a/src/asp/Tools/parallel_stereo b/src/asp/Tools/parallel_stereo index afea1a11d..3d02e41ce 100644 --- a/src/asp/Tools/parallel_stereo +++ b/src/asp/Tools/parallel_stereo @@ -104,12 +104,7 @@ def produce_tiles(args, settings, tile_w, tile_h): sep = "," tile_opt = ['--parallel-tile-size', str(tile_w), str(tile_h)] verbose = False - print("--now in produce_tiles") - print("tile opt is ", tile_opt) - print("args is ", " ".join(args)) - num_pairs = int(settings['num_stereo_pairs'][0]) # for multiview - print("num_pairs is ", num_pairs) if opt.seed_mode != 0 and num_pairs == 1: # D_sub must exist @@ -119,24 +114,7 @@ def produce_tiles(args, settings, tile_w, tile_h): # Create the tiles run_and_parse_output("stereo_parse", args + tile_opt, sep, verbose) - - # print("---local prefix is ", local_prefix) - # print("---out prefix is ", out_prefix) - - # # This is a bugfix for multiview. The tiles are produced in a subdirectory - # if local_prefix != out_prefix: - # local_tile_list = local_prefix + '-dirList.txt' - # out_tile_list = out_prefix + '-dirList.txt' - # if os.path.exists(local_tile_list): - # print("--copy file ", local_tile_list, " to ", out_tile_list) - # shutil.copyfile(local_tile_list, out_tile_list) - # else: - # raise Exception('The file ' + local_tile_list + ' does not exist.') - tiles = readTiles(settings['out_prefix'][0]) - - print("--size of tiles is ", len(tiles)) - return tiles def sym_link_prev_run(prev_run_prefix, out_prefix): diff --git a/src/asp/Tools/stereo_parse.cc b/src/asp/Tools/stereo_parse.cc index 0ec533da2..e81e1d629 100644 --- a/src/asp/Tools/stereo_parse.cc +++ b/src/asp/Tools/stereo_parse.cc @@ -81,7 +81,7 @@ void find_tile_at_loc(std::string const& tile_at_loc, ASPGlobalOptions const& op BBox2i box(start_x, start_y, wid_x, wid_y); if (box.contains(pix)) { - std::cout << "Tile with location: " << tile_name << "\n"; + vw::vw_out() << "Tile with location: " << tile_name << "\n"; success = true; } } @@ -90,6 +90,84 @@ void find_tile_at_loc(std::string const& tile_at_loc, ASPGlobalOptions const& op vw_out() << "No tile found at location.\n"; } +// Produce the list of tiles for which D_sub has valid values. +void produceTiles(std::string const& output_prefix, + vw::Vector2 const& trans_left_image_size, + vw::Vector2i const& parallel_tile_size, + int sgm_collar_size) { + + if (trans_left_image_size == vw::Vector2(0, 0)) + vw_throw(ArgumentErr() << "Cannot produce tiles without a valid L.tif.\n"); + + // We check for valid D_sub only if seed_mode is not 0 and not part of a multiview + // run, as that one is tricky to get right, given that each pair run has its own D_sub. + bool have_D_sub = false; + std::string d_sub_file = output_prefix + "-D_sub.tif"; + vw::ImageView> sub_disp; + vw::Vector2 upsample_scale(0, 0); + bool is_multiview = stereo_settings().part_of_multiview_run; + if (stereo_settings().seed_mode != 0 && !is_multiview) { + have_D_sub = true; + asp::load_D_sub_and_scale(output_prefix, d_sub_file, sub_disp, upsample_scale); + } + + int tile_x = parallel_tile_size[0]; + int tile_y = parallel_tile_size[1]; + int tiles_nx = int(ceil(double(trans_left_image_size[0]) / tile_x)); + int tiles_ny = int(ceil(double(trans_left_image_size[1]) / tile_y)); + + // Open the file for writing + std::string dirList = output_prefix + "-dirList.txt"; + std::ofstream ofs(dirList.c_str()); + + // Iterate in iy from 0 to tiles_ny - 1, and in ix from 0 to tiles_nx - 1. + for (int iy = 0; iy < tiles_ny; iy++) { + for (int ix = 0; ix < tiles_nx; ix++) { + + // Adjust for the tiles at the boundary + int curr_tile_x = tile_x; + int curr_tile_y = tile_y; + if (ix == tiles_nx - 1) + curr_tile_x = int(trans_left_image_size[0]) - ix * tile_x; + if (iy == tiles_ny - 1) + curr_tile_y = int(trans_left_image_size[1]) - iy * tile_y; + + int beg_x = ix * tile_x; + int beg_y = iy * tile_y; + + bool has_valid_vals = true; + if (have_D_sub) { + has_valid_vals = false; + int min_sub_x = floor((beg_x - sgm_collar_size) / upsample_scale[0]); + int min_sub_y = floor((beg_y - sgm_collar_size) / upsample_scale[1]); + int max_sub_x = ceil((beg_x + curr_tile_x + sgm_collar_size) / upsample_scale[0]); + int max_sub_y = ceil((beg_y + curr_tile_y + sgm_collar_size) / upsample_scale[1]); + + min_sub_x = std::max(min_sub_x, 0); + min_sub_y = std::max(min_sub_y, 0); + max_sub_x = std::min(max_sub_x, sub_disp.cols() - 1); + max_sub_y = std::min(max_sub_y, sub_disp.rows() - 1); + + for (int y = min_sub_y; y <= max_sub_y; y++) { + for (int x = min_sub_x; x <= max_sub_x; x++) { + if (is_valid(sub_disp(x, y))) { + has_valid_vals = true; + break; + } + } + if (has_valid_vals) + break; + } + } + + if (has_valid_vals) + ofs << output_prefix << "-" << beg_x << "_" << beg_y << "_" + << curr_tile_x << "_" << curr_tile_y << "\n"; + } + } + +} + int main(int argc, char* argv[]) { try { @@ -208,92 +286,12 @@ int main(int argc, char* argv[]) { vw_out() << "save_lr_disp_diff," << stereo_settings().save_lr_disp_diff << "\n"; vw_out() << "correlator_mode," << stereo_settings().correlator_mode << "\n"; - if (asp::stereo_settings().parallel_tile_size != vw::Vector2i(0, 0)) { - // Produce the tiles for parallel_stereo. Skip the ones not having valid - // disparity. - if (trans_left_image_size == vw::Vector2(0, 0)) - vw_throw(ArgumentErr() << "Cannot produce tiles without a valid L.tif.\n"); - - // We can check for valid D_sub only if seed_mode is not 0 and not part of a multiview - // run, as that one is tricky to get right. - bool have_D_sub = false; - std::string d_sub_file = output_prefix + "-D_sub.tif"; - std::cout << "===d sub file is " << d_sub_file << std::endl; - vw::ImageView> sub_disp; - vw::Vector2 upsample_scale(0, 0); - bool is_multiview = stereo_settings().part_of_multiview_run; - if (stereo_settings().seed_mode != 0 && !is_multiview) { - have_D_sub = true; - asp::load_D_sub_and_scale(output_prefix, d_sub_file, sub_disp, upsample_scale); - } - std::cout << "--upsample_scale is " << upsample_scale << std::endl; - - std::cout << "--trans_left_image size is " << trans_left_image_size << std::endl; - std::cout << "--sgm collar size is " << sgm_collar_size << std::endl; - int tile_x = asp::stereo_settings().parallel_tile_size[0]; - int tile_y = asp::stereo_settings().parallel_tile_size[1]; - std::cout << "--tilew is " << tile_x << std::endl; - std::cout << "--tileh is " << tile_y << std::endl; - int tiles_nx = int(ceil(double(trans_left_image_size[0]) / tile_x)); - int tiles_ny = int(ceil(double(trans_left_image_size[1]) / tile_y)); - std::cout << "--tiles_nx is " << tiles_nx << std::endl; - std::cout << "--tiles_ny is " << tiles_ny << std::endl; - std::cout << "--is multiview is " << is_multiview << std::endl; - - std::string dirList = output_prefix + "-dirList.txt"; - // Open this for writing - std::ofstream ofs(dirList.c_str()); - // Iterate in iy from 0 to tiles_ny - 1, and in ix from 0 to tiles_nx - 1. - for (int iy = 0; iy < tiles_ny; iy++) { - for (int ix = 0; ix < tiles_nx; ix++) { - - // Adjust for the tiles at the boundary - int curr_tile_x = tile_x; - int curr_tile_y = tile_y; - if (ix == tiles_nx - 1) - curr_tile_x = int(trans_left_image_size[0]) - ix * tile_x; - if (iy == tiles_ny - 1) - curr_tile_y = int(trans_left_image_size[1]) - iy * tile_y; - - int beg_x = ix * tile_x; - int beg_y = iy * tile_y; - - bool has_valid_vals = true; - if (have_D_sub) { - has_valid_vals = false; - int min_sub_x = floor((beg_x - sgm_collar_size) / upsample_scale[0]); - int min_sub_y = floor((beg_y - sgm_collar_size) / upsample_scale[1]); - int max_sub_x = ceil((beg_x + curr_tile_x + sgm_collar_size) / upsample_scale[0]); - int max_sub_y = ceil((beg_y + curr_tile_y + sgm_collar_size) / upsample_scale[1]); - - min_sub_x = std::max(min_sub_x, 0); - min_sub_y = std::max(min_sub_y, 0); - max_sub_x = std::min(max_sub_x, sub_disp.cols() - 1); - max_sub_y = std::min(max_sub_y, sub_disp.rows() - 1); - - for (int y = min_sub_y; y <= max_sub_y; y++) { - for (int x = min_sub_x; x <= max_sub_x; x++) { - if (is_valid(sub_disp(x, y))) { - has_valid_vals = true; - break; - } - } - if (has_valid_vals) - break; - } - } - - if (has_valid_vals) - ofs << output_prefix << "-" << beg_x << "_" << beg_y << "_" - << curr_tile_x << "_" << curr_tile_y << "\n"; - } - } - } + if (asp::stereo_settings().parallel_tile_size != vw::Vector2i(0, 0)) + produceTiles(output_prefix, trans_left_image_size, + asp::stereo_settings().parallel_tile_size, sgm_collar_size); - // This block of code should be in its own executable but I am - // reluctant to create one just for it. This functionality will be - // invoked after low-res disparity is computed, whether done in - // C++ or in Python. It will attach a georeference to this disparity. + // Attach a georeference to this disparity. + // TODO(oalexan1): Make this into a function std::string left_image_file = opt.out_prefix + "-L.tif"; if (stereo_settings().attach_georeference_to_lowres_disparity && fs::exists(left_image_file)) {