def run_consistency_check(mvs_dir, window_radius, depth_range=None):
    # do forward-backward checking and filtering
    cmd = 'colmap patch_match_stereo --workspace_path {} \
                    --PatchMatchStereo.window_radius {} \
                    --PatchMatchStereo.min_triangulation_angle 5.0 \
                    --PatchMatchStereo.geom_consistency 1 \
                    --PatchMatchStereo.use_exist_photom 1 \
                    --PatchMatchStereo.overwrite 1 \
                    --PatchMatchStereo.geom_consistency_regularizer 0.3 \
                    --PatchMatchStereo.geom_consistency_max_cost 3 \
                    --PatchMatchStereo.filter 1 \
                    --PatchMatchStereo.filter_min_triangulation_angle 4.99 \
                    --PatchMatchStereo.filter_min_ncc 0.1 \
                    --PatchMatchStereo.filter_geom_consistency_max_cost 1 \
                    --PatchMatchStereo.filter_min_num_consistent 2 \
                    --PatchMatchStereo.gpu_index={} \
                    --PatchMatchStereo.num_samples 15 \
                    --PatchMatchStereo.num_iterations 1'.format(mvs_dir,
                                                                window_radius, gpu_index)
    if depth_range is not None:
        depth_min, depth_max = depth_range
        other_opts = '--PatchMatchStereo.depth_min {} \
                      --PatchMatchStereo.depth_max {}'.format(depth_min, depth_max)
        cmd = '{} {}'.format(cmd, other_opts)
    run_cmd(cmd)
def run_point_triangulation(img_dir, db_file, out_dir, template_file,
                            tri_merge_max_reproj_error,
                            tri_complete_max_reproj_error,
                            filter_max_reproj_error):
    if not os.path.exists(out_dir):
        os.mkdir(out_dir)

    # create initial poses
    create_init_files(db_file, template_file, out_dir)

    # triangulate points
    cmd = 'colmap point_triangulator --Mapper.ba_refine_principal_point 1 \
                                             --database_path {} \
                                             --image_path {} \
                                             --input_path {} \
                                             --output_path {} \
                                             --Mapper.filter_min_tri_angle 4.99 \
                                             --Mapper.init_max_forward_motion 1e20 \
                                             --Mapper.tri_min_angle 5.00 \
                                             --Mapper.tri_merge_max_reproj_error {} \
                                             --Mapper.tri_complete_max_reproj_error {} \
                                             --Mapper.filter_max_reproj_error {} \
                                             --Mapper.extract_colors 1 \
                                             --Mapper.ba_refine_focal_length 0 \
                                             --Mapper.ba_refine_extra_params 0\
                                             --Mapper.max_extra_param 1e20 \
                                             --Mapper.ba_local_num_images 6 \
                                             --Mapper.ba_local_max_num_iterations 100 \
                                             --Mapper.ba_global_images_ratio 1.0000001\
                                             --Mapper.ba_global_max_num_iterations 100 \
                                             --Mapper.tri_ignore_two_view_tracks 1'.format(
        db_file, img_dir, out_dir, out_dir, tri_merge_max_reproj_error,
        tri_complete_max_reproj_error, filter_max_reproj_error)
    run_cmd(cmd)
def run_sift_matching(img_dir, db_file, camera_model):
    assert (camera_model == 'PINHOLE' or camera_model == 'PERSPECTIVE')

    if os.path.exists(db_file):  # otherwise colmap will skip sift matching
        os.remove(db_file)

    # feature extraction
    cmd = 'colmap feature_extractor --database_path {} \
                                    --image_path {} \
                                    --ImageReader.camera_model {} \
                                    --SiftExtraction.max_image_size 10000  \
                                    --SiftExtraction.estimate_affine_shape 0 \
                                    --SiftExtraction.domain_size_pooling 1 \
                                    --SiftExtraction.max_num_features 25000 \
                                    --SiftExtraction.num_threads -1 \
                                    --SiftExtraction.use_gpu 1 \
                                    --SiftExtraction.gpu_index {}'.format(
        db_file, img_dir, camera_model, gpu_index)
    run_cmd(cmd)

    # feature matching
    cmd = 'colmap exhaustive_matcher --database_path {} \
                                            --SiftMatching.guided_matching 1 \
                                            --SiftMatching.num_threads -1 \
                                            --SiftMatching.max_error 3 \
                                            --SiftMatching.max_num_matches 30000 \
                                            --SiftMatching.gpu_index {}'.format(
        db_file, gpu_index)

    run_cmd(cmd)
