예제 #1
0
파일: viz.py 프로젝트: Erotemic/hotspotter
def show_name(hs, nx, nx2_cxs=None, fnum=0, sel_cxs=[], subtitle='',
              annote=False, **kwargs):
    print('[viz] show_name nx=%r' % nx)
    nx2_name = hs.tables.nx2_name
    cx2_nx   = hs.tables.cx2_nx
    name = nx2_name[nx]
    if not nx2_cxs is None:
        cxs = nx2_cxs[nx]
    else:
        cxs = np.where(cx2_nx == nx)[0]
    print('[viz] show_name %r' % hs.cidstr(cxs))
    nRows, nCols = get_square_row_cols(len(cxs))
    print('[viz*] r=%r, c=%r' % (nRows, nCols))
    #gs2 = gridspec.GridSpec(nRows, nCols)
    pnum = lambda px: (nRows, nCols, px + 1)
    fig = df2.figure(fnum=fnum, pnum=pnum(0), **kwargs)
    fig.clf()
    # Trigger computation of all chips in parallel
    hs.refresh_features(cxs)
    for px, cx in enumerate(cxs):
        show_chip(hs, cx=cx, pnum=pnum(px), draw_ell=annote, kpts_alpha=.2)
        if cx in sel_cxs:
            ax = df2.gca()
            df2.draw_border(ax, df2.GREEN, 4)
        #plot_cx3(hs, cx)
    if isinstance(nx, np.ndarray):
        nx = nx[0]
    if isinstance(name, np.ndarray):
        name = name[0]

    figtitle = 'Name View nx=%r name=%r' % (nx, name)
    df2.set_figtitle(figtitle)
예제 #2
0
def plot_time(unixtime_list):
    import draw_func2 as df2
    unixtime_list = np.array(unixtime_list)
    fixed_time = unixtime_list[unixtime_list > 0]
    df2.plot(sorted(unixtime_list))
    ax = df2.gca()
    ax.set_ylim(fixed_time.min(), fixed_time.max())
예제 #3
0
파일: viz.py 프로젝트: obaiga/hotspotter
 def _distplot(dists, color, label, distkey, plot_type=plot_type):
     data = sorted(dists)
     ax = df2.gca()
     min_ = distkey2_min[distkey]
     max_ = distkey2_max[distkey]
     if plot_type == 'plot':
         df2.plot(data, color=color, label=label)
         #xticks = np.linspace(np.min(data), np.max(data), 3)
         #yticks = np.linspace(0, len(data), 5)
         #ax.set_xticks(xticks)
         #ax.set_yticks(yticks)
         ax.set_ylim(min_, max_)
         ax.set_xlim(0, len(dists))
         ax.set_ylabel('distance')
         ax.set_xlabel('matches indexes (sorted by distance)')
         df2.legend(loc='lower right')
     if plot_type == 'pdf':
         df2.plot_pdf(data, color=color, label=label)
         ax.set_ylabel('pr')
         ax.set_xlabel('distance')
         ax.set_xlim(min_, max_)
         df2.legend(loc='upper right')
     df2.dark_background(ax)
     df2.small_xticks(ax)
     df2.small_yticks(ax)
예제 #4
0
파일: viz.py 프로젝트: Erotemic/hotspotter
 def _distplot(dists, color, label, distkey, plot_type=plot_type):
     data = sorted(dists)
     ax = df2.gca()
     min_ = distkey2_min[distkey]
     max_ = distkey2_max[distkey]
     if plot_type == 'plot':
         df2.plot(data, color=color, label=label)
         #xticks = np.linspace(np.min(data), np.max(data), 3)
         #yticks = np.linspace(0, len(data), 5)
         #ax.set_xticks(xticks)
         #ax.set_yticks(yticks)
         ax.set_ylim(min_, max_)
         ax.set_xlim(0, len(dists))
         ax.set_ylabel('distance')
         ax.set_xlabel('matches indexes (sorted by distance)')
         df2.legend(loc='lower right')
     if plot_type == 'pdf':
         df2.plot_pdf(data, color=color, label=label)
         ax.set_ylabel('pr')
         ax.set_xlabel('distance')
         ax.set_xlim(min_, max_)
         df2.legend(loc='upper right')
     df2.dark_background(ax)
     df2.small_xticks(ax)
     df2.small_yticks(ax)
