Example #1
0
def save_if_requested(hs, subdir):
    if not hs.args.save_figures:
        return
    #print('[viz] Dumping Image')
    fpath = hs.dirs.result_dir
    if not subdir is None:
        subdir = helpers.sanatize_fname2(subdir)
        fpath = join(fpath, subdir)
        helpers.ensurepath(fpath)
    df2.save_figure(fpath=fpath, usetitle=True)
    df2.reset()
Example #2
0
def dump(hs, subdir=None, quality=False, overwrite=False):
    if quality is True:
        df2.FIGSIZE = df2.golden_wh2(12)
        df2.DPI = 120
        df2.FONTS.figtitle = df2.FONTS.small
    if quality is False:
        df2.FIGSIZE = df2.golden_wh2(8)
        df2.DPI = 90
        df2.FONTS.figtitle = df2.FONTS.smaller
    #print('[viz] Dumping Image')
    fpath = hs.dirs.result_dir
    if subdir is not None:
        fpath = join(fpath, subdir)
        helpers.ensurepath(fpath)
    df2.save_figure(fpath=fpath, usetitle=True, overwrite=overwrite)
    df2.reset()
Example #3
0
def test_realdata2():
    from helpers import printWARN, printINFO
    import warnings
    import numpy.linalg as linalg
    import numpy as np
    import scipy.sparse as sparse
    import scipy.sparse.linalg as sparse_linalg
    import load_data2
    import params
    import draw_func2 as df2
    import helpers
    import spatial_verification
    #params.reload_module()
    #load_data2.reload_module()
    #df2.reload_module()

    db_dir = load_data2.MOTHERS
    hs = load_data2.HotSpotter(db_dir)
    assign_matches = hs.matcher.assign_matches
    qcx = 0
    cx = hs.get_other_cxs(qcx)[0]
    fm, fs, score = hs.get_assigned_matches_to(qcx, cx)
    # Get chips
    rchip1 = hs.get_chip(qcx)
    rchip2 = hs.get_chip(cx)
    # Get keypoints
    kpts1 = hs.get_kpts(qcx)
    kpts2 = hs.get_kpts(cx)
    # Get feature matches 
    kpts1_m = kpts1[fm[:, 0], :].T
    kpts2_m = kpts2[fm[:, 1], :].T
    
    title='(qx%r v cx%r)\n #match=%r' % (qcx, cx, len(fm))
    df2.show_matches2(rchip1, rchip2, kpts1,  kpts2, fm, fs, title=title)

    np.random.seed(6)
    subst = helpers.random_indexes(len(fm),len(fm))
    kpts1_m = kpts1[fm[subst, 0], :].T
    kpts2_m = kpts2[fm[subst, 1], :].T

    df2.reload_module()
    df2.SHOW_LINES = True
    df2.ELL_LINEWIDTH = 2
    df2.LINE_ALPHA = .5
    df2.ELL_ALPHA  = 1
    df2.reset()
    df2.show_keypoints(rchip1, kpts1_m.T, fignum=0, plotnum=121)
    df2.show_keypoints(rchip2, kpts2_m.T, fignum=0, plotnum=122)
    df2.show_matches2(rchip1, rchip2, kpts1_m.T,  kpts2_m.T, title=title,
                      fignum=1, vert=True)

    spatial_verification.reload_module()
    with helpers.Timer():
        aff_inliers1 = spatial_verification.aff_inliers_from_ellshape2(kpts1_m, kpts2_m, xy_thresh_sqrd)
    with helpers.Timer():
        aff_inliers2 = spatial_verification.aff_inliers_from_ellshape(kpts1_m, kpts2_m, xy_thresh_sqrd)

    # Homogonize+Normalize
    xy1_m    = kpts1_m[0:2,:] 
    xy2_m    = kpts2_m[0:2,:]
    (xyz_norm1, T1) = spatial_verification.homogo_normalize_pts(xy1_m[:,aff_inliers1]) 
    (xyz_norm2, T2) = spatial_verification.homogo_normalize_pts(xy2_m[:,aff_inliers1])

    H_prime = spatial_verification.compute_homog(xyz_norm1, xyz_norm2)
    H = linalg.solve(T2, H_prime).dot(T1)                # Unnormalize

    Hdet = linalg.det(H)

    # Estimate final inliers
    acd1_m   = kpts1_m[2:5,:] # keypoint shape matrix [a 0; c d] matches
    acd2_m   = kpts2_m[2:5,:]
    # Precompute the determinant of lower triangular matrix (a*d - b*c); b = 0
    det1_m = acd1_m[0] * acd1_m[2]
    det2_m = acd2_m[0] * acd2_m[2]

    # Matrix Multiply xyacd matrix by H
    # [[A, B, X],      
    #  [C, D, Y],      
    #  [E, F, Z]] 
    # dot 
    # [(a, 0, x),
    #  (c, d, y),
    #  (0, 0, 1)] 
    # = 
    # [(a*A + c*B + 0*E,   0*A + d*B + 0*X,   x*A + y*B + 1*X),
    #  (a*C + c*D + 0*Y,   0*C + d*D + 0*Y,   x*C + y*D + 1*Y),
    #  (a*E + c*F + 0*Z,   0*E + d*F + 0*Z,   x*E + y*F + 1*Z)]
    # =
    # [(a*A + c*B,               d*B,         x*A + y*B + X),
    #  (a*C + c*D,               d*D,         x*C + y*D + Y),
    #  (a*E + c*F,               d*F,         x*E + y*F + Z)]
    # # IF x=0 and y=0
    # =
    # [(a*A + c*B,               d*B,         0*A + 0*B + X),
    #  (a*C + c*D,               d*D,         0*C + 0*D + Y),
    #  (a*E + c*F,               d*F,         0*E + 0*F + Z)]
    # =
    # [(a*A + c*B,               d*B,         X),
    #  (a*C + c*D,               d*D,         Y),
    #  (a*E + c*F,               d*F,         Z)]
    # --- 
    #  A11 = a*A + c*B
    #  A21 = a*C + c*D
    #  A31 = a*E + c*F
    #  A12 = d*B
    #  A22 = d*D
    #  A32 = d*F
    #  A31 = X
    #  A32 = Y
    #  A33 = Z
    #
    # det(A) = A11*(A22*A33 - A23*A32) - A12*(A21*A33 - A23*A31) + A13*(A21*A32 - A22*A31)

    det1_mAt = det1_m * Hdet
    # Check Error in position and scale
    xy_sqrd_err = (x1_mAt - x2_m)**2 + (y1_mAt - y2_m)**2
    scale_sqrd_err = det1_mAt / det2_m
    # Check to see if outliers are within bounds
    xy_inliers = xy_sqrd_err < xy_thresh_sqrd
    s1_inliers = scale_sqrd_err > scale_thresh_low
    s2_inliers = scale_sqrd_err < scale_thresh_high
    _inliers, = np.where(np.logical_and(np.logical_and(xy_inliers, s1_inliers), s2_inliers))

    xy1_mHt = transform_xy(H, xy1_m)                        # Transform Kpts1 to Kpts2-space
    sqrd_dist_error = np.sum( (xy1_mHt - xy2_m)**2, axis=0) # Final Inlier Errors
    inliers = sqrd_dist_error < xy_thresh_sqrd



    df2.show_matches2(rchip1, rchip2, kpts1_m.T[best_inliers1], kpts2_m.T[aff_inliers1], title=title, fignum=2, vert=False)
    df2.show_matches2(rchip1, rchip2, kpts1_m.T[best_inliers2], kpts2_m.T[aff_inliers2], title=title, fignum=3, vert=False)
    df2.present(wh=(600,400))
