コード例 #1
0
def kpts_matrices(kpts):
    # We are given the keypoint in invA format
    # invV = perdoch.invA
    #    V = perdoch.A
    #    Z = perdoch.E
    # invert into V
    #invV = kpts_to_invV(kpts)
    invV = ktool.get_invV_mats3x3(kpts)
    V = ktool.invert_invV_mats(invV)
    Z = ktool.get_Z_mats(V)
    return invV, V, Z
コード例 #2
0
ファイル: ellipse.py プロジェクト: Erotemic/vtool
def kpts_matrices(kpts):
    # We are given the keypoint in invA format
    # invV = perdoch.invA
    #    V = perdoch.A
    #    Z = perdoch.E
    # invert into V
    #invV = kpts_to_invV(kpts)
    invV = ktool.get_invV_mats3x3(kpts)
    V = ktool.invert_invV_mats(invV)
    Z = ktool.get_Z_mats(V)
    return invV, V, Z
コード例 #3
0
def sample_uniform(kpts, nSamples=128):
    """
    SeeAlso:
        python -m pyhesaff.tests.test_ellipse --test-in_depth_ellipse --show

    """
    nKp = len(kpts)
    # Get keypoint matrix forms
    invV_mats3x3 = ktool.get_invV_mats3x3(kpts)
    V_mats3x3 = ktool.invert_invV_mats(invV_mats3x3)
    #-------------------------------
    # Get uniform points on a circle
    circle_pts = homogenous_circle_pts(nSamples + 1)[0:-1]
    assert circle_pts.shape == (nSamples, 3)
    #-------------------------------
    # Get uneven points sample (get_uneven_point_sample)
    polygon1_list = matrix_multiply(invV_mats3x3,
                                    circle_pts.T).transpose(0, 2, 1)
    assert polygon1_list.shape == (nKp, nSamples, 3)
    # -------------------------------
    # The transformed points are not sampled uniformly... Bummer
    # We will sample points evenly across the sampled polygon
    # then we will project them onto the ellipse
    dists = np.array([circular_distance(arr) for arr in polygon1_list])
    assert dists.shape == (nKp, nSamples)
    # perimeter of the polygon
    perimeter = dists.sum(1)
    assert perimeter.shape == (nKp, )
    # Take a perfect multiple of steps along the perimeter
    multiplier = 1
    step_size = perimeter / (nSamples * multiplier)
    assert step_size.shape == (nKp, )
    # Walk along edge
    num_steps_list = []
    offset_list = []
    total_dist = np.zeros(step_size.shape)  # step_size.copy()
    dist_walked = np.zeros(step_size.shape)
    assert dist_walked.shape == (nKp, )
    assert total_dist.shape == (nKp, )
    distsT = dists.T
    assert distsT.shape == (nSamples, nKp)

    # This loops over the pt samples and performs the operation for every keypoint
    for count in range(nSamples):
        segment_len = distsT[count]
        # Find where your starting location is
        offset_list.append(total_dist - dist_walked)
        # How far can you possibly go?
        total_dist += segment_len
        # How many steps can you take?
        num_steps = (total_dist - dist_walked) // step_size
        num_steps_list.append(num_steps)
        # Log how much further youve gotten
        dist_walked += (num_steps * step_size)
    # Check for floating point errors
    # take an extra step if you need to
    num_steps_list[-1] += np.round((perimeter - dist_walked) / step_size)
    assert np.all(np.array(num_steps_list).sum(0) == nSamples)
    """
    #offset_iter1 = zip(num_steps_list, distsT, offset_list)
    #offset_list = [((step_size - offset) / dist, ((num * step_size) - offset) / dist, num)
                   #for num, dist, offset in zip(num_steps_list, distsT, offset_list)]

    #offset_iter2 = offset_list

    #cut_locs = [[
        #np.linspace(off1, off2, n, endpoint=True) for (off1, off2, n) in zip(offset1, offset2, num)]
        #for (offset1, offset2, num) in offset_iter2
    #]
    # store the percent location at each line segment where
    # the cut will be made
    """
    # HERE IS NEXT
    cut_list = []
    # This loops over the pt samples and performs the operation for every keypoint
    for num, dist, offset in zip(num_steps_list, distsT, offset_list):
        #if num == 0
        #cut_list.append([])
        #continue
        # This was a bitch to keep track of
        offset1 = (step_size - offset) / dist
        offset2 = ((num * step_size) - offset) / dist
        cut_locs = [
            np.linspace(off1, off2, n, endpoint=True)
            for (off1, off2, n) in zip(offset1, offset2, num)
        ]
        # post check for divide by 0
        cut_locs = [
            np.array([0 if np.isinf(c) else c for c in cut])
            for cut in cut_locs
        ]
        cut_list.append(cut_locs)
    cut_list = np.array(cut_list).T
    assert cut_list.shape == (nKp, nSamples)

    # =================
    # METHOD 1
    # =================
    # Linearly interpolate between points on the polygons at the places we cut
    def interpolate(pt1, pt2, percent):
        # interpolate between point1 and point2
        return ((1 - percent) * pt1) + ((percent) * pt2)

    def polygon_points(polygon_pts, dist_list):
        return np.array([
            interpolate(polygon_pts[count],
                        polygon_pts[(count + 1) % nSamples], loc)
            for count, locs in enumerate(dist_list) for loc in iter(locs)
        ])

    new_locations = np.array([
        polygon_points(polygon_pts, cuts)
        for polygon_pts, cuts in zip(polygon1_list, cut_list)
    ])
    # =================
    # =================
    # METHOD 2
    """
    #from itertools import cycle as icycle
    #from itertools import islice

    #def icycle_shift1(iterable):
        #return islice(icycle(poly_pts), 1, len(poly_pts) + 1)

    #cutptsIter_list = [zip(iter(poly_pts), icycle_shift1(poly_pts), cuts)
                       #for poly_pts, cuts in zip(polygon1_list, cut_list)]
    #new_locations = [[[((1 - cut) * pt1) + ((cut) * pt2) for cut in cuts]
                      #for (pt1, pt2, cuts) in cutPtsIter]
                     #for cutPtsIter in cutptsIter_list]
    """
    # =================

    # assert new_locations.shape == (nKp, nSamples, 3)
    # Warp new_locations to the unit circle
    #new_unit = V.dot(new_locations.T).T
    new_unit = np.array(
        [v.dot(newloc.T).T for v, newloc in zip(V_mats3x3, new_locations)])
    # normalize new_unit
    new_mag = np.sqrt((new_unit**2).sum(-1))
    new_unorm_unit = new_unit / np.dstack([new_mag] * 3)
    new_norm_unit = new_unorm_unit / np.dstack([new_unorm_unit[:, :, 2]] * 3)
    # Get angle (might not be necessary)
    #x_axis = np.array([1, 0, 0])
    #arccos_list = x_axis.dot(new_norm_unit.T)
    #uniform_theta_list = np.arccos(arccos_list)
    # Maybe this?
    # Find the angle from the center of the circle
    theta_list2 = np.arctan2(new_norm_unit[:, :, 1], new_norm_unit[:, :, 0])
    # assert uniform_theta_list.shape = (nKp, nSample)
    # Use this angle to unevenly sample the perimeter of the circle
    uneven_cicrle_pts = np.dstack(
        [np.cos(theta_list2),
         np.sin(theta_list2),
         np.ones(theta_list2.shape)])
    # The uneven circle points were sampled in such a way that when they are
    # transformeed they will be approximately uniform along the boundary of the
    # ellipse.
    uniform_ell_hpts = [
        v.dot(pts.T).T for (v, pts) in zip(invV_mats3x3, uneven_cicrle_pts)
    ]
    # Remove the homogenous coordinate and we're done
    ell_border_pts_list = [pts[:, 0:2] for pts in uniform_ell_hpts]
    return ell_border_pts_list
