예제 #1
0
def get_affine_matrix(fixed_points, registering_points):
    print("\nGetting affine transform.")
    fixed_points = invert_xy_order(fixed_points)
    registering_points = invert_xy_order(registering_points)

    trans = affine6p.estimate(fixed_points, registering_points)
    warp_mtx = np.array(trans.get_matrix())[:2, :]
    return warp_mtx
def affine_calculate(p, p0):
    """
	Takes two m x 2 lists or numpy arrays of points, calculated the affine transformation matrix to move p -> p0
	"""
    p1 = np.array(p)
    p2 = np.array(p0)

    T = affine6p.estimate(p, p0).get_matrix()

    return T
def array_to_geotif(array_data,
                    tif_name,
                    tile_corner,
                    save_folder=f"intermediate/geotifs",
                    affine_option='4corners'):
    """Convert an array into a geoTIF, which is a format required to intersect with ROI polygon.
    """
    if affine_option == '4corners':
        origin = [[1, 1], [1, array_data.shape[2]],
                  [array_data.shape[1], array_data.shape[2]],
                  [array_data.shape[1], 1]]
        convert = tile_corner
        trans_matrix = affine6p.estimate(origin, convert).get_matrix()
        transform = Affine(trans_matrix[0][1], trans_matrix[0][0],
                           trans_matrix[0][2], trans_matrix[1][1],
                           trans_matrix[1][0], trans_matrix[1][2])

    elif affine_option == '4bounds':
        west = min(tile_corner[0][0], tile_corner[3][0])
        south = min(tile_corner[2][1], tile_corner[3][1])
        east = max(tile_corner[1][0], tile_corner[2][0])
        north = max(tile_corner[0][1], tile_corner[1][1])
        bearing = GetBearing(tile_corner[0], tile_corner[1])
        transform = rasterio.transform.from_bounds(
            west, south, east, north, array_data.shape[1],
            array_data.shape[2])  #* Affine.rotation(bearing)
        #FIXME: to be further tested

    else:
        print(f"Affine option {affine_option} not supported...Aborting")
        return

    # Save png as geoTIF
    with rasterio.open(f"{bucket}/{save_folder}/{tif_name}",
                       'w',
                       driver='GTiff',
                       height=array_data.shape[1],
                       width=array_data.shape[2],
                       count=3,
                       dtype=array_data.dtype,
                       crs='EPSG:4326',
                       transform=transform) as dst:
        dst.write(array_data)

    return transform
def transform_v1(phi_orig, largestCC):
    flip_shp_prior = 1 - largestCC
    # trans_dist returns the min distance between 1 to 0 in the matrix
    trans_dist, trans_idx = scipy.ndimage.distance_transform_edt(
        flip_shp_prior, sampling=[1, 1], return_indices=True)
    x_tar, y_tar = trans_idx[0], trans_idx[1]
    x_tar = (x_tar * phi_orig).astype('int32')
    y_tar = (y_tar * phi_orig).astype('int32')
    x_src = np.zeros(x_tar.shape)
    for row in range(x_src.shape[0]):
        x_src[row, :] = row

    y_src = np.zeros(y_tar.shape)
    for col in range(y_src.shape[1]):
        y_src[:, col] = col
    x_src = (x_src * phi_orig).astype('int32')
    y_src = (y_src * phi_orig).astype('int32')

    x_nonzero_idx, y_nonzero_idx = np.where(x_tar != 0)
    tar_pts_coor = np.array(
        [x_tar[np.where(x_tar != 0)], y_tar[np.where(x_tar != 0)]]).T
    src_pts_coor = np.array(
        [x_src[np.where(x_tar != 0)], y_src[np.where(x_tar != 0)]]).T

    trans = affine6p.estimate(src_pts_coor, tar_pts_coor)
    M = trans.get_matrix()

    M = np.array(M)
    print(M[0:2, :])
    print(src_pts_coor.shape)
    rows, cols = phi_orig.shape
    dst_img = np.zeros((rows, cols))
    for i in range(src_pts_coor.shape[0]):
        dst_pt = np.array(trans.transform(src_pts_coor[i]))
        dst_pt = dst_pt.astype('int32')
        if np.all(dst_pt >= 0) and dst_pt[0] < rows and dst_pt[1] < cols:
            dst_img[dst_pt[0], dst_pt[1]] = 1
    return dst_img
예제 #5
0
    def test_affine6p(self):
        '''
        should affine6p correctly
        '''
        for sple in samples:
            # check estimate
            t = affine6p.estimate(sple['a'], sple['b'])
            print("matrix = {0}".format(t.get_matrix()))
            for k in range(0, 6):
                msg = sple['id'] + ': ' + str(k) + '=' + str(t.params[k])
                self.assertTrue(
                    abs(t.params[k] - sple["params"][k]) < 0.001, msg)

            # check functions
            print("{0} -> {1}".format(sple['a'], sple['b']))
            print("matrix = {0}".format(t.get_matrix()))
            print("rotation_x = {0}".format(t.get_rotation_x()))
            print("rotation_y = {0}".format(t.get_rotation_y()))
            print("scale_x = {0}".format(t.get_scale_x()))
            print("scale_y = {0}".format(t.get_scale_y()))
            print("scale = {0}".format(t.get_scale()))
            print("translation = {0}".format(t.get_translation()))
            print(" ")

            # check estimate_error
            e = affine6p.estimate_error(t, sple['a'], sple['b'])
            msg = sple['id'] + ': error =' + str(e)
            self.assertTrue(abs(e - sple["error"]) < 0.001, msg)

            # check transform_inv
            if len(sple['a']) == 3:
                for k in range(0, 3):
                    b2 = t.transform_inv(sple['b'][k])
                    for l in range(0, 2):
                        msg = sple['id'] + ': a2 =' + str(b2[l])
                        self.assertTrue(
                            abs(b2[l] - sple["a"][k][l]) < 0.001, msg)
               "y"]])  # extract the coordinates in meters for the same points
m_coords

# %% [markdown]
# we determine the transform between the two, we know the two set of points do correspont to each other and there must be a transform between the two
# we use an affine transform for this... via affine6p (or nudged library if you prefer)

# %%
#pip install affine6p --user if not installed already

# %%
import affine6p
# using a complete affine transform is a little overkill in our case, but in the general situation migh be desirable, especially when workin on scanned imagery

# %%
T = affine6p.estimate(px_coords.tolist(), m_coords.tolist())
err = affine6p.estimate_error(T, px_coords.tolist(),
                              m_coords.tolist())  # mean squared distance
np.sqrt(err)  # around 20 cm average error due to digitalization

# %% [markdown]
# we got a very low error, good!

# %% [markdown]
# we have our transform, now we work with the picture
#

# %%
figure(figsize=(10, 10))  # fast inspection
imshow(im)