Example #4
0
    data_ = pca.transform(data)
    nn2_data_ = pca.transform(nn2_data)
    qx2_nn_ = pca.transform(qx2_nn)
    krx2_query_ = pca.transform(krx2_query)
    krx2_nn_ = pca.transform(krx2_nn)
else:
    print('Plotting full dimensionality')
    query_ = (query)
    data_ = (data)
    qx2_nn_ = (qx2_nn)
    krx2_query_ = (krx2_query)
    krx2_nn_ = (krx2_nn)

# Figure and Axis
plt = df2.plt
df2.reset()
fig = plt.figure(1)
if tdim == 2:
    ax = fig.add_subplot(111)
elif tdim > 2:
    from mpl_toolkits.mplot3d import Axes3D
    ax = fig.add_subplot(111, projection='3d')


def plot_points(data, color, marker):
    dataT = data.T
    if len(dataT) == 2:
        ax.plot(dataT[0],
                dataT[1],
                color=color,
                marker=marker,
    data_   = pca.transform(data)
    nn2_data_ = pca.transform(nn2_data)
    qx2_nn_ = pca.transform(qx2_nn)
    krx2_query_ = pca.transform(krx2_query)
    krx2_nn_ = pca.transform(krx2_nn)
else:
    print('Plotting full dimensionality')
    query_  = (query)
    data_   = (data)
    qx2_nn_ = (qx2_nn)
    krx2_query_ = (krx2_query)
    krx2_nn_ = (krx2_nn)

# Figure and Axis
plt = df2.plt
df2.reset()
fig = plt.figure(1)
if tdim == 2: 
    ax  = fig.add_subplot(111)
elif tdim > 2:
    from mpl_toolkits.mplot3d import Axes3D
    ax  = fig.add_subplot(111, projection='3d')

def plot_points(data, color, marker):
    dataT = data.T
    if len(dataT) == 2:
        ax.plot(dataT[0], dataT[1], color=color, marker=marker, linestyle='None')
    elif len(dataT) == 3:
        ax.scatter(dataT[0], dataT[1], dataT[2], color=color, marker=marker)

def plot_lines(point_pairs, color):
Example #6
0
def in_depth_ellipse2x2(rchip, kp):
    #-----------------------
    # SETUP
    #-----------------------
    from hotspotter import draw_func2 as df2
    np.set_printoptions(precision=8)
    tau = 2 * np.pi
    df2.reset()
    df2.figure(9003, docla=True, doclf=True)
    ax = df2.gca()
    ax.invert_yaxis()

    def _plotpts(data, px, color=df2.BLUE, label=''):
        #df2.figure(9003, docla=True, pnum=(1, 1, px))
        df2.plot2(data.T[0], data.T[1], '.', '', color=color, label=label)
        df2.update()

    def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''):
        ax = df2.gca()
        arrowargs = dict(head_width=.5, length_includes_head=True, label=label)
        arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs)
        arrow.set_edgecolor(color)
        arrow.set_facecolor(color)
        ax.add_patch(arrow)
        df2.update()

    def _2x2_eig(M2x2):
        (evals, evecs) = np.linalg.eig(M2x2)
        l1, l2 = evals
        v1, v2 = evecs
        return l1, l2, v1, v2

    #-----------------------
    # INPUT
    #-----------------------
    # We will call perdoch's invA = invV
    print('--------------------------------')
    print('Let V = Perdoch.A')
    print('Let Z = Perdoch.E')
    print('--------------------------------')
    print('Input from Perdoch\'s detector: ')

    # We are given the keypoint in invA format
    (x, y, ia11, ia21, ia22), ia12 = kp, 0
    invV = np.array([[ia11, ia12], [ia21, ia22]])
    V = np.linalg.inv(invV)
    # <HACK>
    #invV = V / np.linalg.det(V)
    #V = np.linalg.inv(V)
    # </HACK>
    Z = (V.T).dot(V)

    print('invV is a transform from points on a unit-circle to the ellipse')
    helpers.horiz_print('invV = ', invV)
    print('--------------------------------')
    print('V is a transformation from points on the ellipse to a unit circle')
    helpers.horiz_print('V = ', V)
    print('--------------------------------')
    print('Points on a matrix satisfy (x).T.dot(Z).dot(x) = 1')
    print('where Z = (V.T).dot(V)')
    helpers.horiz_print('Z = ', Z)

    # Define points on a unit circle
    theta_list = np.linspace(0, tau, 50)
    cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list])

    # Transform those points to the ellipse using invV
    ellipse_pts1 = invV.dot(cicrle_pts.T).T

    # Transform those points to the ellipse using V
    ellipse_pts2 = V.dot(cicrle_pts.T).T

    #Lets check our assertion: (x_).T.dot(Z).dot(x_) = 1
    checks1 = [x_.T.dot(Z).dot(x_) for x_ in ellipse_pts1]
    checks2 = [x_.T.dot(Z).dot(x_) for x_ in ellipse_pts2]
    assert all([abs(1 - check) < 1E-11 for check in checks1])
    #assert all([abs(1 - check) < 1E-11 for check in checks2])
    print('... all of our plotted points satisfy this')

    #=======================
    # THE CONIC SECTION
    #=======================
    # All of this was from the Perdoch paper, now lets move into conic sections
    # We will use the notation from wikipedia
    # http://en.wikipedia.org/wiki/Conic_section
    # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections

    #-----------------------
    # MATRIX REPRESENTATION
    #-----------------------
    # The matrix representation of a conic is:
    (A, B2, B2_, C) = Z.flatten()
    (D, E, F) = (0, 0, 1)
    B = B2 * 2
    assert B2 == B2_, 'matrix should by symmetric'
    print('--------------------------------')
    print('Now, using wikipedia\' matrix representation of a conic.')
    con = np.array((('    A', 'B / 2', 'D / 2'), ('B / 2', '    C', 'E / 2'),
                    ('D / 2', 'E / 2', '    F')))
    helpers.horiz_print('A matrix A_Q = ', con)

    # A_Q is our conic section (aka ellipse matrix)
    A_Q = np.array(((A, B / 2, D / 2), (B / 2, C, E / 2), (D / 2, E / 2, F)))

    helpers.horiz_print('A_Q = ', A_Q)

    #-----------------------
    # DEGENERATE CONICS
    #-----------------------
    print('----------------------------------')
    print('As long as det(A_Q) != it is not degenerate.')
    print('If the conic is not degenerate, we can use the 2x2 minor: A_33')
    print('det(A_Q) = %s' % str(np.linalg.det(A_Q)))
    assert np.linalg.det(A_Q) != 0, 'degenerate conic'
    A_33 = np.array(((A, B / 2), (B / 2, C)))
    helpers.horiz_print('A_33 = ', A_33)

    #-----------------------
    # CONIC CLASSIFICATION
    #-----------------------
    print('----------------------------------')
    print('The determinant of the minor classifies the type of conic it is')
    print('(det == 0): parabola, (det < 0): hyperbola, (det > 0): ellipse')
    print('det(A_33) = %s' % str(np.linalg.det(A_33)))
    assert np.linalg.det(A_33) > 0, 'conic is not an ellipse'
    print('... this is indeed an ellipse')

    #-----------------------
    # CONIC CENTER
    #-----------------------
    print('----------------------------------')
    print('the centers of the ellipse are obtained by: ')
    print('x_center = (B * E - (2 * C * D)) / (4 * A * C - B ** 2)')
    print('y_center = (D * B - (2 * A * E)) / (4 * A * C - B ** 2)')
    # Centers are obtained by solving for where the gradient of the quadratic
    # becomes 0. Without going through the derivation the calculation is...
    # These should be 0, 0 if we are at the origin, or our original x, y
    # coordinate specified by the keypoints. I'm doing the calculation just for
    # shits and giggles
    x_center = (B * E - (2 * C * D)) / (4 * A * C - B**2)
    y_center = (D * B - (2 * A * E)) / (4 * A * C - B**2)
    helpers.horiz_print('x_center = ', x_center)
    helpers.horiz_print('y_center = ', y_center)

    #-----------------------
    # MAJOR AND MINOR AXES
    #-----------------------
    # Now we are going to determine the major and minor axis
    # of this beast. It just the center augmented by the eigenvecs
    print('----------------------------------')

    # The angle between the major axis and our x axis is:
    l1, l2, v1, v2 = _2x2_eig(A_33)
    x_axis = np.array([1, 0])
    theta = np.arccos(x_axis.dot(v1))

    # The eccentricity is determined by:
    nu = 1
    numer = 2 * np.sqrt((A - C)**2 + B**2)
    denom = nu * (A + C) + np.sqrt((A - C)**2 + B**2)
    eccentricity = np.sqrt(numer / denom)

    from scipy.special import ellipeinc
    #-----------------------
    # DRAWING
    #-----------------------
    # Lets start off by drawing the ellipse that we are goign to work with
    # Create unit circle sample

    # Draw the keypoint using the tried and true df2
    # Other things should subsiquently align
    df2.draw_kpts2(np.array([(0, 0, ia11, ia21, ia22)]),
                   ell_linewidth=4,
                   ell_color=df2.DEEP_PINK,
                   ell_alpha=1,
                   arrow=True,
                   rect=True)

    # Plot ellipse points
    _plotpts(ellipse_pts1, 0, df2.YELLOW, label='invV.dot(cicrle_pts.T).T')

    # Plot ellipse axis
    # !HELP! I DO NOT KNOW WHY I HAVE TO DIVIDE, SQUARE ROOT, AND NEGATE!!!
    l1, l2, v1, v2 = _2x2_eig(A_33)
    dx1, dy1 = (v1 / np.sqrt(l1))
    dx2, dy2 = (v2 / np.sqrt(l2))
    _plotarrow(0, 0, dx1, -dy1, color=df2.ORANGE, label='ellipse axis')
    _plotarrow(0, 0, dx2, -dy2, color=df2.ORANGE)

    # Plot ellipse orientation
    orient_axis = invV.dot(np.eye(2))
    dx1, dx2, dy1, dy2 = orient_axis.flatten()
    _plotarrow(0, 0, dx1, dy1, color=df2.BLUE, label='ellipse rotation')
    _plotarrow(0, 0, dx2, dy2, color=df2.BLUE)

    df2.legend()
    df2.dark_background()
    df2.gca().invert_yaxis()
    return locals()