コード例 #4
0
def get_affine_inliers(kpts1, kpts2, fm, fs, xy_thresh_sqrd, scale_thresh_sqrd,
                       ori_thresh):
    """
    Estimates inliers deterministically using elliptical shapes

    Compute all transforms from kpts1 to kpts2 (enumerate all hypothesis)
    We transform from chip1 -> chip2
    The determinants are squared keypoint scales

    FROM PERDOCH 2009::
        H = inv(Aj).dot(Rj.T).dot(Ri).dot(Ai)
        H = inv(Aj).dot(Ai)
        The input invVs = perdoch.invA's

    CommandLine:
        python -m vtool.spatial_verification --test-get_affine_inliers

    Example:
        >>> # ENABLE_DOCTEST
        >>> from vtool.spatial_verification import *  # NOQA
        >>> import vtool.tests.dummy as dummy
        >>> import vtool.keypoint as ktool
        >>> kpts1, kpts2 = dummy.get_dummy_kpts_pair((100, 100))
        >>> fm = dummy.make_dummy_fm(len(kpts1)).astype(np.int32)
        >>> fs = np.ones(len(fm), dtype=np.float64)
        >>> xy_thresh_sqrd = ktool.KPTS_DTYPE(.009) ** 2
        >>> scale_thresh_sqrd = ktool.KPTS_DTYPE(2)
        >>> ori_thresh = ktool.KPTS_DTYPE(TAU / 4)
        >>> output = get_affine_inliers(kpts1, kpts2, fm, fs, xy_thresh_sqrd,
        >>>                             scale_thresh_sqrd, ori_thresh)
        >>> result = ut.hashstr(output)
        >>> print(result)
        89kz8nh6p+66t!+u

    Ignore::
        from vtool.spatial_verification import *  # NOQA
        import vtool.tests.dummy as dummy
        import vtool.keypoint as ktool
        kpts1, kpts2 = dummy.get_dummy_kpts_pair((100, 100))
        a = kpts1[fm.T[0]]
        b = kpts1.take(fm.T[0])

        align = fm.dtype.itemsize * fm.shape[1]
        align2 = [fm.dtype.itemsize, fm.dtype.itemsize]
        viewtype1 = np.dtype(np.void, align)
        viewtype2 = np.dtype(np.int32, align2)
        c = np.ascontiguousarray(fm).view(viewtype1)
        fm_view = np.ascontiguousarray(fm).view(viewtype1)
        qfx = fm.view(np.dtype(np.int32 np.int32.itemsize))
        dfx = fm.view(np.dtype(np.int32, np.int32.itemsize))
        d = np.ascontiguousarray(c).view(viewtype2)

        fm.view(np.dtype(np.void, align))
        np.ascontiguousarray(fm).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1])))
    """
    #http://ipython-books.github.io/featured-01/
    kpts1_m = kpts1.take(fm.T[0], axis=0)
    kpts2_m = kpts2.take(fm.T[1], axis=0)

    # Get keypoints to project in matrix form
    #invVR2s_m = ktool.get_invV_mats(kpts2_m, with_trans=True, with_ori=True)
    #invVR1s_m = ktool.get_invV_mats(kpts1_m, with_trans=True, with_ori=True)
    invVR2s_m = ktool.get_invVR_mats3x3(kpts2_m)
    invVR1s_m = ktool.get_invVR_mats3x3(kpts1_m)
    RV1s_m = ktool.invert_invV_mats(invVR1s_m)  # 539 us
    # BUILD ALL HYPOTHESIS TRANSFORMS: The transform from kp1 to kp2 is:
    Aff_mats = matrix_multiply(invVR2s_m, RV1s_m)
    # Get components to test projects against
    xy2_m = ktool.get_xys(kpts2_m)
    det2_m = ktool.get_sqrd_scales(kpts2_m)
    ori2_m = ktool.get_oris(kpts2_m)
    # SLOWER EQUIVALENT
    # RV1s_m    = ktool.get_V_mats(kpts1_m, with_trans=True, with_ori=True)  # 5.2 ms
    # xy2_m  = ktool.get_invVR_mats_xys(invVR2s_m)
    # ori2_m = ktool.get_invVR_mats_oris(invVR2s_m)
    # assert np.all(ktool.get_oris(kpts2_m) == ktool.get_invVR_mats_oris(invVR2s_m))
    # assert np.all(ktool.get_xys(kpts2_m) == ktool.get_invVR_mats_xys(invVR2s_m))

    # The previous versions of this function were all roughly comparable.
    # The for loop one was the slowest. I'm deciding to go with the one
    # where there is no internal function definition. It was moderately faster,
    # and it gives us access to profile that function
    inliers_and_errors_list = [
        _test_hypothesis_inliers(Aff, invVR1s_m, xy2_m, det2_m, ori2_m,
                                 xy_thresh_sqrd, scale_thresh_sqrd, ori_thresh)
        for Aff in Aff_mats
    ]
    aff_inliers_list = [tup[0] for tup in inliers_and_errors_list]
    aff_errors_list = [tup[1] for tup in inliers_and_errors_list]
    return aff_inliers_list, aff_errors_list, Aff_mats
