def disparity(out_dir, img1, rpc1, img2, rpc2, x=None, y=None, w=None, h=None, prv1=None, cld_msk=None, roi_msk=None): """ Computes a disparity map from a Pair of Pleiades images, without tiling Args: out_dir: path to the output directory img1: path to the reference image. rpc1: paths to the xml file containing the rpc coefficients of the reference image img2: path to the secondary image. rpc2: paths to the xml file containing the rpc coefficients of the secondary image x, y, w, h: four integers defining the rectangular ROI in the reference image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. prv1 (optional): path to a preview of the reference image cld_msk (optional): path to a gml file containing a cloud mask roi_msk (optional): path to a gml file containing a mask defining the area contained in the full image. Returns: nothing """ # output files rect1 = '%s/rectified_ref.tif' % (out_dir) rect2 = '%s/rectified_sec.tif' % (out_dir) disp = '%s/rectified_disp.tif' % (out_dir) mask = '%s/rectified_mask.png' % (out_dir) cwid_msk = '%s/cloud_water_image_domain_mask.png' % (out_dir) subsampling = '%s/subsampling.txt' % (out_dir) pointing = '%s/pointing.txt' % out_dir center = '%s/center_keypts_sec.txt' % out_dir sift_matches = '%s/sift_matches.txt' % out_dir sift_matches_plot = '%s/sift_matches_plot.png' % out_dir H_ref = '%s/H_ref.txt' % out_dir H_sec = '%s/H_sec.txt' % out_dir disp_min_max = '%s/disp_min_max.txt' % out_dir config = '%s/config.json' % out_dir # disparity (block-matching) disp_min, disp_max = np.loadtxt(disp_min_max) if cfg['disp_min'] is not None: disp_min = cfg['disp_min'] if cfg['disp_max'] is not None: disp_max = cfg['disp_max'] block_matching.compute_disparity_map(rect1, rect2, disp, mask, cfg['matching_algorithm'], disp_min, disp_max) # intersect mask with the cloud_water_image_domain mask (recomputed here to # get to be sampled on the epipolar grid) ww, hh = common.image_size(rect1) H1 = np.loadtxt(H_ref) masking.cloud_water_image_domain(cwid_msk, ww, hh, H1, rpc1, roi_msk, cld_msk) try: masking.intersection(mask, mask, cwid_msk) masking.erosion(mask, mask, cfg['msk_erosion']) except OSError: print "file %s not produced" % mask
def process_pair_single_tile(out_dir, img1, rpc1, img2, rpc2, x=None, y=None, w=None, h=None, prv1=None, cld_msk=None, roi_msk=None, A=None): """ Computes a disparity map from a Pair of Pleiades images, without tiling Args: out_dir: path to the output directory img1: path to the reference image. rpc1: paths to the xml file containing the rpc coefficients of the reference image img2: path to the secondary image. rpc2: paths to the xml file containing the rpc coefficients of the secondary image x, y, w, h: four integers defining the rectangular ROI in the reference image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. prv1 (optional): path to a preview of the reference image cld_msk (optional): path to a gml file containing a cloud mask roi_msk (optional): path to a gml file containing a mask defining the area contained in the full image. A (optional, default None): pointing correction matrix. If None, it will be estimated by this function. Returns: nothing """ # create a directory for the experiment if not os.path.exists(out_dir): os.makedirs(out_dir) # output files rect1 = '%s/rectified_ref.tif' % (out_dir) rect2 = '%s/rectified_sec.tif' % (out_dir) disp = '%s/rectified_disp.tif' % (out_dir) mask = '%s/rectified_mask.png' % (out_dir) cwid_msk = '%s/cloud_water_image_domain_mask.png' % (out_dir) subsampling = '%s/subsampling.txt' % (out_dir) pointing = '%s/pointing.txt' % out_dir center = '%s/center_keypts_sec.txt' % out_dir sift_matches = '%s/sift_matches.txt' % out_dir sift_matches_plot = '%s/sift_matches_plot.png' % out_dir H_ref = '%s/H_ref.txt' % out_dir H_sec = '%s/H_sec.txt' % out_dir disp_min_max = '%s/disp_min_max.txt' % out_dir config = '%s/config.json' % out_dir # select ROI try: print "ROI x, y, w, h = %d, %d, %d, %d" % (x, y, w, h) except TypeError: if prv1: x, y, w, h = common.get_roi_coordinates(img1, prv1) else: print 'Neither a ROI nor a preview file are defined. Aborting.' return # redirect stdout and stderr to log file if not cfg['debug']: fout = open('%s/stdout.log' % out_dir, 'w', 0) # '0' for no buffering sys.stdout = fout sys.stderr = fout # debug print print 'tile %d %d running on process %s' % (x, y, multiprocessing.current_process()) # ensure that the coordinates of the ROI are multiples of the zoom factor z = cfg['subsampling_factor'] x, y, w, h = common.round_roi_to_nearest_multiple(z, x, y, w, h) # check if the ROI is completely masked (water, or outside the image domain) H = np.array([[1, 0, -x], [0, 1, -y], [0, 0, 1]]) if masking.cloud_water_image_domain(cwid_msk, w, h, H, rpc1, roi_msk, cld_msk): print "Tile masked by water or outside definition domain, skip" open("%s/this_tile_is_masked.txt" % out_dir, 'a').close() sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ if not cfg['debug']: fout.close() return # correct pointing error # A is the correction matrix and m is the list of sift matches if A is None: A, m = pointing_accuracy.compute_correction(img1, rpc1, img2, rpc2, x, y, w, h) if A is not None: np.savetxt(pointing, A) if m is not None: np.savetxt(sift_matches, m) np.savetxt(center, np.mean(m[:, 2:4], 0)) visualisation.plot_matches_pleiades(img1, img2, rpc1, rpc2, m, x, y, w, h, sift_matches_plot) else: m = None # rectification H1, H2, disp_min, disp_max = rectification.rectify_pair(img1, img2, rpc1, rpc2, x, y, w, h, rect1, rect2, A, m) # block-matching if cfg['disp_min'] is not None: disp_min = cfg['disp_min'] if cfg['disp_max'] is not None: disp_max = cfg['disp_max'] block_matching.compute_disparity_map(rect1, rect2, disp, mask, cfg['matching_algorithm'], disp_min, disp_max) # intersect mask with the cloud_water_image_domain mask (recomputed here to # get to be sampled on the epipolar grid) ww, hh = common.image_size(rect1) masking.cloud_water_image_domain(cwid_msk, ww, hh, H1, rpc1, roi_msk, cld_msk) try: masking.intersection(mask, mask, cwid_msk) masking.erosion(mask, mask, cfg['msk_erosion']) except OSError: print "file %s not produced" % mask # save the subsampling factor, the rectifying homographies and the # disparity bounds. # ATTENTION if subsampling_factor is > 1 the rectified images will be # smaller, and the homography matrices and disparity range will reflect # this fact np.savetxt(subsampling, np.array([z])) np.savetxt(H_ref, H1) np.savetxt(H_sec, H2) np.savetxt(disp_min_max, np.array([disp_min, disp_max])) # save json file with all the parameters needed to reproduce this tile tile_cfg = copy.deepcopy(cfg) tile_cfg['roi'] = {'x': x, 'y': y, 'w': w, 'h': h} f = open(config, 'w') json.dump(tile_cfg, f, indent=2) f.close() # close logs common.garbage_cleanup() if not cfg['debug']: sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__ fout.close() return
def main(img_name=None, exp_name=None, x=None, y=None, w=None, h=None, reference_image_id=1, secondary_image_id=2): # input files im1 = 'data/%s/%04d.png' % (img_name, reference_image_id) im2 = 'data/%s/%04d.png' % (img_name, secondary_image_id) rpc1 = 'data/%s/%04d.png.P' % (img_name, reference_image_id) rpc2 = 'data/%s/%04d.png.P' % (img_name, secondary_image_id) im1_color = 'data/%s/%04d.png' % (img_name, reference_image_id) prev1 = 'data/%s/%04d.png' % (img_name, reference_image_id) ### GF: all the same image pointing = 'data/%s/pointing_correction_%02d_%02d.txt' % (img_name, reference_image_id, secondary_image_id) # output files rect1 = '/tmp/%s%d.tif' % (exp_name, reference_image_id) rect2 = '/tmp/%s%d.tif' % (exp_name, secondary_image_id) hom1 = '/tmp/%s_hom%d.txt' % (exp_name, reference_image_id) hom2 = '/tmp/%s_hom%d.txt' % (exp_name, secondary_image_id) outrpc1 = '/tmp/%s_rpc%d.xml' % (exp_name, reference_image_id) outrpc2 = '/tmp/%s_rpc%d.xml' % (exp_name, secondary_image_id) crop1_color = '/tmp/%s%d_color.tif' % (exp_name, reference_image_id) disp = '/tmp/%s_disp.pgm' % (exp_name) mask = '/tmp/%s_mask.png' % (exp_name) cloud = '/tmp/%s_cloud.ply' % (exp_name) height = '/tmp/%s_height.tif' % (exp_name) rpc_err = '/tmp/%s_rpc_err.tif'% (exp_name) height_unrect = '/tmp/%s_height_unrect.tif' % (exp_name) mask_unrect = '/tmp/%s_mask_unrect.png' % (exp_name) subsampling_file = '/tmp/%s_subsampling.txt' % (exp_name) """ Launches the s2p stereo pipeline on a pair of Pleiades images """ ## 0. select ROI try: print "ROI x, y, w, h = %d, %d, %d, %d" % (x, y, w, h) except (NameError,TypeError): x,y = 0,0 w,h = common.image_size(im1) # x, y, w, h = common.get_roi_coordinates(rpc1, prev1) ### GF: ROI IS THE WHOLE IMAGE print "ROI x, y, w, h = %d, %d, %d, %d" % (x, y, w, h) ## 0.5 copy the rpcs to the output directory, and save the subsampling factor from shutil import copyfile copyfile(rpc1, outrpc1) copyfile(rpc2, outrpc2) np.savetxt(subsampling_file, np.array([global_params.subsampling_factor])) # ATTENTION if subsampling_factor is set the rectified images will be # smaller, and the homography matrices and disparity range will reflect # this fact ## 1. rectification # If the pointing correction matrix is available, then use it. If not # proceed without correction H1, H2, disp_min, disp_max = rectification.rectify_pair(im1, im2, rpc1,rpc2, x, y, w, h, rect1, rect2) # save homographies to tmp files np.savetxt(hom1, H1) np.savetxt(hom2, H2) ## 2. block-matching # block_matching.compute_disparity_map(rect1, rect2, disp, mask, # 'hirschmuller08', disp_min, disp_max, extra_params='3') block_matching.compute_disparity_map(rect1, rect2, disp, mask, global_params.matching_algorithm, disp_min, disp_max) ## 3. triangulation FOR PROJECTIVE MATRICES DLT algorithm Hartley chapter 12.2 or 12.5 # from python import disp_to_h_projective as triangulate_proj # triangulate_proj.compute_height_map(rpc1,rpc2,hom1,hom2,disp,mask, height, rpc_err) common.run("disp_to_h_projective %s %s %s %s %s %s %s %s" % (rpc1, rpc2, hom1, hom2, disp, mask, height, rpc_err)) try: zoom = global_params.subsampling_factor except NameError: zoom = 1 ref_crop = common.image_crop_TIFF(im1, x, y, w, h) triangulation.transfer_map(height, ref_crop, H1, x, y, zoom, height_unrect) triangulation.transfer_map(mask, ref_crop, H1, x, y, zoom, mask_unrect) ## 4. colorize and generate point cloud print (img_name, exp_name, x, y, w, h, height_unrect) generate_cloud(img_name, exp_name, x, y, w, h, height_unrect, reference_image_id) ### cleanup while common.garbage: common.run('rm ' + common.garbage.pop())