Example #7
0
def get_kp_border(rchip, kp):
    np.set_printoptions(precision=8)

    df2.reset()
    df2.figure(9003, docla=True, doclf=True)

    def _plotpts(data, px, color=df2.BLUE, label=''):
        #df2.figure(9003, docla=True, pnum=(1, 1, px))
        df2.plot2(data.T[0], data.T[1], '-', '', color=color, label=label)
        df2.update()

    def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''):
        ax = df2.gca()
        arrowargs = dict(head_width=.5, length_includes_head=True, label='')
        arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs)
        arrow.set_edgecolor(color)
        arrow.set_facecolor(color)
        ax.add_patch(arrow)
        df2.update()

    def _2x2_eig(M2x2):
        (evals, evecs) = np.linalg.eig(M2x2)
        l1, l2 = evals
        v1, v2 = evecs
        return l1, l2, v1, v2

    #-----------------------
    # INPUT
    #-----------------------
    # We are given the keypoint in invA format
    (x, y, ia11, ia21, ia22), ia12 = kp, 0

    # invA2x2 is a transformation from points on a unit circle to the ellipse
    invA2x2 = np.array([[ia11, ia12], [ia21, ia22]])

    #-----------------------
    # DRAWING
    #-----------------------
    # Lets start off by drawing the ellipse that we are goign to work with
    # Create unit circle sample
    tau = 2 * np.pi
    theta_list = np.linspace(0, tau, 1000)
    cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list])
    ellipse_pts = invA2x2.dot(cicrle_pts.T).T
    _plotpts(ellipse_pts, 0, df2.BLACK, label='invA2x2.dot(unit_circle)')
    l1, l2, v1, v2 = _2x2_eig(invA2x2)
    dx1, dy1 = (v1 * l1)
    dx2, dy2 = (v2 * l2)
    _plotarrow(0, 0, dx1, dy1, color=df2.ORANGE, label='invA2x2 e1')
    _plotarrow(0, 0, dx2, dy2, color=df2.RED, label='invA2x2 e2')

    #-----------------------
    # REPRESENTATION
    #-----------------------
    # A2x2 is a transformation from points on the ellipse to a unit circle
    A2x2 = np.linalg.inv(invA2x2)

    # Points on a matrix satisfy (x).T.dot(E2x2).dot(x) = 1
    E2x2 = A2x2.T.dot(A2x2)

    #Lets check our assertion: (x).T.dot(E2x2).dot(x) = 1
    checks = [pt.T.dot(E2x2).dot(pt) for pt in ellipse_pts]
    assert all([abs(1 - check) < 1E-11 for check in checks])

    #-----------------------
    # CONIC SECTIONS
    #-----------------------
    # All of this was from the Perdoch paper, now lets move into conic sections
    # We will use the notation from wikipedia
    # http://en.wikipedia.org/wiki/Conic_section
    # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections

    # The matrix representation of a conic is:
    ((A, B, B_, C), (D, E, F)) = (E2x2.flatten(), (0, 0, 1))
    assert B == B_, 'matrix should by symmetric'

    # A_Q is our conic section (aka ellipse matrix)
    A_Q = np.array(((A, B / 2, D / 2), (B / 2, C, E / 2), (D / 2, E / 2, F)))

    assert np.linalg.det(A_Q) != 0, 'degenerate conic'
    # As long as det(A_Q) is not 0 it is not degenerate and we can work with the
    # minor 2x2 matrix

    A_33 = np.array(((A, B / 2), (B / 2, C)))

    # (det == 0)->parabola, (det < 0)->hyperbola, (det > 0)->ellipse
    assert np.linalg.det(A_33) > 0, 'conic is not an ellipse'

    # Centers are obtained by solving for where the gradient of the quadratic
    # becomes 0. Without going through the derivation the calculation is...
    # These should be 0, 0 if we are at the origin, or our original x, y
    # coordinate specified by the keypoints. I'm doing the calculation just for
    # shits and giggles
    x_center = (B * E - (2 * C * D)) / (4 * A * C - B**2)
    y_center = (D * B - (2 * A * E)) / (4 * A * C - B**2)

    #=================
    # DRAWING
    #=================
    # Now we are going to determine the major and minor axis
    # of this beast. It just the center augmented by the eigenvecs
    l1, l2, v1, v2 = _2x2_eig(A_33)
    dx1, dy1 = 0 - (v1 / np.sqrt(l1))
    dx2, dy2 = 0 - (v2 / np.sqrt(l2))
    _plotarrow(0, 0, dx1, dy1, color=df2.BLUE)
    _plotarrow(0, 0, dx2, dy2, color=df2.BLUE)

    # The angle between the major axis and our x axis is:
    x_axis = np.array([1, 0])
    theta = np.arccos(x_axis.dot(evec1))

    # The eccentricity is determined by:
    nu = 1
    numer = 2 * np.sqrt((A - C)**2 + B**2)
    denom = nu * (A + C) + np.sqrt((A - C)**2 + B**2)
    eccentricity = np.sqrt(numer / denom)

    from scipy.special import ellipeinc

    # Algebraic form of connic
    #assert (a * (x ** 2)) + (b * (x * y)) + (c * (y ** 2)) + (d * x) + (e * y) + (f) == 0

    #---------------------

    invA = np.array([[a, 0], [c, d]])

    Ashape = np.linalg.inv(np.array([[a, 0], [c, d]]))
    Ashape /= np.sqrt(np.linalg.det(Ashape))

    tau = 2 * np.pi
    nSamples = 100
    theta_list = np.linspace(0, tau, nSamples)

    # Create unit circle sample
    cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list])
    circle_hpts = np.hstack([cicrle_pts, np.ones((len(cicrle_pts), 1))])

    # Transform as if the unit cirle was the warped patch
    ashape_pts = Ashape.dot(cicrle_pts.T).T

    inv = np.linalg.inv
    svd = np.linalg.svd
    U, S_, V = svd(Ashape)
    S = np.diag(S_)
    pxl_list3 = invA.dot(cicrle_pts[:, 0:2].T).T
    pxl_list4 = invA.dot(ashape_pts[:, 0:2].T).T
    pxl_list5 = invA.T.dot(cicrle_pts[:, 0:2].T).T
    pxl_list6 = invA.T.dot(ashape_pts[:, 0:2].T).T
    pxl_list7 = inv(V).dot(ashape_pts[:, 0:2].T).T
    pxl_list8 = inv(U).dot(ashape_pts[:, 0:2].T).T
    df2.draw()

    def _plot(data, px, title=''):
        df2.figure(9003, docla=True, pnum=(2, 4, px))
        df2.plot2(data.T[0], data.T[1], '.', title)

    df2.figure(9003, doclf=True)
    _plot(cicrle_pts, 1, 'unit circle')
    _plot(ashape_pts, 2, 'A => circle shape')
    _plot(pxl_list3, 3)
    _plot(pxl_list4, 4)
    _plot(pxl_list5, 5)
    _plot(pxl_list6, 6)
    _plot(pxl_list7, 7)
    _plot(pxl_list8, 8)
    df2.draw()

    invA = np.array([[a, 0, x], [c, d, y], [0, 0, 1]])

    pxl_list = invA.dot(circle_hpts.T).T[:, 0:2]

    df2.figure(9002, doclf=True)
    df2.imshow(rchip)
    df2.plot2(pxl_list.T[0], pxl_list.T[1], '.')
    df2.draw()

    vals = [cv2.getRectSubPix(rchip, (1, 1), tuple(pxl)) for pxl in pxl_list]
    return vals
