示例#1
0
文件: sift_test.py 项目: wjy-ucas/s2p
def test_matches_on_rpc_roi():
    """
    Unit test for the function sift.matches_on_rpc_roi.
    """
    img1 = data_path('input_triplet/img_01.tif')
    img2 = data_path('input_triplet/img_02.tif')
    rpc1 = rpcm.rpc_from_geotiff(img1)
    rpc2 = rpcm.rpc_from_geotiff(img2)
    computed = sift.matches_on_rpc_roi(img1,
                                       img2,
                                       rpc1,
                                       rpc2,
                                       100,
                                       100,
                                       200,
                                       200,
                                       method='relative',
                                       sift_thresh=0.6,
                                       epipolar_threshold=10)
    expected = np.loadtxt(
        data_path('expected_output/units/matches_on_rpc_roi.txt'))
    np.testing.assert_allclose(computed,
                               expected,
                               rtol=0.01,
                               atol=0.1,
                               verbose=True)
示例#2
0
def get_angles(ref_filename, sec_filename):
    ref_rpc = rpcm.rpc_from_geotiff(ref_filename)
    sec_rpc = rpcm.rpc_from_geotiff(sec_filename)

    width, height, pixel_dim = s2p.common.image_size_gdal(ref_filename)

    # get the rpc of the first image
    ref_image_rpc = rpcm.rpc_from_geotiff(ref_filename)
    # get the localization of the center of the image
    lon_center, lat_center = ref_image_rpc.localization(
        width // 2, height // 2, 0)

    ref_zenith, ref_azimut = ref_rpc.incidence_angles(lon_center,
                                                      lat_center,
                                                      z=0)
    sec_zenith, sec_azimut = sec_rpc.incidence_angles(lon_center,
                                                      lat_center,
                                                      z=0)

    ref_sec_angle = rpcm.angle_between_views(ref_filename,
                                             sec_filename,
                                             lon_center,
                                             lat_center,
                                             z=0)

    return ref_zenith, ref_azimut, sec_zenith, sec_azimut, ref_sec_angle
示例#3
0
文件: sift_test.py 项目: hnrck/s2p
def test_matches_on_rpc_roi():
    """
    Test SIFT matching of two image ROIs.
    """
    img1 = data_path('input_triplet/img_01.tif')
    img2 = data_path('input_triplet/img_02.tif')
    rpc1 = rpcm.rpc_from_geotiff(data_path('input_triplet/img_01.tif'))
    rpc2 = rpcm.rpc_from_geotiff(data_path('input_triplet/img_02.tif'))
    computed = s2p.sift.matches_on_rpc_roi(img1, img2, rpc1, rpc2, 100, 100,
                                           200, 200)
    expected = np.loadtxt(
        data_path('expected_output/units/matches_on_rpc_roi.txt'))
    assert_arrays_are_equal(computed, expected)
示例#4
0
def get_coordinates_with_config(tile, m, M):
    tile_cfg = s2p.read_config_file(os.path.join(tile, "config.json"))

    x = tile_cfg['roi']['x']
    y = tile_cfg['roi']['y']
    w = tile_cfg['roi']['w']
    h = tile_cfg['roi']['h']

    rpc = rpcm.rpc_from_geotiff(tile_cfg['images'][0]['img'])

    a = np.array([x, x,   x,   x, x+w, x+w, x+w, x+w])
    b = np.array([y, y, y+h, y+h,   y,   y, y+h, y+h])
    c = np.array([m, M,   m,   M,   m,   M,   m,   M])

    lon, lat, __ = rpc.direct_estimate(a, b, c)

    out = list(common.bounding_box2D(np.vstack([lon, lat]).T))

    out[2] += out[0]
    out[3] += out[1]

    latlon = [[out[0], out[3], 0],
              [out[2], out[3], 0],
              [out[2], out[1], 0],
              [out[0], out[1], 0],
              [out[0], out[3], 0]]

    return latlon
示例#5
0
def vissat_meta_from_geotiff(image_filename):
    geotiff_meta = readGTIFFmeta(image_filename)
    rpc = rpcm.rpc_from_geotiff(image_filename)

    meta_dict = {}
    rpc_dict = {}

    rpc_dict['rowOff'] = rpc.row_offset
    rpc_dict['rowScale'] = rpc.row_scale

    rpc_dict['colOff'] = rpc.col_offset
    rpc_dict['colScale'] = rpc.col_scale

    rpc_dict['latOff'] = rpc.lat_offset
    rpc_dict['latScale'] = rpc.lat_scale

    rpc_dict['lonOff'] = rpc.lon_offset
    rpc_dict['lonScale'] = rpc.lon_scale

    rpc_dict['altOff'] = rpc.alt_offset
    rpc_dict['altScale'] = rpc.alt_scale

    # polynomial coefficients
    rpc_dict['rowNum'] = rpc.row_num
    rpc_dict['rowDen'] = rpc.row_den
    rpc_dict['colNum'] = rpc.col_num
    rpc_dict['colDen'] = rpc.col_den

    # width, height
    meta_dict['width'] = geotiff_meta[0]['width']
    meta_dict['height'] = geotiff_meta[0]['height']

    meta_dict['rpc'] = rpc_dict

    return meta_dict
示例#6
0
def check_parameters(d):
    """
    Check that the provided dictionary defines all mandatory s2p arguments.

    Args:
        d: python dictionary
    """
    # verify that input files paths are defined
    if 'images' not in d or len(d['images']) < 2:
        print('ERROR: missing paths to input images')
        sys.exit(1)
    for img in d['images']:
        if not dict_has_keys(img, ['img']):
            print('ERROR: missing img paths for image', img)
            sys.exit(1)

    # read RPCs
    for img in d['images']:
        if 'rpc' in img:
            if isinstance(img['rpc'], str):  # path to an RPC file
                img['rpcm'] = rpcm.rpc_from_rpc_file(img['rpc'])
            elif isinstance(img['rpc'], dict):  # RPC dict in 'rpcm' format
                img['rpcm'] = rpcm.RPCModel(img['rpc'], dict_format='rpcm')
            else:
                raise NotImplementedError(
                    'rpc of type {} not supported'.format(type(img['rpc'])))
        else:
            img['rpcm'] = rpcm.rpc_from_geotiff(img['img'])

    # verify that an input ROI is defined
    if 'full_img' in d and d['full_img']:
        sz = common.image_size_gdal(d['images'][0]['img'])
        d['roi'] = {'x': 0, 'y': 0, 'w': sz[0], 'h': sz[1]}
    elif 'roi' in d and dict_has_keys(d['roi'], ['x', 'y', 'w', 'h']):
        pass
    elif 'roi_geojson' in d:
        ll_poly = geographiclib.read_lon_lat_poly_from_geojson(
            d['roi_geojson'])
        d['roi'] = rpc_utils.roi_process(
            d['images'][0]['rpcm'],
            ll_poly,
            use_srtm=d.get('use_srtm'),
            exogenous_dem=d.get('exogenous_dem'),
            exogenous_dem_geoid_mode=d.get('exogenous_dem_geoid_mode'))
    else:
        print('ERROR: missing or incomplete roi definition')
        sys.exit(1)

    # d['roi'] : all the values must be integers
    d['roi']['x'] = int(np.floor(d['roi']['x']))
    d['roi']['y'] = int(np.floor(d['roi']['y']))
    d['roi']['w'] = int(np.ceil(d['roi']['w']))
    d['roi']['h'] = int(np.ceil(d['roi']['h']))

    # warn about unknown parameters. The known parameters are those defined in
    # the global config.cfg dictionary, plus the mandatory 'images' and 'roi'
    for k in d.keys():
        if k not in ['images', 'roi', 'roi_geojson']:
            if k not in cfg:
                print('WARNING: ignoring unknown parameter {}.'.format(k))
示例#7
0
def fixture_images():
    res = []
    for i in [1, 2]:
        im = data_path(os.path.join('input_pair', 'img_0{}.tif'.format(i)))
        rpc = rpc_from_geotiff(im)
        res.append(im)
        res.append(rpc)
    return res
示例#8
0
def test_matches_from_rpc():
    """
    Test for rpc_utils.matches_from_rpc().
    """
    r1 = rpcm.rpc_from_geotiff(
        data_path(os.path.join('input_pair', 'img_01.tif')))
    r2 = rpcm.rpc_from_geotiff(
        data_path(os.path.join('input_pair', 'img_02.tif')))

    test_matches = rpc_utils.matches_from_rpc(r1, r2, 100, 100, 200, 200, 5)
    expected_matches = np.loadtxt(
        data_path(
            os.path.join('expected_output', 'units',
                         'unit_matches_from_rpc.txt')))

    np.testing.assert_equal(test_matches.shape[0], 125, verbose=True)
    np.testing.assert_allclose(test_matches,
                               expected_matches,
                               rtol=0.01,
                               atol=0.1,
                               verbose=True)
示例#9
0
def test_roi_process():
    """
    Test for rpc_utils.roi_process().
    """
    rpc = rpcm.rpc_from_geotiff(
        data_path(os.path.join('input_pair', 'img_01.tif')))
    ll_poly = np.asarray([[55.649517, -21.231542], [55.651502, -21.231542],
                          [55.651502, -21.229672], [55.649517, -21.229672]])
    computed = [
        rpc_utils.roi_process(rpc, ll_poly)[k] for k in ['x', 'y', 'w', 'h']
    ]
    expected = (271.48531909338635, 1.5901905457030807, 407.3786143153775,
                413.5301010405019)
    np.testing.assert_allclose(computed, expected, atol=1e-3)
示例#10
0
def try_rpcm(img, x, y):
    try:
        import rpcm
    except ImportError as e:
        print('Cannot import rpcm:', e)
        return
    try:
        rpc = rpcm.rpc_from_geotiff(img)
        import srtm4
        z = srtm4.srtm4(rpc.lon_offset, rpc.lat_offset)
        lon, lat = rpc.localization(x, y, z)
    except Exception as e:
        print('Error while localization:', e)
        return
    return lon, lat
示例#11
0
def rpc2map(img, imgx, imgy, imgz=0):
    """
    generate 3D world coordinates from input image pixel coordinates using the RPC model
    See rpcm: https://github.com/cmla/rpcm/blob/master/rpcm/rpc_model.py for implementation
    Parameters
    ----------
    img: str
        path to image file containing RPC in in gdal tags
    imgx,imgy,imgz: int/float
        Image x,y in pixel units, z: height in world coordinates
    Returns
    ----------
    mx,my: np.arrays
        numpy arrays containing longitudes (mx) and latitudes (my) in geographic (EPSG:4326) coordinates
    """
    rpc = rpc_from_geotiff(img)
    mx, my = rpc.localization(imgx, imgy, imgz)
    return mx, my
示例#12
0
def crop_aoi(geotiff, aoi, z=0):
    """
    Crop a geographic AOI in a georeferenced image using its RPC functions.

    Args:
        geotiff (string): path or url to the input GeoTIFF image file
        aoi (geojson.Polygon): GeoJSON polygon representing the AOI
        z (float, optional): base altitude with respect to WGS84 ellipsoid (0
            by default)

    Return:
        crop (array): numpy array containing the cropped image
        x, y, w, h (ints): image coordinates of the crop. x, y are the
            coordinates of the top-left corner, while w, h are the dimensions
            of the crop.
    """
    x, y, w, h = bounding_box_of_projected_aoi(rpcm.rpc_from_geotiff(geotiff), aoi, z)
    with rasterio.open(geotiff, 'r') as src:
        crop = src.read(window=((y, y + h), (x, x + w)), boundless=True).squeeze()
    return crop, x, y
示例#13
0
def lon_lat_image_footprint(image, z=0):
    """
    Compute the longitude, latitude footprint of an image using its RPC model.

    Args:
        image (str): path or url to a GeoTIFF file
        z (float): altitude (in meters above the WGS84 ellipsoid) used to
            convert the image corners pixel coordinates into longitude, latitude

    Returns:
        geojson.Polygon object containing the image footprint polygon
    """
    rpc = rpcm.rpc_from_geotiff(image)
    with rasterio.open(image, 'r') as src:
        h, w = src.shape
    coords = []
    for x, y, z in zip([0, w, w, 0], [0, 0, h, h], [z, z, z, z]):
        lon, lat = rpc.localization(x, y, z)
        coords.append([lon, lat])
    return geojson.Polygon([coords])
示例#14
0
def utm_zone(rpc, x, y, w, h):
    """
    Compute the UTM zone where the ROI probably falls (or close to its border).

    Args:
        rpc: instance of the rpcm.RPCModel class, or path to a GeoTIFF file
        x, y, w, h: four integers defining a rectangular region of interest
            (ROI) in the image. (x, y) is the top-left corner, and (w, h)
            are the dimensions of the rectangle.

    Returns:
        a string of the form '18N' or '18S' where 18 is the utm zone
        identificator.
    """
    # read rpc file
    if not isinstance(rpc, rpcm.RPCModel):
        rpc = rpcm.rpc_from_geotiff(rpc)

    # determine lat lon of the center of the roi, assuming median altitude
    lon, lat = rpc.localization(x + .5 * w, y + .5 * h, rpc.alt_offset)[:2]

    return geographiclib.compute_utm_zone(lon, lat)
示例#15
0
def test_roi_process(use_srtm, exogenous_dem, exogenous_dem_geoid_mode,
                     expected):
    """
    Test for rpc_utils.roi_process().
    """
    rpc = rpcm.rpc_from_geotiff(
        data_path(os.path.join("input_pair", "img_01.tif")))
    ll_poly = np.asarray([
        [55.649517, -21.231542],
        [55.651502, -21.231542],
        [55.651502, -21.229672],
        [55.649517, -21.229672],
    ])
    output = rpc_utils.roi_process(
        rpc,
        ll_poly,
        use_srtm=use_srtm,
        exogenous_dem=exogenous_dem,
        exogenous_dem_geoid_mode=exogenous_dem_geoid_mode,
    )
    computed = [output[k] for k in ["x", "y", "w", "h"]]
    np.testing.assert_allclose(computed, expected, atol=1e-3)
示例#16
0
    common.run('gdal_translate -of VRT -a_ullr 0 0 %d %d %s %s' %
               (w, h, in_img_file, tmp_vrt))

    common.run(('gdalwarp -co RPB=NO -co PROFILE=GeoTIFF -r %s -co "BIGTIFF=IF_NEEDED" -co "TILED=YES" -ovr NONE -overwrite -to SRC_METHOD=NO_GEOTRANSFORM -to DST_METHOD=NO_GEOTRANSFORM -tr'
                ' %d %d %s %s') % (filt, scale_x, scale_y, tmp_vrt, out_img_file))

    try:
        # Remove aux files if any
        os.remove(out_img_file + ".aux.xml")
    except OSError:
        pass

    # Clean tmp vrt file
    os.remove(tmp_vrt)

    print("Done")

    # generate rpc file
    print("Generating {} ...".format(out_rcp_file))

    r = rpcm.rpc_from_geotiff(in_img_file)
    r.linScale /= scale_y
    r.linOff /= scale_y
    r.colScale /= scale_x
    r.colOff /= scale_x
    r.write(out_rcp_file)

    print("Done")

    sys.exit(0)
示例#17
0
    '/home/agomez/Documents/iie/satelite/DATA/IARPA_DATA/ground_truth/mvs3d_gt_crop_05.tif'
]

