Exemplo n.º 1
0
 def test_matrix(self, level=1):
     x = np.arange(9).reshape((3, 3)) + 1
     theta = -np.pi / 2
     M = np.array([[np.cos(theta), -np.sin(theta), 0],
                   [np.sin(theta), np.cos(theta), 2], [0, 0, 1]])
     x90 = transform.matrix(x, M, order=1)
     assert_array_almost_equal(x90, np.rot90(x))
Exemplo n.º 2
0
 def test_matrix(self,level=1):
     x = np.arange(9).reshape((3,3)) + 1
     theta = -np.pi/2
     M = np.array([[np.cos(theta), -np.sin(theta), 0],
                   [np.sin(theta),  np.cos(theta), 2],
                   [0,              0,             1]])
     x90 = transform.matrix(x, M, order=1)
     assert_array_almost_equal(x90, np.rot90(x))
Exemplo n.º 3
0
def with_transform(images, matrices, weights=None, order=1,
                   oshape=None, save_tiff=False,
                   method='interpolate'):
    """Stack images after performing coordinate transformations.

    Parameters
    ----------
    images : list of ndarray
        Images to be stacked.
    matrices : list of (3,3) ndarray
        Coordinate transformation matrices.
    weights : list of float
        Weight of each input image.  By default, all images are
        weighted equally.  The merging algorithm takes into account
        whether images overlap.
    order : int
        Order of the interpolant used by the scaling algorithm.  Linear,
        by default.
    oshape : tuple of int
        Output shape.  If not specified, the output shape is auto determined to
        include all images.
    save_tiff : bool
        Whether to save copies of the warped images.  False by default.
    method : {'interpolate', 'polygon'}
        Use standard interpolation (default) or polygon interpolation.
        Note: Polygon interpolation is currently disabled.

    Notes
    -----
    For each image, a 3x3 coordinate transformation matrix, ``A``,
    must be given. Each coordinate, ``c = [x,y,1]^T``, in the source
    image is then translated to its position in the destination image,
    ``d = A*c``.

    After warping the images, they are combined according to the given
    weights.  Note that the overlap of frames is taken into account.
    For example, in areas where only one image occurs, the pixels of
    that image will carry a weight of one, whereas in other areas it
    may be less, depending on the overlap of other images.

    """
    nr_images = len(images)
    if weights is None:
        weights = np.ones(nr_images, dtype=sc.ftype) / nr_images

    if not (len(images) == len(matrices) == len(weights)):
        raise ValueError("Number of images, transformation matrices and "
                         "weights should match.")

    images = [np.atleast_2d(i) for i in images]
    affine_matrices = [np.atleast_2d(m) for m in matrices]

    reshape = (oshape is None)
    if reshape:
        all_tf_cnrs = np.empty((0,2))
        for img, tf_matrix in zip(images, matrices):
            rows, cols = img.shape[:2]
            tf_cnrs = _tf_corners(rows, cols, tf_matrix)
            all_tf_cnrs = np.vstack((all_tf_cnrs, tf_cnrs))

        # Calculate bounding box [(x0,y0),(x1,y1)]
        bbox_top_left = np.floor(all_tf_cnrs.min(axis=0))
        bbox_bottom_right = np.ceil(all_tf_cnrs.max(axis=0))

        oshape = np.array(images[0].shape)
        oshape[:2][::-1] = np.absolute(bbox_bottom_right -
                                       bbox_top_left).astype(int) + 1

    sources = []
    boundaries = []
    for n, (img, tf_matrix, weight) in \
            enumerate(zip(images, affine_matrices, weights)):
        if reshape:
            tf_matrix = tf_matrix.copy()
            tf_matrix[:2,2] -= bbox_top_left

        boundaries.append(_tf_corners(img.shape[0] + 1,
                                      img.shape[1] + 1, tf_matrix))
#        if method == 'polygon':
#            sources.append(interp_transf_polygon(img, np.linalg.inv(tf_matrix),
#                                                 oshape))
#        else:
        sources.append(transform.matrix(img, tf_matrix,
                                        output_shape=oshape, order=order,
                                        mode='reflect'))

        log.info('Transformed image %d' % n)

    if save_tiff:
        from scipy.misc import imsave
        for n, (s, bounds) in enumerate(zip(sources, boundaries)):
            # Convert to 4-channel RGBA
            tmp = np.empty(np.append(s.shape[:2], 4), dtype=s.dtype)
            if s.ndim == 3:
                print tmp.shape, s.shape
                tmp[..., :3] = s[..., :3]

                # Keep red layer for use as mask
                s = s[..., 0]
            else:
                # Fill R, G, and B
                tmp.T.swapaxes(1, 2)[:] = s

            tmp[..., 3] = 0

            mask = mask_roi(s.shape[0], s.shape[1], bounds)

            # Set the alpha mask
            t = tmp[...,3]
            t.fill(255)
            t[~mask] = 0

            imsave('stack_%d.tiff' % n, tmp)

    out = np.zeros(oshape, dtype=sc.ftype)
    total_weights = np.zeros(oshape, dtype=float)
    for (s, bounds), w in zip(zip(sources, boundaries), weights):
        mask = mask_roi(s.shape[0], s.shape[1], bounds)
        out[mask] += (w * s)[mask]
        total_weights[mask] += w

    mask = (total_weights != 0)
    out[mask] = out[mask] / total_weights[mask]

    return out
