Beispiel #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
Beispiel #2
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
Beispiel #3
0
def check_kpts_in_bounds(kpts_, width, height):
    # Test to make sure the extents of the keypoints are in bounds
    unit_bbox = np.array([(-1, -1, 1), (-1, 1, 1), (1, -1, 1), (1, 1, 1)]).T
    #invV = kpts_to_invV(kpts_)
    invV = ktool.get_invV_mats3x3(kpts_)
    bbox_pts = [v.dot(unit_bbox)[0:2] for v in invV]
    maxx = np.array([pts[0].max() for pts in bbox_pts]) < width
    minx = np.array([pts[0].min() for pts in bbox_pts]) > 0
    maxy = np.array([pts[1].max() for pts in bbox_pts]) < height
    miny = np.array([pts[1].min() for pts in bbox_pts]) > 0
    isvalid = np.array(maxx * minx * maxy * miny, dtype=np.bool)
    return isvalid
Beispiel #4
0
def check_kpts_in_bounds(kpts_, width, height):
    # Test to make sure the extents of the keypoints are in bounds
    unit_bbox = np.array([(-1, -1, 1),
                          (-1,  1, 1),
                          ( 1, -1, 1),
                          ( 1,  1, 1)]).T
    #invV = kpts_to_invV(kpts_)
    invV = ktool.get_invV_mats3x3(kpts_)
    bbox_pts = [v.dot(unit_bbox)[0:2] for v in invV]
    maxx = np.array([pts[0].max() for pts in bbox_pts]) < width
    minx = np.array([pts[0].min() for pts in bbox_pts]) > 0
    maxy = np.array([pts[1].max() for pts in bbox_pts]) < height
    miny = np.array([pts[1].min() for pts in bbox_pts]) > 0
    isvalid = np.array(maxx * minx * maxy * miny, dtype=np.bool)
    return isvalid
Beispiel #5
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
Beispiel #6
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