예제 #5
0
파일: viz.py 프로젝트: Erotemic/hotspotter
def show_keypoints(rchip, kpts, draw_ell=True, draw_pts=False, sel_fx=None, fnum=0,
                   pnum=None, color=None, rect=False, **kwargs):
    df2.imshow(rchip, fnum=fnum, pnum=pnum, **kwargs)
    _annotate_kpts(kpts, sel_fx, draw_ell, draw_pts, color=color, rect=rect)
    ax = df2.gca()
    ax._hs_viewtype = 'keypoints'
    ax._hs_kpts = kpts
예제 #6
0
 def _on_chip_click(event):
     print_('[inter] clicked chip')
     ax, x, y = event.inaxes, event.xdata, event.ydata
     if ax is None or x is None:
         # The click is not in any axis
         print('... out of axis')
         annote_ptr[0] = (annote_ptr[0] + 1) % 3
         mode = annote_ptr[0]
         draw_ell = mode == 1
         draw_pts = mode == 2
         print('... default kpts view mode=%r' % mode)
         _chip_view(draw_ell=draw_ell, draw_pts=draw_pts)
     else:
         hs_viewtype = ax.__dict__.get('_hs_viewtype', '')
         print_(' hs_viewtype=%r' % hs_viewtype)
         if hs_viewtype == 'chip' and event.key == 'shift':
             print('... masking')
             # TODO: Do better integration of masking
             _chip_view()
             df2.disconnect_callback(fig, 'button_press_event')
             mc = mask_creator.MaskCreator(df2.gca())  # NOQA
         elif hs_viewtype == 'chip':
             kpts = hs.get_kpts(cx)
             if len(kpts) > 0:
                 fx = nearest_point(x, y, kpts)[0]
                 print('... clicked fx=%r' % fx)
                 _select_ith_kpt(fx)
             else:
                 print('... len(kpts) == 0')
         else:
             print('...Unknown viewtype')
     viz.draw()
예제 #7
0
 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()
예제 #8
0
 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()
예제 #9
0
파일: viz.py 프로젝트: obaiga/hotspotter
def show_keypoints(rchip,
                   kpts,
                   draw_ell=True,
                   draw_pts=False,
                   sel_fx=None,
                   fnum=0,
                   pnum=None,
                   color=None,
                   rect=False,
                   **kwargs):
    df2.imshow(rchip, fnum=fnum, pnum=pnum, **kwargs)
    _annotate_kpts(kpts, sel_fx, draw_ell, draw_pts, color=color, rect=rect)
    ax = df2.gca()
    ax._hs_viewtype = 'keypoints'
    ax._hs_kpts = kpts
