Esempio n. 1
0
 def test_init(self, level=1):
     g0 = Grid([0, 1], [0, 1])
     g1 = Grid(2, 2)
     g2 = Grid([[0, 0], [1, 1]], [[0, 1], [0, 1]])
     for g in [g0, g1, g2]:
         assert_array_almost_equal(g['cols'], np.array([[0, 1], [0, 1]]))
         assert_array_almost_equal(g['rows'], np.array([[0, 0], [1, 1]]))
         assert_array_almost_equal(g['z'], np.array([[1, 1], [1, 1]]))
Esempio n. 2
0
 def test_coords_readonly(self, level=2):
     g = Grid([0], [0])
     try:
         g.coords = []
     except AttributeError:
         pass
     else:
         fail("should not be able to set coords")
Esempio n. 3
0
 def test_coords_readonly(self, level=2):
     g = Grid([0], [0])
     try:
         g.coords = []
     except AttributeError:
         pass
     else:
         fail("should not be able to set coords")
Esempio n. 4
0
 def test_coords(self, level=1):
     g = Grid([0], [0, 1, 2])
     assert_array_almost_equal(
         g.coords, np.array([[[0, 0, 1], [1, 0, 1], [2, 0, 1]]]))
     g = Grid([0, 1], [0, 1])
     assert_array_almost_equal(
         g.coords, np.array([[[0, 0, 1], [1, 0, 1]], [[0, 1, 1], [1, 1,
                                                                  1]]]))
Esempio n. 5
0
def mask_roi(rows, cols, bounds):
    """Return a mask for operating only on pixels inside the given bounds.

    Parameters
    ----------
    rows, cols : int
        Shape of the target image.
    bounds : (M, 3) array of (x, y, 1) coordinates
        Boundary coordinates.

    """
    # Sort corners clockwise.  This can be done with a single
    # swap operation, but that's a bit more work.
    mask = (bounds < 1e-14)
    bounds[mask] -= 0.5
    bounds[~mask] += 0.5

    centroid = bounds.mean(axis=0)
    diff = bounds - centroid
    angle = np.arctan2(diff[:, 1], diff[:, 0])
    bounds = bounds[np.argsort(angle)]
    bounds = np.vstack((bounds, bounds[0]))

    p = Polygon(bounds[:, 0], bounds[:, 1])
    g = Grid(rows, cols)
    return p.inside(g['cols'].flat, g['rows'].flat).reshape(rows, cols)
Esempio n. 6
0
 def test_fields(self, level=1):
     g = Grid([0], [0])
     assert_equal(g['cols'], g.cols)
Esempio n. 7
0
 def test_getitem(self, level=1):
     g = Grid([0], [0])
     assert_array_almost_equal(g['cols'], np.array([[0]]))
Esempio n. 8
0
def correspond(fA, A, fB, B, win_size=9):
    """Given coordinates of features in two images, determine
    possible correspondences using a Quantile-Quantile
    comparison.

    Parameters
    ----------
    fA : list of tuple (x,y)
        Coordinates of the features in the source image.
    A : (m,n) ndarray of type uint8
        Source image.
    fB : list of tuple (x,y)
        Coordinates of the features in the target image.
    A : (m,n) ndarray of type uint8
        Target image.

    Returns
    -------
    matches : list
        [((coord_source), (coord_target)), ...]

    """
    # Ensure uneven window size
    win_size = int(win_size)
    win_size = win_size + ((win_size + 1) % 2)

    ## Used to round feature corners, used e.g. in LPT matching
    # Mask for removing corners
    r_max = ((win_size - 1) / 2.)**2
    g = Grid(win_size, win_size)
    center = (win_size - 1) / 2.
    mask = (((g['cols'] - center)**2 + (g['rows'] - center)**2) > r_max)

    # Pre-calculate patches
    pA = {}
    angles = np.linspace(-np.pi, np.pi, 50)
    for (i, j) in fA:
        try:
            m, n, p, q = _safe_coord(i, j, A, win_size)
        except IndexError:
            pass
        else:
            patch = np.array(A[m:n, p:q], dtype=float)
            #            patch[mask] = -1 # round feature
            pA[(i, j)] = patch

    pB = {}
    for (i, j) in fB:
        try:
            m, n, p, q = _safe_coord(i, j, B, win_size)
        except IndexError:
            pass
        else:
            patch = np.array(B[m:n, p:q], dtype=float)
            #            patch[mask] = -1 # round feature
            pB[(i, j)] = patch

    count = 1
    result_d = {}

    for (i, j) in fA:
        if count % 10 == 1:
            log.debug("%s/%s" % (count, len(fA)))
        count += 1
        match_likelihood = -np.inf

        patch_A = pA.get((i, j), None)
        if patch_A is None:
            continue

        # Sort values for QQ-comparison
        patch_A = np.sort(patch_A)

        for (m, n) in fB:
            patch_B = pB.get((m, n), None)
            if patch_B is None:
                continue
            patch_B = np.sort(patch_B)

            norm = np.linalg.norm

            # A very counter-intuitive feature-matching scheme
            # that works.

            # |A - B| <= max(|A|, |B|) since all elements are positive
            order = 2
            tmp = patch_B - patch_A
            tmp = -norm(tmp, order) / max(norm(patch_B, order),
                                          norm(patch_A, order))

            if tmp > -0.5 and tmp > match_likelihood:
                match_likelihood = tmp
                result_d[(i, j)] = (m, n)

    # Get rid of features that occur twice in the mapping
    # There can be only one, after all
    reverse_d = {}
    for k, v in result_d.iteritems():
        reverse_d[v] = reverse_d.get(v, [])
        reverse_d[v].append(k)

    for k, v in reverse_d.iteritems():
        if len(v) > 1:
            for coord in v:
                del result_d[coord]

    return result_d.items()