示例#1
0
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)
示例#2
0
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)
示例#3
0
文件: s2p.py 项目: jmichel-otb/s2p
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