Ejemplo n.º 4
0
def triangulate_task(track, rpc_models, affine_models, out_file):
    init = solve_init(track, rpc_models, affine_models)
    write_to_taskfile(track, rpc_models, init, out_file)

    # triangulate
    tmp_file = '{}.result.txt'.format(out_file)
    run_cmd(
        '/data2/kz298/satellite_stereo/rpc_triangulate_solver/multi_rpc_triangule/multi_rpc_triangulate {} {}'
        .format(out_file, tmp_file),
        disable_log=True)

    # read result
    with open(out_file) as fp:
        lines = fp.readlines()
        init_point = [float(x) for x in lines[0].strip().split(' ')]
        # init_err = float(lines[1].strip())
    with open(tmp_file) as fp:
        lines = fp.readlines()
        final_point = [float(x) for x in lines[0].strip().split(' ')]
        # final_err = float(lines[1].strip())

    # remove tmpfile
    os.remove(tmp_file)

    # double check the final_err
    # init_err = compute_reproj_err(rpc_models, track, init)
    final_err = compute_reproj_err(rpc_models, track, final_point)
    # #print('here ceres final_err: {}, python: {}'.format(final_err, tmp))
    # assert (np.abs(init_err - final_err) < 0.001)

    # logging.info('init point: lat,lon,alt={}, reproj. err.: {}'.format(init_point, init_err))
    # logging.info('final point: lat,lon,alt={}, reproj. err.: {}'.format(final_point, final_err))

    return final_point, final_err
Ejemplo n.º 5
0
def fuse(colmap_dir):
    cmd = 'colmap stereo_fusion --workspace_path {colmap_dir}/mvs \
                         --output_path {colmap_dir}/mvs/fused.ply \
                         --input_type geometric \
                         --StereoFusion.min_num_pixels 4\
                         --StereoFusion.max_reproj_error 2\
                         --StereoFusion.max_depth_error 1.0\
                         --StereoFusion.max_normal_error 10'.format(
        colmap_dir=colmap_dir)
    run_cmd(cmd)
def run_photometric_mvs(mvs_dir, window_radius, depth_range=None):
    cmd = 'colmap patch_match_stereo --workspace_path {} \
                    --PatchMatchStereo.window_radius {}\
                    --PatchMatchStereo.min_triangulation_angle 5.0 \
                    --PatchMatchStereo.filter 0 \
                    --PatchMatchStereo.geom_consistency 0 \
                    --PatchMatchStereo.gpu_index={} \
                    --PatchMatchStereo.num_samples 15 \
                    --PatchMatchStereo.num_iterations 12 \
                    --PatchMatchStereo.overwrite 1'.format(mvs_dir,
                                                           window_radius, gpu_index)
    if depth_range is not None:
        depth_min, depth_max = depth_range
        other_opts = '--PatchMatchStereo.depth_min {} \
                      --PatchMatchStereo.depth_max {}'.format(depth_min, depth_max)
        cmd = '{} {}'.format(cmd, other_opts)
    run_cmd(cmd)
Ejemplo n.º 7
0
def crop_ntf(in_ntf, out_png, ntf_size, bbx_size):
    (ntf_width, ntf_height) = ntf_size
    (ul_col, ul_row, width, height) = bbx_size

    # assert bounding box is completely inside the image
    assert (ul_col >= 0 and ul_col + width - 1 < ntf_width
            and ul_row >= 0 and ul_row + height - 1 < ntf_height)

    logging.info('ntf image to cut: {}, width, height: {}, {}'.format(in_ntf, ntf_width, ntf_height))
    logging.info('cut image bounding box, ul_col, ul_row, width, height: {}, {}, {}, {}'.format(ul_col, ul_row,
                                                                                                width, height))
    logging.info('png image to save: {}'.format(out_png))

    # note the coordinate system of .ntf
    cmd = 'gdal_translate -of png -ot UInt16 -srcwin {} {} {} {} {} {}' \
        .format(ul_col, ul_row, width, height, in_ntf, out_png)
    run_cmd(cmd)
    os.remove('{}.aux.xml'.format(out_png))
def run_global_ba(in_dir, out_dir, weight):
    if not os.path.exists(out_dir):
        os.mkdir(out_dir)

    # global bundle adjustment
    # one meter is roughly three pixels, we should square it
    cmd = 'colmap bundle_adjuster --input_path {in_dir} --output_path {out_dir} \
                                    --BundleAdjustment.max_num_iterations 5000 \
                                    --BundleAdjustment.refine_focal_length 0\
                                    --BundleAdjustment.refine_principal_point 1 \
                                    --BundleAdjustment.refine_extra_params 0 \
                                    --BundleAdjustment.refine_extrinsics 0 \
                                    --BundleAdjustment.function_tolerance 0 \
                                    --BundleAdjustment.gradient_tolerance 0 \
                                    --BundleAdjustment.parameter_tolerance 1e-10 \
                                    --BundleAdjustment.constrain_points 1 \
                                    --BundleAdjustment.constrain_points_loss_weight {weight}'.format(
        in_dir=in_dir, out_dir=out_dir, weight=weight)

    run_cmd(cmd)