コード例 #5
0
def get_affine_inliers(kpts1, kpts2, fm, fs,
                        xy_thresh_sqrd,
                        scale_thresh_sqrd,
                        ori_thresh):
    """
    Estimates inliers deterministically using elliptical shapes

    Compute all transforms from kpts1 to kpts2 (enumerate all hypothesis)
    We transform from chip1 -> chip2
    The determinants are squared keypoint scales

    FROM PERDOCH 2009::
        H = inv(Aj).dot(Rj.T).dot(Ri).dot(Ai)
        H = inv(Aj).dot(Ai)
        The input invVs = perdoch.invA's

    CommandLine:
        python -m vtool.spatial_verification --test-get_affine_inliers

    Example:
        >>> # ENABLE_DOCTEST
        >>> from vtool.spatial_verification import *  # NOQA
        >>> import vtool.tests.dummy as dummy
        >>> import vtool.keypoint as ktool
        >>> kpts1, kpts2 = dummy.get_dummy_kpts_pair((100, 100))
        >>> fm = dummy.make_dummy_fm(len(kpts1)).astype(np.int32)
        >>> fs = np.ones(len(fm), dtype=np.float64)
        >>> xy_thresh_sqrd = ktool.KPTS_DTYPE(.009) ** 2
        >>> scale_thresh_sqrd = ktool.KPTS_DTYPE(2)
        >>> ori_thresh = ktool.KPTS_DTYPE(TAU / 4)
        >>> output = get_affine_inliers(kpts1, kpts2, fm, fs, xy_thresh_sqrd,
        >>>                             scale_thresh_sqrd, ori_thresh)
        >>> result = ut.hashstr(output)
        >>> print(result)
        89kz8nh6p+66t!+u

    Ignore::
        from vtool.spatial_verification import *  # NOQA
        import vtool.tests.dummy as dummy
        import vtool.keypoint as ktool
        kpts1, kpts2 = dummy.get_dummy_kpts_pair((100, 100))
        a = kpts1[fm.T[0]]
        b = kpts1.take(fm.T[0])

        align = fm.dtype.itemsize * fm.shape[1]
        align2 = [fm.dtype.itemsize, fm.dtype.itemsize]
        viewtype1 = np.dtype(np.void, align)
        viewtype2 = np.dtype(np.int32, align2)
        c = np.ascontiguousarray(fm).view(viewtype1)
        fm_view = np.ascontiguousarray(fm).view(viewtype1)
        qfx = fm.view(np.dtype(np.int32 np.int32.itemsize))
        dfx = fm.view(np.dtype(np.int32, np.int32.itemsize))
        d = np.ascontiguousarray(c).view(viewtype2)

        fm.view(np.dtype(np.void, align))
        np.ascontiguousarray(fm).view(np.dtype((np.void, Z.dtype.itemsize * Z.shape[1])))
    """
    #http://ipython-books.github.io/featured-01/
    kpts1_m = kpts1.take(fm.T[0], axis=0)
    kpts2_m = kpts2.take(fm.T[1], axis=0)

    # Get keypoints to project in matrix form
    #invVR2s_m = ktool.get_invV_mats(kpts2_m, with_trans=True, with_ori=True)
    #invVR1s_m = ktool.get_invV_mats(kpts1_m, with_trans=True, with_ori=True)
    invVR2s_m = ktool.get_invVR_mats3x3(kpts2_m)
    invVR1s_m = ktool.get_invVR_mats3x3(kpts1_m)
    RV1s_m    = ktool.invert_invV_mats(invVR1s_m)  # 539 us
    # BUILD ALL HYPOTHESIS TRANSFORMS: The transform from kp1 to kp2 is:
    Aff_mats = matrix_multiply(invVR2s_m, RV1s_m)
    # Get components to test projects against
    xy2_m  = ktool.get_xys(kpts2_m)
    det2_m = ktool.get_sqrd_scales(kpts2_m)
    ori2_m = ktool.get_oris(kpts2_m)
    # SLOWER EQUIVALENT
    # RV1s_m    = ktool.get_V_mats(kpts1_m, with_trans=True, with_ori=True)  # 5.2 ms
    # xy2_m  = ktool.get_invVR_mats_xys(invVR2s_m)
    # ori2_m = ktool.get_invVR_mats_oris(invVR2s_m)
    # assert np.all(ktool.get_oris(kpts2_m) == ktool.get_invVR_mats_oris(invVR2s_m))
    # assert np.all(ktool.get_xys(kpts2_m) == ktool.get_invVR_mats_xys(invVR2s_m))

    # The previous versions of this function were all roughly comparable.
    # The for loop one was the slowest. I'm deciding to go with the one
    # where there is no internal function definition. It was moderately faster,
    # and it gives us access to profile that function
    inliers_and_errors_list = [_test_hypothesis_inliers(Aff, invVR1s_m, xy2_m,
                                                        det2_m, ori2_m,
                                                        xy_thresh_sqrd,
                                                        scale_thresh_sqrd,
                                                        ori_thresh)
                               for Aff in Aff_mats]
    aff_inliers_list = [tup[0] for tup in inliers_and_errors_list]
    aff_errors_list  = [tup[1] for tup in inliers_and_errors_list]
    return aff_inliers_list, aff_errors_list, Aff_mats