Example #8
0
def in_depth_ellipse2x2(rchip, kp):
    #-----------------------
    # SETUP
    #-----------------------
    from hotspotter import draw_func2 as df2
    np.set_printoptions(precision=8)
    tau = 2 * np.pi
    df2.reset()
    df2.figure(9003, docla=True, doclf=True)
    ax = df2.gca()
    ax.invert_yaxis()

    def _plotpts(data, px, color=df2.BLUE, label=''):
        #df2.figure(9003, docla=True, pnum=(1, 1, px))
        df2.plot2(data.T[0], data.T[1], '.', '', color=color, label=label)
        df2.update()

    def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''):
        ax = df2.gca()
        arrowargs = dict(head_width=.5, length_includes_head=True, label=label)
        arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs)
        arrow.set_edgecolor(color)
        arrow.set_facecolor(color)
        ax.add_patch(arrow)
        df2.update()

    def _2x2_eig(M2x2):
        (evals, evecs) = np.linalg.eig(M2x2)
        l1, l2 = evals
        v1, v2 = evecs
        return l1, l2, v1, v2

    #-----------------------
    # INPUT
    #-----------------------
    # We will call perdoch's invA = invV
    print('--------------------------------')
    print('Let V = Perdoch.A')
    print('Let Z = Perdoch.E')
    print('--------------------------------')
    print('Input from Perdoch\'s detector: ')

    # We are given the keypoint in invA format
    (x, y, ia11, ia21, ia22), ia12 = kp, 0
    invV = np.array([[ia11, ia12],
                     [ia21, ia22]])
    V = np.linalg.inv(invV)
    # <HACK>
    #invV = V / np.linalg.det(V)
    #V = np.linalg.inv(V)
    # </HACK>
    Z = (V.T).dot(V)

    print('invV is a transform from points on a unit-circle to the ellipse')
    helpers.horiz_print('invV = ', invV)
    print('--------------------------------')
    print('V is a transformation from points on the ellipse to a unit circle')
    helpers.horiz_print('V = ', V)
    print('--------------------------------')
    print('Points on a matrix satisfy (x).T.dot(Z).dot(x) = 1')
    print('where Z = (V.T).dot(V)')
    helpers.horiz_print('Z = ', Z)

    # Define points on a unit circle
    theta_list = np.linspace(0, tau, 50)
    cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list])

    # Transform those points to the ellipse using invV
    ellipse_pts1 = invV.dot(cicrle_pts.T).T

    # Transform those points to the ellipse using V
    ellipse_pts2 = V.dot(cicrle_pts.T).T

    #Lets check our assertion: (x_).T.dot(Z).dot(x_) = 1
    checks1 = [x_.T.dot(Z).dot(x_) for x_ in ellipse_pts1]
    checks2 = [x_.T.dot(Z).dot(x_) for x_ in ellipse_pts2]
    assert all([abs(1 - check) < 1E-11 for check in checks1])
    #assert all([abs(1 - check) < 1E-11 for check in checks2])
    print('... all of our plotted points satisfy this')

    #=======================
    # THE CONIC SECTION
    #=======================
    # All of this was from the Perdoch paper, now lets move into conic sections
    # We will use the notation from wikipedia
    # http://en.wikipedia.org/wiki/Conic_section
    # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections

    #-----------------------
    # MATRIX REPRESENTATION
    #-----------------------
    # The matrix representation of a conic is:
    (A,  B2, B2_, C) = Z.flatten()
    (D, E, F) = (0, 0, 1)
    B = B2 * 2
    assert B2 == B2_, 'matrix should by symmetric'
    print('--------------------------------')
    print('Now, using wikipedia\' matrix representation of a conic.')
    con = np.array((('    A', 'B / 2', 'D / 2'),
                    ('B / 2', '    C', 'E / 2'),
                    ('D / 2', 'E / 2', '    F')))
    helpers.horiz_print('A matrix A_Q = ', con)

    # A_Q is our conic section (aka ellipse matrix)
    A_Q = np.array(((    A, B / 2, D / 2),
                    (B / 2,     C, E / 2),
                    (D / 2, E / 2,     F)))

    helpers.horiz_print('A_Q = ', A_Q)

    #-----------------------
    # DEGENERATE CONICS
    #-----------------------
    print('----------------------------------')
    print('As long as det(A_Q) != it is not degenerate.')
    print('If the conic is not degenerate, we can use the 2x2 minor: A_33')
    print('det(A_Q) = %s' % str(np.linalg.det(A_Q)))
    assert np.linalg.det(A_Q) != 0, 'degenerate conic'
    A_33 = np.array(((    A, B / 2),
                     (B / 2,     C)))
    helpers.horiz_print('A_33 = ', A_33)

    #-----------------------
    # CONIC CLASSIFICATION
    #-----------------------
    print('----------------------------------')
    print('The determinant of the minor classifies the type of conic it is')
    print('(det == 0): parabola, (det < 0): hyperbola, (det > 0): ellipse')
    print('det(A_33) = %s' % str(np.linalg.det(A_33)))
    assert np.linalg.det(A_33) > 0, 'conic is not an ellipse'
    print('... this is indeed an ellipse')

    #-----------------------
    # CONIC CENTER
    #-----------------------
    print('----------------------------------')
    print('the centers of the ellipse are obtained by: ')
    print('x_center = (B * E - (2 * C * D)) / (4 * A * C - B ** 2)')
    print('y_center = (D * B - (2 * A * E)) / (4 * A * C - B ** 2)')
    # Centers are obtained by solving for where the gradient of the quadratic
    # becomes 0. Without going through the derivation the calculation is...
    # These should be 0, 0 if we are at the origin, or our original x, y
    # coordinate specified by the keypoints. I'm doing the calculation just for
    # shits and giggles
    x_center = (B * E - (2 * C * D)) / (4 * A * C - B ** 2)
    y_center = (D * B - (2 * A * E)) / (4 * A * C - B ** 2)
    helpers.horiz_print('x_center = ', x_center)
    helpers.horiz_print('y_center = ', y_center)

    #-----------------------
    # MAJOR AND MINOR AXES
    #-----------------------
    # Now we are going to determine the major and minor axis
    # of this beast. It just the center augmented by the eigenvecs
    print('----------------------------------')

    # The angle between the major axis and our x axis is:
    l1, l2, v1, v2 = _2x2_eig(A_33)
    x_axis = np.array([1, 0])
    theta = np.arccos(x_axis.dot(v1))

    # The eccentricity is determined by:
    nu = 1
    numer  = 2 * np.sqrt((A - C) ** 2 + B ** 2)
    denom  = nu * (A + C) + np.sqrt((A - C) ** 2 + B ** 2)
    eccentricity = np.sqrt(numer / denom)

    from scipy.special import ellipeinc
    #-----------------------
    # DRAWING
    #-----------------------
    # Lets start off by drawing the ellipse that we are goign to work with
    # Create unit circle sample

    # Draw the keypoint using the tried and true df2
    # Other things should subsiquently align
    df2.draw_kpts2(np.array([(0, 0, ia11, ia21, ia22)]), ell_linewidth=4,
                   ell_color=df2.DEEP_PINK, ell_alpha=1, arrow=True, rect=True)

    # Plot ellipse points
    _plotpts(ellipse_pts1, 0, df2.YELLOW, label='invV.dot(cicrle_pts.T).T')

    # Plot ellipse axis
    # !HELP! I DO NOT KNOW WHY I HAVE TO DIVIDE, SQUARE ROOT, AND NEGATE!!!
    l1, l2, v1, v2 = _2x2_eig(A_33)
    dx1, dy1 = (v1 / np.sqrt(l1))
    dx2, dy2 = (v2 / np.sqrt(l2))
    _plotarrow(0, 0, dx1, -dy1, color=df2.ORANGE, label='ellipse axis')
    _plotarrow(0, 0, dx2, -dy2, color=df2.ORANGE)

    # Plot ellipse orientation
    orient_axis = invV.dot(np.eye(2))
    dx1, dx2, dy1, dy2 = orient_axis.flatten()
    _plotarrow(0, 0, dx1, dy1, color=df2.BLUE, label='ellipse rotation')
    _plotarrow(0, 0, dx2, dy2, color=df2.BLUE)

    df2.legend()
    df2.dark_background()
    df2.gca().invert_yaxis()
    return locals()
