def on_self_left_down(self, event=None):
        self._hover_point = None
        xy = (event.X, event.Y)
        side, imxy = self.locate_mouse(xy)
        if side is not None:
            L = self._left_points if side == LEFT_SIDE else self._right_points
            i, p = geometry.find_point_within_distance(imxy, L, DRAG_RADIUS)
            if i is None:
                L.append(imxy)
            else:
                self._drag_side = side
                self._drag_index = i
                self._drag_offset = np.subtract(p, xy)

        self.Refresh()
    def on_self_left_down(self, event=None):
        self._hover_point = None
        xy = (event.X, event.Y)
        side,imxy = self.locate_mouse(xy)
        if side is not None:
            L = self._left_points if side == LEFT_SIDE else self._right_points
            i,p = geometry.find_point_within_distance(imxy, L, DRAG_RADIUS)
            if i is None:
                L.append(imxy)
            else:
                self._drag_side = side
                self._drag_index = i
                self._drag_offset = np.subtract(p, xy)

        self.Refresh()
    def on_self_paint(self, event=None):
        #dc = wx.PaintDC(self)
        dc = wx.ClientDC(self)
        dc.Clear()

        dc.DrawBitmap(self._left_bitmap, self._left_offset)
        dc.DrawBitmap(self._right_bitmap, self._right_offset)

        HOVER_ALPHA = 80
        LINE_ALPHA = 140
        HOMOGRAPHY_ALPHA = 160

        # Draw the correspondence arcs
        dc.SetPen(wx.Pen((255, 0, 0, LINE_ALPHA), 2))
        for i in range(min(len(self._left_points), len(self._right_points))):
            lxy = np.add(self._left_offset, self._left_points[i])
            rxy = np.add(self._right_offset, self._right_points[i])
            dc.DrawLine(lxy[0], lxy[1], rxy[0], rxy[1])

        # Draw the points
        dc.SetPen(wx.Pen((255, 0, 0, LINE_ALPHA), 6))
        for lx, ly in self._left_points:
            dc.DrawPoint(self._left_offset[0] + lx, self._left_offset[1] + ly)
        for rx, ry in self._right_points:
            dc.DrawPoint(self._right_offset[0] + rx,
                         self._right_offset[1] + ry)

        # Find the closest point
        if self._hover_point is not None:
            side, imxy = self.locate_mouse(self._hover_point)
            if side is not None:
                L = self._left_points if side == LEFT_SIDE else self._right_points
                hover_index, p = geometry.find_point_within_distance(
                    imxy, L, DRAG_RADIUS)

        # Draw the hover arc
        grey = wx.Colour(0, 0, 0, HOVER_ALPHA)  # semi-transparent
        dc.SetPen(wx.Pen(grey, 2))
        if self._hover_point is not None:
            side, imxy = self.locate_mouse(self._hover_point)
            if side is not None:
                offset = self._right_offset if side == LEFT_SIDE else self._left_offset
                Lcur = self._left_points if side == LEFT_SIDE else self._right_points
                Lopp = self._right_points if side == LEFT_SIDE else self._left_points
                if len(Lopp) > len(Lcur):
                    hx, hy = np.add(Lopp[len(Lcur)], offset)
                    dc.DrawLine(hx, hy, self._hover_point[0],
                                self._hover_point[1])

        # Estimate a homography
        if self._show_homography:
            try:
                n = min(len(self._left_points), len(self._right_points))
                if n >= 4:
                    # Estimate the homography
                    H = geometry.fit_homography(self._left_points[:n],
                                                self._right_points[:n])

                    # Project the left image bounds through the homography
                    quad = [(0., 0.), (self._left_shape[0], 0.),
                            self._left_shape, (0., self._left_shape[1])]
                    Hquad = geometry.prdot(H, quad)

                    # Draw the quad
                    dc.SetPen(
                        wx.Pen(wx.Colour(0, 0, 255, HOMOGRAPHY_ALPHA), 4.))
                    for i in range(4):
                        p0 = self._right_offset + Hquad[i]
                        p1 = self._right_offset + Hquad[(i + 1) % 4]
                        dc.DrawLine(p0[0], p0[1], p1[0], p1[1])

            except np.linalg.LinAlgError:
                print('Failed to fit homography')
    def on_self_paint(self, event=None):
        dc = wx.PaintDC(self)
        dc.Clear()

        dc.DrawBitmapPoint(self._left_bitmap, self._left_offset)
        dc.DrawBitmapPoint(self._right_bitmap, self._right_offset)

        HOVER_ALPHA = 80
        LINE_ALPHA = 140
        HOMOGRAPHY_ALPHA = 160

        # Draw the correspondence arcs
        dc.SetPen(wx.Pen((255, 0, 0, LINE_ALPHA), 2))
        for i in range(min(len(self._left_points), len(self._right_points))):
            lxy = np.add(self._left_offset,  self._left_points[i])
            rxy = np.add(self._right_offset, self._right_points[i])
            dc.DrawLine(lxy[0], lxy[1], rxy[0], rxy[1])

        # Draw the points
        dc.SetPen(wx.Pen((255, 0, 0, LINE_ALPHA), 6))
        for lx,ly in self._left_points:
            dc.DrawPoint(self._left_offset[0]+lx, self._left_offset[1]+ly)
        for rx,ry in self._right_points:
            dc.DrawPoint(self._right_offset[0]+rx, self._right_offset[1]+ry)


        # Find the closest point
        if self._hover_point is not None:
            side,imxy = self.locate_mouse(self._hover_point)
            if side is not None:
                L = self._left_points if side == LEFT_SIDE else self._right_points
                hover_index,p = geometry.find_point_within_distance(imxy, L, DRAG_RADIUS)

        # Draw the hover arc
        grey = wx.Colour(0, 0, 0, HOVER_ALPHA)  # semi-transparent
        dc.SetPen(wx.Pen(grey, 2))
        if self._hover_point is not None:
            side,imxy = self.locate_mouse(self._hover_point)
            if side is not None:
                offset = self._right_offset if side == LEFT_SIDE else self._left_offset
                Lcur = self._left_points if side == LEFT_SIDE else self._right_points
                Lopp = self._right_points if side == LEFT_SIDE else self._left_points
                if len(Lopp) > len(Lcur):
                    hx,hy = np.add(Lopp[len(Lcur)], offset)
                    dc.DrawLine(hx, hy, self._hover_point[0], self._hover_point[1])

        # Estimate a homography
        if self._show_homography:
            try:
                n = min(len(self._left_points), len(self._right_points))
                if n >= 4:
                    # Estimate the homography
                    H = geometry.fit_homography(self._left_points[:n],
                                                self._right_points[:n])
                
                    # Project the left image bounds through the homography
                    quad = [(0., 0.),
                            (self._left_shape[0], 0.),
                            self._left_shape,
                            (0., self._left_shape[1])]
                    Hquad = geometry.prdot(H, quad)

                    # Draw the quad
                    dc.SetPen(wx.Pen(wx.Colour(0, 0, 255, HOMOGRAPHY_ALPHA), 4.))
                    for i in range(4):
                        p0 = self._right_offset + Hquad[i]
                        p1 = self._right_offset + Hquad[(i+1)%4]
                        dc.DrawLine(p0[0], p0[1], p1[0], p1[1])

            except np.linalg.LinAlgError:
                print 'Failed to fit homography'