#output_dir = '/home/agomez/Documents/iie/satelite/DATA/IARPA_DATA/cropped'

# Near in time images
output_dir = '/media/agomez/SeagateGoFlex750GB/SATELITE/DATA/IARPA_DATA/cropped'

# Far in time images
keys = [2, 12, 20, 26, 33, 43]
output_dir = '/media/agomez/SeagateGoFlex750GB/SATELITE/DATA/IARPA_DATA/cropped_far_in_time'

for k in keys:

    image_filename = image_filenames_dict[k]
    rpc = rpcm.rpc_from_geotiff(image_filename)
    print(k, image_filename)

    _, image_name = os.path.split(image_filename)
    image_acquisition_date_string = image_name[16:29]

    for mvs3d_gt_crop_filename in mvs3d_gt_crop_filename_list:
        gt_filename = mvs3d_gt_crop_filename
        _, gt_name = os.path.split(gt_filename)
        gt_name_no_extension, _ = os.path.splitext(gt_name)

        gt_cropped_data_dir = os.path.join(output_dir, gt_name_no_extension)
        if not os.path.isdir(gt_cropped_data_dir):
            os.makedirs(gt_cropped_data_dir)

        # get aoi from gt
示例#18
0
def aoi_info_from_geotiff_gt(ref_filename,
                             gt_filename,
                             padding=0.0,
                             height_guard=[-5, +5]):
    ''' aoi_from_gt
    Returns an aoi from an image and a gt

    padding: relative to the size the gt region (e.g. 0.1 adds a 10% of the extension of
    the region on the four boundaries)
    '''

    # get the dimensions of the first image
    width, height, pixel_dim = s2p.common.image_size_gdal(ref_filename)

    # get the rpc of the first image
    ref_image_rpc = rpcm.rpc_from_geotiff(ref_filename)
    # get the localization of the center of the image
    lon_center, lat_center = ref_image_rpc.localization(
        width // 2, height // 2, 0)

    zone_number = utm.latlon_to_zone_number(lat_center, lon_center)
    zone_letter = utm.latitude_to_zone_letter(lat_center)

    # Build the AOI of the GT ------------------------------

    gt_metadata = readGTIFFmeta(gt_filename)
    bounding_box = gt_metadata[1]
    gt_min_easting = bounding_box.left
    gt_max_easting = bounding_box.right
    gt_min_northing = bounding_box.bottom
    gt_max_northing = bounding_box.top

    # padding
    gt_easting_extension = gt_max_easting - gt_min_easting
    gt_northing_extension = gt_max_northing - gt_min_northing
    gt_min_easting -= padding * gt_easting_extension
    gt_max_easting += padding * gt_easting_extension
    gt_min_northing -= padding * gt_northing_extension
    gt_max_northing += padding * gt_northing_extension
    # update the extension
    gt_easting_extension = gt_max_easting - gt_min_easting
    gt_northing_extension = gt_max_northing - gt_min_northing

    # convert easting, northing to lon,lat
    gt_min_lat, gt_min_lon = utm.to_latlon(gt_min_easting, gt_min_northing,
                                           zone_number, zone_letter)
    gt_max_lat, gt_max_lon = utm.to_latlon(gt_max_easting, gt_max_northing,
                                           zone_number, zone_letter)

    zone_hemisphere = 'N' if gt_min_lat > 0 else 'S'

    aoi = {
        'coordinates': [[[gt_min_lon, gt_min_lat], [gt_min_lon, gt_max_lat],
                         [gt_max_lon, gt_max_lat], [gt_max_lon, gt_min_lat],
                         [gt_min_lon, gt_min_lat]]],
        'type':
        'Polygon'
    }

    utm_bbx = [
        gt_min_easting, gt_max_easting, gt_min_northing, gt_max_northing
    ]
    lonlat_bbx = [gt_min_lon, gt_max_lon, gt_min_lat, gt_max_lat]

    # get min and max height from the gt image
    gt = s2p.common.gdal_read_as_array_with_nans(gt_filename)
    min_height, max_height = robust_image_min_max(gt)
    # add height guard
    min_height += height_guard[0]
    max_height += height_guard[1]

    return aoi, min_height, max_height, zone_hemisphere, zone_letter, zone_number, utm_bbx, lonlat_bbx
示例#19
0
def check_parameters(d):
    """
    Check that the provided dictionary defines all mandatory s2p arguments.

    Args:
        d: python dictionary
    """
    # verify that input files paths are defined
    if 'images' not in d or len(d['images']) < 2:
        print('ERROR: missing paths to input images')
        sys.exit(1)
    for img in d['images']:
        if not dict_has_keys(img, ['img']):
            print('ERROR: missing img paths for image', img)
            sys.exit(1)

    # read RPCs
    for img in d['images']:
        if 'rpc' in img:
            if isinstance(img['rpc'], str):  # path to an RPC file
                img['rpcm'] = rpcm.rpc_from_rpc_file(img['rpc'])
            elif isinstance(img['rpc'], dict):  # RPC dict in 'rpcm' format
                img['rpcm'] = rpcm.RPCModel(img['rpc'], dict_format='rpcm')
            else:
                raise NotImplementedError(
                    'rpc of type {} not supported'.format(type(img['rpc'])))
        else:
            img['rpcm'] = rpcm.rpc_from_geotiff(img['img'])

    # verify that roi or path to preview file are defined
    if 'full_img' in d and d['full_img']:
        sz = common.image_size_gdal(d['images'][0]['img'])
        d['roi'] = {'x': 0, 'y': 0, 'w': sz[0], 'h': sz[1]}
    elif 'roi' in d and dict_has_keys(d['roi'], ['x', 'y', 'w', 'h']):
        pass
    elif 'roi_utm' in d and dict_has_keys(
            d['roi_utm'], ['utm_band', 'hemisphere', 'x', 'y', 'w', 'h']):
        d['roi'] = rpc_utils.utm_roi_to_img_roi(d['images'][0]['rpcm'],
                                                d['roi_utm'],
                                                d.get('use_srtm'))
    elif 'roi_kml' in d:
        # this call defines cfg['utm_zone'] and cfg['utm_bbx'] as side effects
        d['roi'] = rpc_utils.kml_roi_process(d['images'][0]['rpcm'],
                                             d['roi_kml'], d.get('utm_zone'),
                                             d.get('use_srtm'))
    elif 'roi_geojson' in d:
        # this call defines cfg['utm_zone'] and cfg['utm_bbx'] as side effects
        d['roi'] = rpc_utils.geojson_roi_process(d['images'][0]['rpcm'],
                                                 d['roi_geojson'],
                                                 d.get('utm_zone'),
                                                 d.get('use_srtm'))
    else:
        print('ERROR: missing or incomplete roi definition')
        sys.exit(1)

    # d['roi'] : all the values must be integers
    d['roi']['x'] = int(np.floor(d['roi']['x']))
    d['roi']['y'] = int(np.floor(d['roi']['y']))
    d['roi']['w'] = int(np.ceil(d['roi']['w']))
    d['roi']['h'] = int(np.ceil(d['roi']['h']))

    # warn about unknown parameters. The known parameters are those defined in
    # the global config.cfg dictionary, plus the mandatory 'images' and 'roi' or
    # 'roi_utm'
    for k in d.keys():
        if k not in [
                'images', 'roi', 'roi_kml', 'roi_geojson', 'roi_utm',
                'utm_zone'
        ]:
            if k not in cfg:
                print('WARNING: ignoring unknown parameter {}.'.format(k))