Exemplo n.º 4
0
def with_transform(images,
                   matrices,
                   weights=None,
                   order=1,
                   oshape=None,
                   save_tiff=False,
                   method='interpolate'):
    """Stack images after performing coordinate transformations.

    Parameters
    ----------
    images : list of ndarray
        Images to be stacked.
    matrices : list of (3,3) ndarray
        Coordinate transformation matrices.
    weights : list of float
        Weight of each input image.  By default, all images are
        weighted equally.  The merging algorithm takes into account
        whether images overlap.
    order : int
        Order of the interpolant used by the scaling algorithm.  Linear,
        by default.
    oshape : tuple of int
        Output shape.  If not specified, the output shape is auto determined to
        include all images.
    save_tiff : bool
        Whether to save copies of the warped images.  False by default.
    method : {'interpolate', 'polygon'}
        Use standard interpolation (default) or polygon interpolation.
        Note: Polygon interpolation is currently disabled.

    Notes
    -----
    For each image, a 3x3 coordinate transformation matrix, ``A``,
    must be given. Each coordinate, ``c = [x,y,1]^T``, in the source
    image is then translated to its position in the destination image,
    ``d = A*c``.

    After warping the images, they are combined according to the given
    weights.  Note that the overlap of frames is taken into account.
    For example, in areas where only one image occurs, the pixels of
    that image will carry a weight of one, whereas in other areas it
    may be less, depending on the overlap of other images.

    """
    nr_images = len(images)
    if weights is None:
        weights = np.ones(nr_images, dtype=sc.ftype) / nr_images

    if not (len(images) == len(matrices) == len(weights)):
        raise ValueError("Number of images, transformation matrices and "
                         "weights should match.")

    images = [np.atleast_2d(i) for i in images]
    affine_matrices = [np.atleast_2d(m) for m in matrices]

    reshape = (oshape is None)
    if reshape:
        all_tf_cnrs = np.empty((0, 2))
        for img, tf_matrix in zip(images, matrices):
            rows, cols = img.shape[:2]
            tf_cnrs = _tf_corners(rows, cols, tf_matrix)
            all_tf_cnrs = np.vstack((all_tf_cnrs, tf_cnrs))

        # Calculate bounding box [(x0,y0),(x1,y1)]
        bbox_top_left = np.floor(all_tf_cnrs.min(axis=0))
        bbox_bottom_right = np.ceil(all_tf_cnrs.max(axis=0))

        oshape = np.array(images[0].shape)
        oshape[:2][::-1] = np.absolute(bbox_bottom_right -
                                       bbox_top_left).astype(int) + 1

    sources = []
    boundaries = []
    for n, (img, tf_matrix, weight) in \
            enumerate(zip(images, affine_matrices, weights)):
        if reshape:
            tf_matrix = tf_matrix.copy()
            tf_matrix[:2, 2] -= bbox_top_left

        boundaries.append(
            _tf_corners(img.shape[0] + 1, img.shape[1] + 1, tf_matrix))
        #        if method == 'polygon':
        #            sources.append(interp_transf_polygon(img, np.linalg.inv(tf_matrix),
        #                                                 oshape))
        #        else:
        sources.append(
            transform.matrix(img,
                             tf_matrix,
                             output_shape=oshape,
                             order=order,
                             mode='reflect'))

        log.info('Transformed image %d' % n)

    if save_tiff:
        from scipy.misc import imsave
        for n, (s, bounds) in enumerate(zip(sources, boundaries)):
            # Convert to 4-channel RGBA
            tmp = np.empty(np.append(s.shape[:2], 4), dtype=s.dtype)
            if s.ndim == 3:
                print tmp.shape, s.shape
                tmp[..., :3] = s[..., :3]

                # Keep red layer for use as mask
                s = s[..., 0]
            else:
                # Fill R, G, and B
                tmp.T.swapaxes(1, 2)[:] = s

            tmp[..., 3] = 0

            mask = mask_roi(s.shape[0], s.shape[1], bounds)

            # Set the alpha mask
            t = tmp[..., 3]
            t.fill(255)
            t[~mask] = 0

            imsave('stack_%d.tiff' % n, tmp)

    out = np.zeros(oshape, dtype=sc.ftype)
    total_weights = np.zeros(oshape, dtype=float)
    for (s, bounds), w in zip(zip(sources, boundaries), weights):
        mask = mask_roi(s.shape[0], s.shape[1], bounds)
        out[mask] += (w * s)[mask]
        total_weights[mask] += w

    mask = (total_weights != 0)
    out[mask] = out[mask] / total_weights[mask]

    return out