def pointing_correction(tile_info): """ Compute the translations that correct the pointing errors on a tile. There is one correction per pair of images. Args: tile_info: dictionary containing all the information needed to process the tile """ tile_dir = tile_info['directory'] x, y, w, h = tile_info['coordinates'] for i in range(1, tile_info['number_of_pairs'] + 1): paired_tile_dir = os.path.join(tile_dir, 'pair_%d' % i) img1, rpc1 = cfg['images'][0]['img'], cfg['images'][0]['rpc'] img2, rpc2 = cfg['images'][i]['img'], cfg['images'][i]['rpc'] roi_msk = cfg['images'][0]['roi'] cld_msk = cfg['images'][0]['cld'] wat_msk = cfg['images'][0]['wat'] # create a directory for the experiment if not os.path.exists(paired_tile_dir): os.makedirs(paired_tile_dir) # output files cwid_msk = '%s/cloud_water_image_domain_mask.png' % (paired_tile_dir) pointing = '%s/pointing.txt' % paired_tile_dir center = '%s/center_keypts_sec.txt' % paired_tile_dir sift_matches = '%s/sift_matches.txt' % paired_tile_dir # check if the tile is already done if os.path.isfile( '%s/pointing.txt' % paired_tile_dir) and cfg['skip_existing']: print "pointing correction on tile %d %d (pair %d) already done, skip" % ( x, y, i) else: # check if the ROI is masked by water or out of 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, wat_msk): print "Tile masked by water or outside definition domain, skip" open("%s/this_tile_is_masked.txt" % paired_tile_dir, 'a').close() else: # correct pointing error # A is the correction matrix and m is the list of sift matches A, m = pointing_accuracy.compute_correction( img1, rpc1, img2, rpc2, x, y, w, h) if A is not None: np.savetxt(pointing, A, fmt='%6.3f') if m is not None: np.savetxt(sift_matches, m, fmt='%9.3f') np.savetxt(center, np.mean(m[:, 2:4], 0), fmt='%9.3f') if cfg['debug']: png = '%s/sift_matches_plot.png' % paired_tile_dir visualisation.plot_matches_pleiades( img1, img2, rpc1, rpc2, m, x, y, w, h, png)
def pointing_correction(tile_info): """ Compute the translations that correct the pointing errors on a tile. There is one correction per pair of images. Args: tile_info: dictionary containing all the information needed to process the tile """ tile_dir = tile_info['directory'] x, y, w, h = tile_info['coordinates'] for i in range(1, tile_info['number_of_pairs'] + 1): paired_tile_dir = os.path.join(tile_dir, 'pair_%d' % i) img1, rpc1 = cfg['images'][0]['img'], cfg['images'][0]['rpc'] img2, rpc2 = cfg['images'][i]['img'], cfg['images'][i]['rpc'] roi_msk = cfg['images'][0]['roi'] cld_msk = cfg['images'][0]['cld'] wat_msk = cfg['images'][0]['wat'] # create a directory for the experiment if not os.path.exists(paired_tile_dir): os.makedirs(paired_tile_dir) # output files cwid_msk = '%s/cloud_water_image_domain_mask.png' % (paired_tile_dir) pointing = '%s/pointing.txt' % paired_tile_dir center = '%s/center_keypts_sec.txt' % paired_tile_dir sift_matches = '%s/sift_matches.txt' % paired_tile_dir # check if the tile is already done if os.path.isfile('%s/pointing.txt' % paired_tile_dir) and cfg['skip_existing']: print "pointing correction on tile %d %d (pair %d) already done, skip" % (x, y, i) else: # check if the ROI is masked by water or out of 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, wat_msk): print "Tile masked by water or outside definition domain, skip" open("%s/this_tile_is_masked.txt" % paired_tile_dir, 'a').close() else: # correct pointing error # A is the correction matrix and m is the list of sift matches A, m = pointing_accuracy.compute_correction(img1, rpc1, img2, rpc2, x, y, w, h) if A is not None: np.savetxt(pointing, A, fmt='%6.3f') if m is not None: np.savetxt(sift_matches, m, fmt='%9.3f') np.savetxt(center, np.mean(m[:, 2:4], 0), fmt='%9.3f') if cfg['debug']: png = '%s/sift_matches_plot.png' % paired_tile_dir visualisation.plot_matches_pleiades(img1, img2, rpc1, rpc2, m, x, y, w, h, png)
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