Example #9
0
def get_kp_border(rchip, kp):
    np.set_printoptions(precision=8)

    df2.reset()
    df2.figure(9003, docla=True, doclf=True)

    def _plotpts(data, px, color=df2.BLUE, label=''):
        #df2.figure(9003, docla=True, pnum=(1, 1, px))
        df2.plot2(data.T[0], data.T[1], '-', '', color=color, label=label)
        df2.update()

    def _plotarrow(x, y, dx, dy, color=df2.BLUE, label=''):
        ax = df2.gca()
        arrowargs = dict(head_width=.5, length_includes_head=True, label='')
        arrow = df2.FancyArrow(x, y, dx, dy, **arrowargs)
        arrow.set_edgecolor(color)
        arrow.set_facecolor(color)
        ax.add_patch(arrow)
        df2.update()

    def _2x2_eig(M2x2):
        (evals, evecs) = np.linalg.eig(M2x2)
        l1, l2 = evals
        v1, v2 = evecs
        return l1, l2, v1, v2

    #-----------------------
    # INPUT
    #-----------------------
    # We are given the keypoint in invA format
    (x, y, ia11, ia21, ia22), ia12 = kp, 0

    # invA2x2 is a transformation from points on a unit circle to the ellipse
    invA2x2 = np.array([[ia11, ia12],
                        [ia21, ia22]])

    #-----------------------
    # DRAWING
    #-----------------------
    # Lets start off by drawing the ellipse that we are goign to work with
    # Create unit circle sample
    tau = 2 * np.pi
    theta_list = np.linspace(0, tau, 1000)
    cicrle_pts = np.array([(np.cos(t), np.sin(t)) for t in theta_list])
    ellipse_pts = invA2x2.dot(cicrle_pts.T).T
    _plotpts(ellipse_pts, 0, df2.BLACK, label='invA2x2.dot(unit_circle)')
    l1, l2, v1, v2 = _2x2_eig(invA2x2)
    dx1, dy1 = (v1 * l1)
    dx2, dy2 = (v2 * l2)
    _plotarrow(0, 0, dx1, dy1, color=df2.ORANGE, label='invA2x2 e1')
    _plotarrow(0, 0, dx2, dy2, color=df2.RED, label='invA2x2 e2')

    #-----------------------
    # REPRESENTATION
    #-----------------------
    # A2x2 is a transformation from points on the ellipse to a unit circle
    A2x2 = np.linalg.inv(invA2x2)

    # Points on a matrix satisfy (x).T.dot(E2x2).dot(x) = 1
    E2x2 = A2x2.T.dot(A2x2)

    #Lets check our assertion: (x).T.dot(E2x2).dot(x) = 1
    checks = [pt.T.dot(E2x2).dot(pt) for pt in ellipse_pts]
    assert all([abs(1 - check) < 1E-11 for check in checks])

    #-----------------------
    # CONIC SECTIONS
    #-----------------------
    # All of this was from the Perdoch paper, now lets move into conic sections
    # We will use the notation from wikipedia
    # http://en.wikipedia.org/wiki/Conic_section
    # http://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections

    # The matrix representation of a conic is:
    ((A,  B, B_, C), (D, E, F)) = (E2x2.flatten(), (0, 0, 1))
    assert B == B_, 'matrix should by symmetric'

    # A_Q is our conic section (aka ellipse matrix)
    A_Q = np.array(((    A, B / 2, D / 2),
                    (B / 2,     C, E / 2),
                    (D / 2, E / 2,     F)))

    assert np.linalg.det(A_Q) != 0, 'degenerate conic'
    # As long as det(A_Q) is not 0 it is not degenerate and we can work with the
    # minor 2x2 matrix

    A_33 = np.array(((    A, B / 2),
                     (B / 2,     C)))

    # (det == 0)->parabola, (det < 0)->hyperbola, (det > 0)->ellipse
    assert np.linalg.det(A_33) > 0, 'conic is not an ellipse'

    # Centers are obtained by solving for where the gradient of the quadratic
    # becomes 0. Without going through the derivation the calculation is...
    # These should be 0, 0 if we are at the origin, or our original x, y
    # coordinate specified by the keypoints. I'm doing the calculation just for
    # shits and giggles
    x_center = (B * E - (2 * C * D)) / (4 * A * C - B ** 2)
    y_center = (D * B - (2 * A * E)) / (4 * A * C - B ** 2)

    #=================
    # DRAWING
    #=================
    # Now we are going to determine the major and minor axis
    # of this beast. It just the center augmented by the eigenvecs
    l1, l2, v1, v2 = _2x2_eig(A_33)
    dx1, dy1 = 0 - (v1 / np.sqrt(l1))
    dx2, dy2 = 0 - (v2 / np.sqrt(l2))
    _plotarrow(0, 0, dx1, dy1, color=df2.BLUE)
    _plotarrow(0, 0, dx2, dy2, color=df2.BLUE)

    # The angle between the major axis and our x axis is:
    x_axis = np.array([1, 0])
    theta = np.arccos(x_axis.dot(evec1))


    # The eccentricity is determined by:
    nu = 1
    numer  = 2 * np.sqrt((A - C) ** 2 + B ** 2)
    denom  = nu * (A + C) + np.sqrt((A - C) ** 2 + B ** 2)
    eccentricity = np.sqrt(numer / denom)



    from scipy.special import ellipeinc


    # Algebraic form of connic
    #assert (a * (x ** 2)) + (b * (x * y)) + (c * (y ** 2)) + (d * x) + (e * y) + (f) == 0




    #---------------------

    invA = np.array([[a, 0],
                     [c, d]])

    Ashape = np.linalg.inv(np.array([[a, 0],
                                     [c, d]]))
    Ashape /= np.sqrt(np.linalg.det(Ashape))

    tau = 2 * np.pi
    nSamples = 100
    theta_list = np.linspace(0, tau, nSamples)

    # Create unit circle sample
    cicrle_pts  = np.array([(np.cos(t), np.sin(t)) for t in theta_list])
    circle_hpts = np.hstack([cicrle_pts, np.ones((len(cicrle_pts), 1))])

    # Transform as if the unit cirle was the warped patch
    ashape_pts = Ashape.dot(cicrle_pts.T).T

    inv = np.linalg.inv
    svd = np.linalg.svd
    U, S_, V = svd(Ashape)
    S = np.diag(S_)
    pxl_list3 = invA.dot(cicrle_pts[:, 0:2].T).T
    pxl_list4 = invA.dot(ashape_pts[:, 0:2].T).T
    pxl_list5 = invA.T.dot(cicrle_pts[:, 0:2].T).T
    pxl_list6 = invA.T.dot(ashape_pts[:, 0:2].T).T
    pxl_list7 = inv(V).dot(ashape_pts[:, 0:2].T).T
    pxl_list8 = inv(U).dot(ashape_pts[:, 0:2].T).T
    df2.draw()


    def _plot(data, px, title=''):
        df2.figure(9003, docla=True, pnum=(2, 4, px))
        df2.plot2(data.T[0], data.T[1], '.', title)

    df2.figure(9003, doclf=True)
    _plot(cicrle_pts, 1, 'unit circle')
    _plot(ashape_pts, 2, 'A => circle shape')
    _plot(pxl_list3, 3)
    _plot(pxl_list4, 4)
    _plot(pxl_list5, 5)
    _plot(pxl_list6, 6)
    _plot(pxl_list7, 7)
    _plot(pxl_list8, 8)
    df2.draw()


    invA = np.array([[a, 0, x],
                     [c, d, y],
                     [0, 0, 1]])

    pxl_list = invA.dot(circle_hpts.T).T[:, 0:2]

    df2.figure(9002, doclf=True)
    df2.imshow(rchip)
    df2.plot2(pxl_list.T[0], pxl_list.T[1], '.')
    df2.draw()

    vals = [cv2.getRectSubPix(rchip, (1, 1), tuple(pxl)) for pxl in pxl_list]
    return vals