コード例 #6
0
ファイル: ellipse.py プロジェクト: Erotemic/vtool
def sample_uniform(kpts, nSamples=128):
    """
    SeeAlso:
        python -m pyhesaff.tests.test_ellipse --test-in_depth_ellipse --show

    """
    nKp = len(kpts)
    # Get keypoint matrix forms
    invV_mats3x3 = ktool.get_invV_mats3x3(kpts)
    V_mats3x3 = ktool.invert_invV_mats(invV_mats3x3)
    #-------------------------------
    # Get uniform points on a circle
    circle_pts = homogenous_circle_pts(nSamples + 1)[0:-1]
    assert circle_pts.shape == (nSamples, 3)
    #-------------------------------
    # Get uneven points sample (get_uneven_point_sample)
    polygon1_list = matrix_multiply(invV_mats3x3, circle_pts.T).transpose(0, 2, 1)
    assert polygon1_list.shape == (nKp, nSamples, 3)
    # -------------------------------
    # The transformed points are not sampled uniformly... Bummer
    # We will sample points evenly across the sampled polygon
    # then we will project them onto the ellipse
    dists = np.array([circular_distance(arr) for arr in polygon1_list])
    assert dists.shape == (nKp, nSamples)
    # perimeter of the polygon
    perimeter = dists.sum(1)
    assert perimeter.shape == (nKp,)
    # Take a perfect multiple of steps along the perimeter
    multiplier = 1
    step_size = perimeter / (nSamples * multiplier)
    assert step_size.shape == (nKp,)
    # Walk along edge
    num_steps_list = []
    offset_list = []
    total_dist = np.zeros(step_size.shape)  # step_size.copy()
    dist_walked = np.zeros(step_size.shape)
    assert dist_walked.shape == (nKp,)
    assert total_dist.shape == (nKp,)
    distsT = dists.T
    assert distsT.shape == (nSamples, nKp)

    # This loops over the pt samples and performs the operation for every keypoint
    for count in range(nSamples):
        segment_len = distsT[count]
        # Find where your starting location is
        offset_list.append(total_dist - dist_walked)
        # How far can you possibly go?
        total_dist += segment_len
        # How many steps can you take?
        num_steps = (total_dist - dist_walked) // step_size
        num_steps_list.append(num_steps)
        # Log how much further youve gotten
        dist_walked += (num_steps * step_size)
    # Check for floating point errors
    # take an extra step if you need to
    num_steps_list[-1] += np.round((perimeter - dist_walked) / step_size)
    assert np.all(np.array(num_steps_list).sum(0) == nSamples)

    """
    #offset_iter1 = zip(num_steps_list, distsT, offset_list)
    #offset_list = [((step_size - offset) / dist, ((num * step_size) - offset) / dist, num)
                   #for num, dist, offset in zip(num_steps_list, distsT, offset_list)]

    #offset_iter2 = offset_list

    #cut_locs = [[
        #np.linspace(off1, off2, n, endpoint=True) for (off1, off2, n) in zip(offset1, offset2, num)]
        #for (offset1, offset2, num) in offset_iter2
    #]
    # store the percent location at each line segment where
    # the cut will be made
    """
    # HERE IS NEXT
    cut_list = []
    # This loops over the pt samples and performs the operation for every keypoint
    for num, dist, offset in zip(num_steps_list, distsT, offset_list):
        #if num == 0
            #cut_list.append([])
            #continue
        # This was a bitch to keep track of
        offset1 = (step_size - offset) / dist
        offset2 = ((num * step_size) - offset) / dist
        cut_locs = [np.linspace(off1, off2, n, endpoint=True) for (off1, off2, n) in zip(offset1, offset2, num)]
        # post check for divide by 0
        cut_locs = [np.array([0 if np.isinf(c) else c for c in cut]) for cut in cut_locs]
        cut_list.append(cut_locs)
    cut_list = np.array(cut_list).T
    assert cut_list.shape == (nKp, nSamples)

    # =================
    # METHOD 1
    # =================
    # Linearly interpolate between points on the polygons at the places we cut
    def interpolate(pt1, pt2, percent):
        # interpolate between point1 and point2
        return ((1 - percent) * pt1) + ((percent) * pt2)

    def polygon_points(polygon_pts, dist_list):
        return np.array([interpolate(polygon_pts[count], polygon_pts[(count + 1) % nSamples], loc)
                         for count, locs in enumerate(dist_list)
                         for loc in iter(locs)])

    new_locations = np.array([polygon_points(polygon_pts, cuts) for polygon_pts,
                              cuts in zip(polygon1_list, cut_list)])
    # =================
    # =================
    # METHOD 2
    """
    #from itertools import cycle as icycle
    #from itertools import islice

    #def icycle_shift1(iterable):
        #return islice(icycle(poly_pts), 1, len(poly_pts) + 1)

    #cutptsIter_list = [zip(iter(poly_pts), icycle_shift1(poly_pts), cuts)
                       #for poly_pts, cuts in zip(polygon1_list, cut_list)]
    #new_locations = [[[((1 - cut) * pt1) + ((cut) * pt2) for cut in cuts]
                      #for (pt1, pt2, cuts) in cutPtsIter]
                     #for cutPtsIter in cutptsIter_list]
    """
    # =================

    # assert new_locations.shape == (nKp, nSamples, 3)
    # Warp new_locations to the unit circle
    #new_unit = V.dot(new_locations.T).T
    new_unit = np.array([v.dot(newloc.T).T for v, newloc in zip(V_mats3x3, new_locations)])
    # normalize new_unit
    new_mag = np.sqrt((new_unit ** 2).sum(-1))
    new_unorm_unit = new_unit / np.dstack([new_mag] * 3)
    new_norm_unit = new_unorm_unit / np.dstack([new_unorm_unit[:, :, 2]] * 3)
    # Get angle (might not be necessary)
    #x_axis = np.array([1, 0, 0])
    #arccos_list = x_axis.dot(new_norm_unit.T)
    #uniform_theta_list = np.arccos(arccos_list)
    # Maybe this?
    # Find the angle from the center of the circle
    theta_list2 = np.arctan2(new_norm_unit[:, :, 1], new_norm_unit[:, :, 0])
    # assert uniform_theta_list.shape = (nKp, nSample)
    # Use this angle to unevenly sample the perimeter of the circle
    uneven_cicrle_pts = np.dstack([np.cos(theta_list2), np.sin(theta_list2), np.ones(theta_list2.shape)])
    # The uneven circle points were sampled in such a way that when they are
    # transformeed they will be approximately uniform along the boundary of the
    # ellipse.
    uniform_ell_hpts = [v.dot(pts.T).T for (v, pts) in zip(invV_mats3x3, uneven_cicrle_pts)]
    # Remove the homogenous coordinate and we're done
    ell_border_pts_list = [pts[:, 0:2] for pts in uniform_ell_hpts]
    return ell_border_pts_list