Beispiel #1
0
def lstsq_filter(x1, y1, x2, y2, psi=200, order=2, **kwargs):
    ''' Remove vectors that don't fit the model x1 = f(x2, y2)^n

    Fit the model x1 = f(x2, y2)^n using least squares method
    Simulate x1 using the model
    Compare actual and simulated x1 and remove points where error is too high
    Parameters
    ----------
        x1, y1, x2, y2 : coordinates of start and end of displacement [pixels]
        psi : threshold error between actual and simulated x1 [pixels]
    Returns
    -------
        x1 : 1D vector - filtered source X coordinates on img1, pix
        y1 : 1D vector - filtered source Y coordinates on img1, pix
        x2 : 1D vector - filtered destination X coordinates on img2, pix
        y2 : 1D vector - filtered destination Y coordinates on img2, pix
    '''
    if len(x1) == 0:
        return map(np.array, [[],[],[],[]])
    # interpolate using N-order polynomial
    x2sim, y2sim = interpolation_poly(x1, y1, x2, y2, x1, y1, order=order)

    # find error between actual and simulated x1
    err = np.hypot(x2 - x2sim, y2 - y2sim)

    # find pixels with error below psi
    gpi = err < psi

    print('LSTSQ filter: %d -> %d' % (len(x1), len(gpi[gpi])))
    return x1[gpi], y1[gpi], x2[gpi], y2[gpi]
Beispiel #2
0
    def test_interpolation_poly(self):
        keyPoints1, descr1 = find_key_points(self.img1, nFeatures=self.nFeatures)
        keyPoints2, descr2 = find_key_points(self.img2, nFeatures=self.nFeatures)
        x1, y1, x2, y2 = get_match_coords(keyPoints1, descr1,
                                          keyPoints2, descr2)
        x2p1, y2p1 = interpolation_poly(x1, y1, x2, y2, x1, y1, 1)
        x2p2, y2p2 = interpolation_poly(x1, y1, x2, y2, x1, y1, 2)
        x2p3, y2p3 = interpolation_poly(x1, y1, x2, y2, x1, y1, 3)

        plt.subplot(1,2,1)
        plt.plot(x2, x2p1, '.')
        plt.plot(x2, x2p2, '.')
        plt.plot(x2, x2p3, '.')
        plt.subplot(1,2,2)
        plt.plot(y2, y2p1, '.')
        plt.plot(y2, y2p2, '.')
        plt.plot(y2, y2p3, '.')
        plt.savefig('sea_ice_drift_tests_%s.png' % inspect.currentframe().f_code.co_name)
        plt.close('all')
        self.assertEqual(len(x2p1), len(x1))
Beispiel #3
0
def prepare_first_guess(c2pm1,
                        r2pm1,
                        n1,
                        c1,
                        r1,
                        n2,
                        c2,
                        r2,
                        img_size,
                        min_fg_pts=5,
                        min_border=20,
                        max_border=50,
                        old_border=True,
                        **kwargs):
    ''' For the given intial coordinates estimate the approximate final coordinates
    Parameters
    ---------
        c2_pm1 : 1D vector, initial PM column on image 2
        r2_pm1 : 1D vector, initial PM rows of image 2
        n1 : Nansat, the fist image with 2D array
        c1 : 1D vector, initial FT columns on img1
        r1 : 1D vector, initial FT rows on img2
        n2 : Nansat, the second image with 2D array
        c2 : 1D vector, final FT columns on img2
        r2 : 1D vector, final FT rows on img2
        img_size : int, size of template
        min_fg_pts : int, minimum number of fist guess points
        min_border : int, minimum searching distance
        max_border : int, maximum searching distance
        old_border : bool, use old border selection algorithm?
        **kwargs : parameters for:
            x2y2_interpolation_poly
            x2y2_interpolation_near
    Returns
    -------
        c2_fg : 1D vector, approximate final PM columns on img2 (first guess)
        r2_fg : 1D vector, approximate final PM rows on img2 (first guess)
        border : 1D vector, searching distance
    '''
    n2_shape = n2.shape()
    # convert initial FT points to coordinates on image 2
    lon1, lat1 = n1.transform_points(c1, r1)
    c1n2, r1n2 = n2.transform_points(lon1, lat1, 1)

    # interpolate 1st guess using 2nd order polynomial
    c2p2, r2p2 = np.round(
        interpolation_poly(c1n2, r1n2, c2, r2, c2pm1, r2pm1, **kwargs))

    # interpolate 1st guess using griddata
    c2fg, r2fg = np.round(
        interpolation_near(c1n2, r1n2, c2, r2, c2pm1, r2pm1, **kwargs))

    # TODO:
    # Now border is proportional to the distance to the point
    # BUT it assumes that:
    #     close to any point error is small, and
    #     error varies between points
    # What if error does not vary with distance from the point?
    # Border can be estimated as error of the first guess
    # (x2 - x2_predicted_with_polynom) gridded using nearest neighbour.
    if old_border:
        # find distance to nearest neigbour and create border matrix
        border_img = get_distance_to_nearest_keypoint(c2, r2, n2_shape)
        border = np.zeros(c2pm1.size) + max_border
        gpi = ((c2pm1 >= 0) * (c2pm1 < n2_shape[1]) * (r2pm1 >= 0) *
               (r2pm1 < n2_shape[0]))
        border[gpi] = border_img[np.round(r2pm1[gpi]).astype(np.int16),
                                 np.round(c2pm1[gpi]).astype(np.int16)]
    else:
        c2tst, r2tst = interpolation_poly(c1n2, r1n2, c2, r2, c1n2, r1n2,
                                          **kwargs)
        c2dif, r2dif = interpolation_near(c1n2, r1n2, c2 - c2tst, r2 - r2tst,
                                          c2pm1, r2pm1, **kwargs)
        border = np.hypot(c2dif, r2dif)

    # define searching distance
    border[border < min_border] = min_border
    border[border > max_border] = max_border
    border[np.isnan(c2fg)] = max_border
    border = np.floor(border)

    # define FG based on P2 and GD
    c2fg[np.isnan(c2fg)] = c2p2[np.isnan(c2fg)]
    r2fg[np.isnan(r2fg)] = r2p2[np.isnan(r2fg)]

    return c2fg, r2fg, border