예제 #10
0
파일: viz.py 프로젝트: obaiga/hotspotter
def show_name(hs,
              nx,
              nx2_cxs=None,
              fnum=0,
              sel_cxs=[],
              subtitle='',
              annote=False,
              **kwargs):
    print('[viz] show_name nx=%r' % nx)
    nx2_name = hs.tables.nx2_name
    cx2_nx = hs.tables.cx2_nx
    name = nx2_name[nx]
    if not nx2_cxs is None:
        cxs = nx2_cxs[nx]
    else:
        cxs = np.where(cx2_nx == nx)[0]
    print('[viz] show_name %r' % hs.cidstr(cxs))
    nRows, nCols = get_square_row_cols(len(cxs))
    print('[viz*] r=%r, c=%r' % (nRows, nCols))
    #gs2 = gridspec.GridSpec(nRows, nCols)
    pnum = lambda px: (nRows, nCols, px + 1)
    fig = df2.figure(fnum=fnum, pnum=pnum(0), **kwargs)
    fig.clf()
    # Trigger computation of all chips in parallel
    hs.refresh_features(cxs)
    for px, cx in enumerate(cxs):
        show_chip(hs, cx=cx, pnum=pnum(px), draw_ell=annote, kpts_alpha=.2)
        if cx in sel_cxs:
            ax = df2.gca()
            df2.draw_border(ax, df2.GREEN, 4)
        #plot_cx3(hs, cx)
    if isinstance(nx, np.ndarray):
        nx = nx[0]
    if isinstance(name, np.ndarray):
        name = name[0]

    figtitle = 'Name View nx=%r name=%r' % (nx, name)
    df2.set_figtitle(figtitle)
예제 #11
0
파일: viz.py 프로젝트: obaiga/hotspotter
def annotate_chipres(hs,
                     res,
                     cx,
                     showTF=True,
                     showScore=True,
                     title_pref='',
                     title_suff='',
                     show_2nd_gname=True,
                     show_2nd_name=True,
                     show_1st=True,
                     time_appart=True,
                     in_image=False,
                     offset1=(0, 0),
                     offset2=(0, 0),
                     show_query=True,
                     xywh2=None,
                     **kwargs):

    printDBG('[viz] annotate_chipres()')
    #print('Did not expect args: %r' % (kwargs.keys(),))
    qcx = res.qcx
    score = res.cx2_score[cx]
    matched_kpts = np.float32(len(res.cx2_fs[cx]))
    #    print('matched_kpts= %r'%str(matched_kpts))
    # TODO Use this function when you clean show_chipres
    (truestr, falsestr, nonamestr) = ('TRUE', 'FALSE', '???')
    is_true, is_unknown = hs.is_true_match(qcx, cx)
    isgt_str = nonamestr if is_unknown else (truestr if is_true else falsestr)
    match_color = {
        nonamestr: df2.UNKNOWN_PURP,
        truestr: df2.TRUE_GREEN,
        falsestr: df2.FALSE_RED
    }[isgt_str]
    # Build title
    title = '*%s*' % isgt_str if showTF else ''
    if showScore:
        score_str = (' score=' + helpers.num_fmt(score)) % (score)
        score_str += ('   matched_kpts=' +
                      helpers.num_fmt(matched_kpts)) % (matched_kpts)
        title += score_str
    title = title_pref + str(title) + title_suff
    # Build xlabel
    xlabel_ = []

    if 'show_1st':
        xlabel_.append('top_gname=%r' % hs.cx2_gname(qcx))
        xlabel_.append('top_name=%r' % hs.cx2_name(qcx))

    if 'show_2nd_gname':
        xlabel_.append('\n below_gname=%r' % hs.cx2_gname(cx))
    if 'show_2nd_name':
        xlabel_.append('below_name=%r' % hs.cx2_name(cx))

    if 'time_appart':
        xlabel_.append('\n' + hs.get_timedelta_str(qcx, cx))
    xlabel = ', '.join(xlabel_)
    ax = df2.gca()
    ax._hs_viewtype = 'chipres'
    ax._hs_qcx = qcx
    ax._hs_cx = cx
    if NO_LABEL_OVERRIDE:
        title = ''
        xlabel = ''
    df2.set_title(title, ax)
    df2.set_xlabel(xlabel, ax)
    if in_image:
        roi1 = hs.cx2_roi(qcx) + np.array(list(offset1) + [0, 0])
        roi2 = hs.cx2_roi(cx) + np.array(list(offset2) + [0, 0])
        theta1 = hs.cx2_theta(qcx)
        theta2 = hs.cx2_theta(cx)
        # HACK!
        lbl1 = 'q' + hs.cidstr(qcx)
        lbl2 = hs.cidstr(cx)
        if show_query:
            df2.draw_roi(roi1, bbox_color=df2.ORANGE, label=lbl1, theta=theta1)
        df2.draw_roi(roi2, bbox_color=match_color, label=lbl2, theta=theta2)
        # No matches draw a red box
        if len(res.cx2_fm[cx]) == 0:
            df2.draw_boxedX(roi2, theta=theta2)
    else:
        if xywh2 is None:
            xy, w, h = df2._axis_xy_width_height(ax)
            xywh2 = (xy[0], xy[1], w, h)
        df2.draw_border(ax, match_color, 4, offset=offset2)
        # No matches draw a red box
        if len(res.cx2_fm[cx]) == 0:
            df2.draw_boxedX(xywh2)
예제 #12
0
파일: viz.py 프로젝트: Erotemic/hotspotter
def annotate_chipres(hs, res, cx, showTF=True, showScore=True, title_pref='',
                     title_suff='', show_gname=False, show_name=True,
                     time_appart=True, in_image=False, offset1=(0, 0),
                     offset2=(0, 0), show_query=True, xywh2=None, **kwargs):
    printDBG('[viz] annotate_chipres()')
    #print('Did not expect args: %r' % (kwargs.keys(),))
    qcx = res.qcx
    score = res.cx2_score[cx]
    # TODO Use this function when you clean show_chipres
    (truestr, falsestr, nonamestr) = ('TRUE', 'FALSE', '???')
    is_true, is_unknown = hs.is_true_match(qcx, cx)
    isgt_str = nonamestr if is_unknown else (truestr if is_true else falsestr)
    match_color = {nonamestr: df2.UNKNOWN_PURP,
                   truestr:   df2.TRUE_GREEN,
                   falsestr:  df2.FALSE_RED}[isgt_str]
    # Build title
    title = '*%s*' % isgt_str if showTF else ''
    if showScore:
        score_str = (' score=' + helpers.num_fmt(score)) % (score)
        title += score_str
    title = title_pref + str(title) + title_suff
    # Build xlabel
    xlabel_ = []
    if 'show_gname':
        xlabel_.append('gname=%r' % hs.cx2_gname(cx))
    if 'show_name':
        xlabel_.append('name=%r' % hs.cx2_name(cx))
    if 'time_appart':
        xlabel_.append('\n' + hs.get_timedelta_str(qcx, cx))
    xlabel = ', '.join(xlabel_)
    ax = df2.gca()
    ax._hs_viewtype = 'chipres'
    ax._hs_qcx = qcx
    ax._hs_cx = cx
    if NO_LABEL_OVERRIDE:
        title = ''
        xlabel = ''
    df2.set_title(title, ax)
    df2.set_xlabel(xlabel, ax)
    if in_image:
        roi1 = hs.cx2_roi(qcx) + np.array(list(offset1) + [0, 0])
        roi2 = hs.cx2_roi(cx) + np.array(list(offset2) + [0, 0])
        theta1 = hs.cx2_theta(qcx)
        theta2 = hs.cx2_theta(cx)
        # HACK!
        lbl1 = 'q' + hs.cidstr(qcx)
        lbl2 = hs.cidstr(cx)
        if show_query:
            df2.draw_roi(roi1, bbox_color=df2.ORANGE, label=lbl1, theta=theta1)
        df2.draw_roi(roi2, bbox_color=match_color, label=lbl2, theta=theta2)
        # No matches draw a red box
        if len(res.cx2_fm[cx]) == 0:
            df2.draw_boxedX(roi2, theta=theta2)
    else:
        if xywh2 is None:
            xy, w, h = df2._axis_xy_width_height(ax)
            xywh2 = (xy[0], xy[1], w, h)
        df2.draw_border(ax, match_color, 4, offset=offset2)
        # No matches draw a red box
        if len(res.cx2_fm[cx]) == 0:
            df2.draw_boxedX(xywh2)
예제 #13
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()
예제 #14
0
def begin_interaction(type_, fnum):
    print('[inter] starting %s interaction' % type_)
    fig = df2.figure(fnum=fnum, docla=True, doclf=True)
    ax = df2.gca()
    df2.disconnect_callback(fig, 'button_press_event', axes=[ax])
    return fig
예제 #15
0
 def query_last_feature():
     viz.show_nearest_descriptors(hs, qcx, last_state.last_fx, df2.next_fnum())
     fig3 = df2.gca()
     df2.connect_callback(fig3, 'button_press_event', _click_chipres_click)
     df2.update()
예제 #16
0
def show_descriptors_match_distances(orgres2_distance,
                                     fnum=1,
                                     db_name='',
                                     **kwargs):
    disttype_list = orgres2_distance.itervalues().next().keys()
    orgtype_list = orgres2_distance.keys()
    (nRow, nCol) = len(orgtype_list), len(disttype_list)
    nColors = nRow * nCol
    color_list = df2.distinct_colors(nColors)
    df2.figure(fnum=fnum, docla=True, doclf=True)
    pnum_ = lambda px: (nRow, nCol, px + 1)
    plot_type = helpers.get_arg('--plot-type', default='plot')

    # Remember min and max val for each distance type (l1, emd...)
    distkey2_min = {distkey: np.uint64(-1) for distkey in disttype_list}
    distkey2_max = {distkey: 0 for distkey in disttype_list}

    def _distplot(dists, color, label, distkey, plot_type=plot_type):
        data = sorted(dists)
        ax = df2.gca()
        min_ = distkey2_min[distkey]
        max_ = distkey2_max[distkey]
        if plot_type == 'plot':
            df2.plot(data, color=color, label=label, yscale='linear')
            #xticks = np.linspace(np.min(data), np.max(data), 3)
            #yticks = np.linspace(0, len(data), 5)
            #ax.set_xticks(xticks)
            #ax.set_yticks(yticks)
            ax.set_ylim(min_, max_)
            ax.set_xlim(0, len(dists))
            ax.set_ylabel('distance')
            ax.set_xlabel('matches indexes (sorted by distance)')
            df2.legend(loc='lower right')
        if plot_type == 'pdf':
            df2.plot_pdf(data, color=color, label=label)
            ax.set_ylabel('pr')
            ax.set_xlabel('distance')
            ax.set_xlim(min_, max_)
            df2.legend(loc='upper left')
        df2.dark_background(ax)
        df2.small_xticks(ax)
        df2.small_yticks(ax)

    px = 0
    for orgkey in orgtype_list:
        for distkey in disttype_list:
            dists = orgres2_distance[orgkey][distkey]
            if len(dists) == 0:
                continue
            min_ = dists.min()
            max_ = dists.max()
            distkey2_min[distkey] = min(distkey2_min[distkey], min_)
            distkey2_max[distkey] = max(distkey2_max[distkey], max_)

    for count, orgkey in enumerate(orgtype_list):
        for distkey in disttype_list:
            printDBG('[allres-viz] plotting: %r' % ((orgkey, distkey), ))
            dists = orgres2_distance[orgkey][distkey]
            df2.figure(fnum=fnum, pnum=pnum_(px))
            color = color_list[px]
            title = distkey + ' ' + orgkey
            label = 'P(%s | %s)' % (distkey, orgkey)
            _distplot(dists, color, label, distkey, **kwargs)
            if count == 0:
                ax = df2.gca()
                ax.set_title(distkey)
            px += 1

    subtitle = 'the matching distances between sift descriptors'
    title = '(sift) matching distances'
    if db_name != '':
        title = db_name + ' ' + title
    df2.set_figtitle(title, subtitle)
    df2.adjust_subplots_safe()
예제 #17
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()