Example #1
0
def interpolate(h, hnext, filter):
  """ interpolate h into hnext, this needs a lot of memory(full mesh of the
  lower level) """
  # round down
  exbot = (hnext['Offset'] * h['Nmesh']) // hnext['Nmesh']
  # round up
  extop = ((hnext['Offset'] + hnext['Size']) * h['Nmesh'] + h['Nmesh'] - 1)// hnext['Nmesh']

  print h['Nmesh'], 'box', exbot, extop

  overlay = joinchunks(h, exbot, extop)
  src = overlay.reshape(*(extop-exbot))
  if filter >= 2:
    src['delta'] = spline_filter(src['delta'], order=filter)
    for d in range(3):
      src['disp'][:, d] = spline_filter(src['disp'][:, d], order=filter)

  for fn in list(yieldfilename(hnext, lookfor='delta1')):
    # read in the current level displacement
    chunk = readchunk(hnext, fn, None, None, extra='1')
    ipos = chunk['ipos']
    ipos = 1.0 * ipos * h['Nmesh'] / hnext['Nmesh'] - exbot
    chunk['delta'] += map_coordinates(src['delta'], ipos.T, order=filter,
            prefilter=False)
    for d in range(3):
      chunk['disp'][:, d] += map_coordinates(src['disp'][..., d], ipos.T,
              order=filter, prefilter=False)
    # write to the full displacement
    writechunk(hnext, fn, chunk)
Example #2
0
    def xy2lonlat(self, x, y):
        """Calculate x,y in own projection from given lon,lat (scalars/arrays).
        """
        if self.projected is True:
            if self.proj.is_latlong():
                return x, y
            else:
                if 'ob_tran' in self.proj4:
                    logging.info('NB: Converting degrees to radians ' +
                                 'due to ob_tran srs')
                    x = np.radians(np.array(x))
                    y = np.radians(np.array(y))
                return self.proj(x, y, inverse=True)
        else:
            np.seterr(invalid='ignore')  # Disable warnings for nan-values
            y = np.atleast_1d(np.array(y))
            x = np.atleast_1d(np.array(x))

            # NB: mask coordinates outside domain
            x[x < self.xmin] = np.nan
            x[x > self.xmax] = np.nan
            y[y < self.ymin] = np.nan
            y[y < self.ymin] = np.nan

            lon = map_coordinates(self.lon, [y, x], order=1,
                                  cval=np.nan, mode='nearest')
            lat = map_coordinates(self.lat, [y, x], order=1,
                                  cval=np.nan, mode='nearest')
            return (lon, lat)
def test_map_coordinates_dts():
    # check that ndimage accepts different data types for interpolation
    data = np.array([[4, 1, 3, 2],
                     [7, 6, 8, 5],
                     [3, 5, 3, 6]])
    shifted_data = np.array([[0, 0, 0, 0],
                             [0, 4, 1, 3],
                             [0, 7, 6, 8]])
    idx = np.indices(data.shape)
    dts = (np.uint8, np.uint16, np.uint32, np.uint64,
           np.int8, np.int16, np.int32, np.int64,
           np.intp, np.uintp, np.float32, np.float64)
    for order in range(0, 6):
        for data_dt in dts:
            these_data = data.astype(data_dt)
            for coord_dt in dts:
                # affine mapping
                mat = np.eye(2, dtype=coord_dt)
                off = np.zeros((2,), dtype=coord_dt)
                out = ndimage.affine_transform(these_data, mat, off)
                assert_array_almost_equal(these_data, out)
                # map coordinates
                coords_m1 = idx.astype(coord_dt) - 1
                coords_p10 = idx.astype(coord_dt) + 10
                out = ndimage.map_coordinates(these_data, coords_m1, order=order)
                assert_array_almost_equal(out, shifted_data)
                # check constant fill works
                out = ndimage.map_coordinates(these_data, coords_p10, order=order)
                assert_array_almost_equal(out, np.zeros((3,4)))
            # check shift and zoom
            out = ndimage.shift(these_data, 1)
            assert_array_almost_equal(out, shifted_data)
            out = ndimage.zoom(these_data, 1)
            assert_array_almost_equal(these_data, out)
Example #4
0
def eval_volume_at_3d_coordinates(volume, coords):
    """ Evaluates the volume data at the given coordinates using trilinear interpolation.

    Parameters
    ----------
    volume : 3D array or 4D array
        Data volume.
    coords : ndarray of shape (N, 3)
        3D coordinates where to evaluate the volume data.

    Returns
    -------
    output : 2D array
        Values from volume.
    """

    if volume.ndim <= 2 or volume.ndim >= 5:
        raise ValueError("Volume must be 3D or 4D!")

    if volume.ndim == 3:
        return map_coordinates(volume, coords.T, order=1, mode="nearest")

    if volume.ndim == 4:
        values_4d = []
        for i in range(volume.shape[-1]):
            values_tmp = map_coordinates(volume[..., i],
                                         coords.T, order=1, mode="nearest")
            values_4d.append(values_tmp)
        return np.ascontiguousarray(np.array(values_4d).T)
Example #5
0
    def __call__( self, X, out=None ):
        """ query_values = Intergrid(...) ( query_points npt x dim )
"""
        X = np.asanyarray(X)
        assert X.shape[-1] == self.dim, ("the query array must have %d columns, "
                "but its shape is %s" % (self.dim, X.shape) )
        Xdim = X.ndim
        if Xdim == 1:
            X = np.asarray([X]) # in a single point -> out scalar
        if self.copy:
            X = X.copy()
        assert X.ndim == 2, X.shape
        npt = X.shape[0]
        if out is None:
            out = np.empty( npt, dtype=self.griddata.dtype )
        t0 = time()
        self._map_to_uniform_grid( X ) # X inplace
#...............................................................................
        map_coordinates( self.griddata, X.T,
            order=self.order, prefilter=self.prefilter,
            mode="nearest", # outside -> edge
                # test: mode="constant", cval=np.NaN,
            output=out )
        if self.verbose:
            print "Intergrid: %.3g msec %d points in a %s grid %d maps order %d" % (
                (time() - t0) * 1000, npt, self.griddata.shape, self.nmap, self.order )
        return out if Xdim == 2 else out[0]
Example #6
0
    def resample(self, source, deformation, warped):
        """
        Resample the source image in the space of target.

        Parameters:
        :param source: The source image.
        :param deformation: The deformation field
        :param warped: Warped image. Should be allocated in the space of target
        and must have the same number of time points as the source image.
        """

        assert source.time_points == warped.time_points
        # Matrix to go from world to voxel space
        ijk_2_voxel = source.mm_2_voxel
        vol_ext = warped.vol_ext

        def_data = [deformation.data[..., i].reshape(vol_ext, order='F')
                    for i in range(deformation.data.shape[-1])]

        # Create the sampling grid in which the source image will be evaluated.
        def_data = [ijk_2_voxel[i][3] + sum(ijk_2_voxel[i][k] * def_data[k]
                    for k in range(len(def_data)))
                    for i in range(len(vol_ext))]

        if source.time_points == 1:
            ndimage.map_coordinates(source.data, def_data,
                                    warped.data, order=self.order,
                                    prefilter=self.prefilter)
        else:
            for i in range(source.time_points):
                ndimage.map_coordinates(source.data[i], def_data,
                                        warped.data[i], order=self.order,
                                        prefilter=self.prefilter)
def radiance(ref,cosb,t_setx,height,r_setx,sang):
    if isinstance(t_setx,(int,float)): ttmp=[t_setx/dtau]
    else: ttmp=t_setx/dtau
    if isinstance(height,(int,float)): htmp=[height/dheight]
    else: htmp=height/dheight
    if isinstance(sang,(int,float)): stmp=[sang-smin]
    else: stmp=sang-smin
    path=ndimage.map_coordinates(path_rad,[ttmp,htmp,stmp])
    back=ndimage.map_coordinates(back_rad,[ttmp,htmp,stmp])
    pixel=ndimage.map_coordinates(pixel_rad,[ttmp,htmp,stmp])
    dir=ndimage.map_coordinates(dir_irad,[ttmp,htmp,stmp])
    sky=ndimage.map_coordinates(sky_irad,[ttmp,htmp,stmp])
    env=ndimage.map_coordinates(env_irad,[ttmp,htmp,stmp])
    sph=ndimage.map_coordinates(sph_alb,[ttmp,htmp,stmp])
    rayl=ndimage.map_coordinates(tau_rayl,[ttmp,htmp,stmp])
    aero=ndimage.map_coordinates(tau_aero,[ttmp,htmp,stmp])
    minor=ndimage.map_coordinates(tau_minor,[ttmp,htmp,stmp])
    dir=dir*cosb/cosb0
    #print dir
    back=back*(1-r_set0*sph)*r_setx/(1-r_setx*sph)/r_set0
    #print back
    env=env*(1-r_set0*sph)*r_setx/(1-r_setx*sph)/r_set0
    odep=rayl+aero+minor
    S=np.cos(np.pi*sang/180)
    rad=path+back+ref*(dir+sky+env)/np.exp(odep/S)/np.pi
    return rad
Example #8
0
    def compose(self, left, right, result):
        """
        Compose deformations.
        Parameters:
        -----------
        :param left: Outer field.
        :param right: Inner field.
        :param result: Resulting field after composition.
        Must be valid and allocated.

        Order of composition: left(right(x))
        """
        ijk_2_voxel = right.mm_2_voxel
        vol_ext = right.vol_ext[:right.data.shape[-1]]
        right_data = [right.data[..., i].reshape(vol_ext, order='F')
                      for i in range(right.data.shape[-1])]

        right_data = [ijk_2_voxel[i][3] + sum(ijk_2_voxel[i][k] * right_data[k]
                      for k in range(len(right_data)))
                      for i in range(len(vol_ext))]

        data = np.squeeze(result.data)
        for i in range(data.shape[-1]):
            ndimage.map_coordinates(np.squeeze(left.data[..., i]),
                                    right_data, data[..., i], mode='reflect',
                                    order=self.order, prefilter=False)
Example #9
0
def smooth_with_spline(img, nx, ny, order=3):
    """Smooth an image with a spline. It returns the fitted spline.

    arguments:
        img - Two-dimensional image.  If img is complex, abs(img) is calculated.
        nx - number of control points in x (columns).
        ny - number control points in y (rows).
        order - order of splines. Defaults to 3.

    returns:
        spline - The fit of the image with the same dimension as img.
    """
    from scipy.ndimage import map_coordinates
    assert img.ndim == 2, "image must be two dimensional"
    assert (type(nx), type(ny)) == (int,int), "nx and ny must be int"
    assert order in range(0,6), "Spline interpolation order must be betwen 0-5."
    order = int(order)
    j = complex(0,1)
    (ys, xs) = img.shape

    # reduce image down to (ny, nx) shape
    new_idx = np.mgrid[0:ys-1:ny*j, 0:xs-1:nx*j]

    # take absolute value if complex. map_coordinates doen't work
    # for some reason, map_coordinates crashes even if np.iscomplex().any() is false.
    img = np.abs(img)

    reduced = map_coordinates(img, new_idx, order=order)

    # blow image back up to img.shape
    (rys, rxs) = reduced.shape
    out_idx = np.mgrid[0:rys-1:ys*j, 0:rxs-1:xs*j]
    return map_coordinates(reduced, out_idx, order=order)
Example #10
0
File: sc.py Project: iagapov/ocelot
 def el_field(self, X, Q, gamma, nxyz):
     if self.random_seed != None:
         np.random.seed(self.random_seed)
     N = X.shape[0]
     X[:, 2] = X[:, 2]*gamma
     XX = np.max(X, axis=0)-np.min(X, axis=0)
     #XX = XX*np.random.uniform(low=1.0, high=1.1)
     if self.debug: print( 'mesh steps:', XX)
     # here we use a fast 3D "near-point" interpolation
     # we need a stand-alone module with 1D,2D,3D parricles-to-grid functions
     steps = XX/(nxyz-3)
     X = X/steps
     X_min = np.min(X, axis=0)
     X_mid = np.dot(Q, X)/np.sum(Q)
     X_off = np.floor(X_min-X_mid) + X_mid
     X = X - X_off
     nx = nxyz[0]
     ny = nxyz[1]
     nz = nxyz[2]
     nzny = nz*ny
     Xi = np.int_(np.floor(X)+1)
     inds = np.int_(Xi[:, 0]*nzny+Xi[:, 1]*nz+Xi[:, 2])  # 3d -> 1d
     q = np.bincount(inds, Q, nzny*nx).reshape(nxyz)
     p = self.potential(q, steps)
     Ex = np.zeros(p.shape)
     Ey = np.zeros(p.shape)
     Ez = np.zeros(p.shape)
     Ex[:nx-1, :, :] = (p[:nx-1, :, :] - p[1:nx, :, :])/steps[0]
     Ey[:, :ny-1, :] = (p[:, :ny-1, :] - p[:, 1:ny, :])/steps[1]
     Ez[:, :, :nz-1] = (p[:, :, :nz-1] - p[:, :, 1:nz])/steps[2]
     Exyz = np.zeros((N, 3))
     Exyz[:, 0] = ndimage.map_coordinates(Ex, np.c_[X[:, 0], X[:, 1]+0.5, X[:, 2]+0.5].T, order=1)*gamma
     Exyz[:, 1] = ndimage.map_coordinates(Ey, np.c_[X[:, 0]+0.5, X[:, 1], X[:, 2]+0.5].T, order=1)*gamma
     Exyz[:, 2] = ndimage.map_coordinates(Ez, np.c_[X[:, 0]+0.5, X[:, 1]+0.5, X[:, 2]].T, order=1)
     return Exyz
Example #11
0
def tract_map_image(tractography, image, quantity_name, file_output):
    from os import path
    from scipy import ndimage

    image = nibabel.load(image)

    ijk_points = tract_in_ijk(image, tractography)
    image_data = image.get_data()

    if image_data.ndim > 3:
        output_name, ext = path.splitext(file_output)
        output_name = output_name + '_%04d' + ext
        for i, image in enumerate(image_data):
            new_scalar_data = ndimage.map_coordinates(
                image.T, ijk_points.T
            )[:, None]
            tractography.original_tracts_data()[
                quantity_name] = new_scalar_data
            tractography_to_file(output_name % i, Tractography(
                tractography.original_tracts(),  tractography.original_tracts_data()))
    else:
        new_scalar_data_flat = ndimage.map_coordinates(
            image_data.T, ijk_points.T
        )[:, None]
        start = 0
        new_scalar_data = []
        for tract in tractography.original_tracts():
            new_scalar_data.append(
                new_scalar_data_flat[start: start + len(tract)])
            start += len(tract)
        tractography.original_tracts_data()[quantity_name] = new_scalar_data

        return Tractography(
            tractography.original_tracts(),  tractography.original_tracts_data()
        )
Example #12
0
def interp3(x, y, z, v, xi, yi, zi, **kwargs):
    """Sample a 3D array "v" with pixel corner locations at "x","y","z" at the
    points in "xi", "yi", "zi" using linear interpolation. Additional kwargs
    are passed on to ``scipy.ndimage.map_coordinates``."""
    import numpy as np
    from scipy.ndimage import map_coordinates
    
    if v.shape != (x.size,y.size,z.size):
        print 'size mismatch in interp3'
        raise ValueError
    
    def index_coords(corner_locs, interp_locs):
        index = np.arange(len(corner_locs))
        if np.all(np.diff(corner_locs) < 0):
            corner_locs, index = corner_locs[::-1], index[::-1]
        return np.interp(interp_locs, corner_locs, index)

    orig_shape = np.asarray(xi).shape
    xi, yi, zi = np.atleast_1d(xi, yi, zi)
    for arr in [xi, yi, zi]:
        arr.shape = -1

    output = np.empty(xi.shape, dtype=float)
    coords = [index_coords(*item) for item in zip([x, y, z], [xi, yi, zi])]

    map_coordinates(v, coords, order=3, output=output, **kwargs)

    return output.reshape(orig_shape)
def minimize_psf(p, im1, im2, box_size, nudgexy, offset): 
    """ Simply minimize residuals
    Args:
        scale - scale factor 
        ave_dm - average dm for a given slice
        ave_sat - average sat for a given slice 
    return:
        residuals for ave_dm and ave_sat
    """

    if nudgexy is False:
        if offset is True:
            return np.nansum(np.abs(((p[0]*im1) - (im2-p[1]))))
        else:
            return np.nansum(np.abs(((p*im1) - im2)))
    else:
        if offset is True:
            #Don't worry about this part - not actually useful!
            x, y = gen_xy(box_size + 4)
            x += p[1]
            y += p[2]
            shifted_im1 = ndimage.map_coordinates(im1, (y, x), cval = np.nan)

            return np.nansum(np.abs(((p[0]*shifted_im1) - (im2-p[3]))))

        else:
            #Don't worry about this part - not actually useful!
            x, y = gen_xy(box_size + 4)
            x += p[1]
            y += p[2]
            shifted_im1 = ndimage.map_coordinates(im1, (y, x), cval = np.nan)

            return np.nansum(np.abs(((p[0]*shifted_im1) - im2)))
Example #14
0
def profile_line(img, src, dst, linewidth=1,
                 order=1, mode='constant', cval=0.0):
    """Return the intensity profile of an image measured along a scan line.

    Parameters
    ----------
    img : numeric array, shape (M, N[, C])
        The image, either grayscale (2D array) or multichannel
        (3D array, where the final axis contains the channel
        information).
    src : 2-tuple of numeric scalar (float or int)
        The start point of the scan line.
    dst : 2-tuple of numeric scalar (float or int)
        The end point of the scan line.
    linewidth : int, optional
        Width of the scan, perpendicular to the line
    order : int in {0, 1, 2, 3, 4, 5}, optional
        The order of the spline interpolation to compute image values at
        non-integer coordinates. 0 means nearest-neighbor interpolation.
    mode : string, one of {'constant', 'nearest', 'reflect', 'wrap'}, optional
        How to compute any values falling outside of the image.
    cval : float, optional
        If `mode` is 'constant', what constant value to use outside the image.

    Returns
    -------
    return_value : array
        The intensity profile along the scan line. The length of the profile
        is the ceil of the computed length of the scan line.

    Examples
    --------
    >>> x = np.array([[1, 1, 1, 2, 2, 2]])
    >>> img = np.vstack([np.zeros_like(x), x, x, x, np.zeros_like(x)])
    >>> img
    array([[0, 0, 0, 0, 0, 0],
           [1, 1, 1, 2, 2, 2],
           [1, 1, 1, 2, 2, 2],
           [1, 1, 1, 2, 2, 2],
           [0, 0, 0, 0, 0, 0]])
    >>> profile_line(img, (2, 1), (2, 4))
    array([ 1.,  1.,  2.,  2.])

    Notes
    -----
    The destination point is included in the profile, in contrast to
    standard numpy indexing.
    """
    perp_lines = _line_profile_coordinates(src, dst, linewidth=linewidth)
    if img.ndim == 3:
        pixels = [ndi.map_coordinates(img[..., i], perp_lines,
                                      order=order, mode=mode, cval=cval)
                  for i in range(img.shape[2])]
        pixels = np.transpose(np.asarray(pixels), (1, 2, 0))
    else:
        pixels = ndi.map_coordinates(img, perp_lines,
                                     order=order, mode=mode, cval=cval)
    intensities = pixels.mean(axis=1)

    return intensities
Example #15
0
    def compose(self, left, right):
        """
        Compose position fields.
        Parameters:
        -----------
        :param left: Outer field.
        :param right: Inner field
        Order of composition: left(right(x))
        :return The composed position field
        """

        d = np.zeros(left.data.shape)
        result = Image.from_data(d, header=left.get_header())

        vol_ext = left.vol_ext[:left.data.shape[-1]]
        left_data = [left.data[..., i].reshape(vol_ext, order='F')
                     for i in range(left.data.shape[-1])]

        data = np.squeeze(result.data)

        for i in range(data.shape[-1]):
            # todo: Incorrect behaviour at boundary
            # This is an issue we need to revisit.
            # Nearest mode is not good when we are dealing with fields.
            # Unfortunately map_coordinates does not allow for leaving the value
            # as is and we will need to implement this at some point.
            ndimage.map_coordinates(np.squeeze(right.data[..., i]),
                                    left_data,
                                    data[..., i],
                                    mode='nearest',
                                    order=self.order, prefilter=True)

        return result
Example #16
0
    def compose_with_position_field(self, left, right_pos):
        """
        Compose displacement fields.
        Parameters:
        -----------
        :param left: Outer displacement field.
        :param right_pos: Inner position field.
        Order of composition: left(right_pos(x))
        :return Return the composed displacement field
        """

        d = np.zeros(right_pos.data.shape)
        result = Image.from_data(d, header=right_pos.get_header())
        vol_ext = right_pos.vol_ext[:right_pos.data.shape[-1]]
        right_data = [right_pos.data[..., i].reshape(vol_ext, order='F')
                      for i in range(right_pos.data.shape[-1])]

        data = np.squeeze(result.data)

        for i in range(data.shape[-1]):
            ndimage.map_coordinates(np.squeeze(left.data[..., i]),
                                    right_data,
                                    data[..., i],
                                    mode='nearest',
                                    order=self.order, prefilter=True)
        return result
Example #17
0
def EField(X,Q,gamma,kern,steps):
    N=X.shape[0];
    X[:,2]=X[:,2]*gamma
    X=X/steps
    X_min=np.min(X,axis=0)
    X_mid=np.dot(Q,X)/np.sum(Q);
    X_off=np.floor(X_min-X_mid)+X_mid;
    X=X-X_off  
    nx,ny,nz=np.int_(3+np.floor(np.max(X,axis=0)))
    nzny=nz*ny
    Xi=np.int_(np.floor(X)+1)
    inds=np.int_(Xi[:,0]*nzny+Xi[:,1]*nz+Xi[:,2]) # 3d -> 1d
    q=np.bincount(inds,Q,nzny*nx)
    print len(q), nx*ny*nz
    
    q=q.reshape(nx,ny,nz)
    #t0=time.time()   
    print q.shape, steps
    p,kern=Phi(q,kern,steps)
    #t1=time.time(); print t1-t0
    Ex=np.zeros(p.shape);Ey=np.zeros(p.shape);Ez=np.zeros(p.shape);
    Ex[:nx-1,:,:]=(p[:nx-1,:,:]-p[1:nx,:,:])/steps[0]
    Ey[:,:ny-1,:]=(p[:,:ny-1,:]-p[:,1:ny,:])/steps[1]
    Ez[:,:,:nz-1]=(p[:,:,:nz-1]-p[:,:,1:nz])/steps[2]
    Exyz=np.zeros((N,3))
    Exyz[:,0]=ndimage.map_coordinates(Ex,np.c_[X[:,0],X[:,1]+0.5,X[:,2]+0.5].T,order=1)*gamma
    Exyz[:,1]=ndimage.map_coordinates(Ey,np.c_[X[:,0]+0.5,X[:,1],X[:,2]+0.5].T,order=1)*gamma
    Exyz[:,2]=ndimage.map_coordinates(Ez,np.c_[X[:,0]+0.5,X[:,1]+0.5,X[:,2]].T,order=1)
    #t1=time.time();    print t1-t0
    return Exyz
Example #18
0
def EField(X,Q,gamma,nxyz):
    N=X.shape[0];
    X[:,2]=X[:,2]*gamma
    XX=np.max(X,axis=0)-np.min(X,axis=0)
    XX=XX*np.random.uniform(low=1.0,high=1.1)
    print 'mesh steps:', XX
    steps=XX/(nxyz-3)
    X=X/steps
    X_min=np.min(X,axis=0)
    X_mid=np.dot(Q,X)/np.sum(Q);
    X_off=np.floor(X_min-X_mid)+X_mid;
    X=X-X_off  
    nx=nxyz[0];ny=nxyz[1];nz=nxyz[2];nzny=nz*ny
    Xi=np.int_(np.floor(X)+1)
    inds=np.int_(Xi[:,0]*nzny+Xi[:,1]*nz+Xi[:,2]) # 3d -> 1d
    print inds.shape, nxyz
    q=np.bincount(inds,Q,nzny*nx).reshape(nxyz)
    p=Phi(q,steps)
    Ex=np.zeros(p.shape);Ey=np.zeros(p.shape);Ez=np.zeros(p.shape);
    Ex[:nx-1,:,:]=(p[:nx-1,:,:]-p[1:nx,:,:])/steps[0]
    Ey[:,:ny-1,:]=(p[:,:ny-1,:]-p[:,1:ny,:])/steps[1]
    Ez[:,:,:nz-1]=(p[:,:,:nz-1]-p[:,:,1:nz])/steps[2]
    Exyz=np.zeros((N,3))
    Exyz[:,0]=ndimage.map_coordinates(Ex,np.c_[X[:,0],X[:,1]+0.5,X[:,2]+0.5].T,order=1)*gamma
    Exyz[:,1]=ndimage.map_coordinates(Ey,np.c_[X[:,0]+0.5,X[:,1],X[:,2]+0.5].T,order=1)*gamma
    Exyz[:,2]=ndimage.map_coordinates(Ez,np.c_[X[:,0]+0.5,X[:,1]+0.5,X[:,2]].T,order=1)
    return Exyz
Example #19
0
def map_coordinates_3d_4d(input_array, indices):
    """ Evaluate the input_array data at the given indices
    using trilinear interpolation

    Parameters
    ----------
    input_array : ndarray,
        3D or 4D array
    indices : ndarray

    Returns
    -------
    output : ndarray
        1D or 2D array
    """

    if input_array.ndim <= 2 or input_array.ndim >= 5:
        raise ValueError("Input array can only be 3d or 4d")

    if input_array.ndim == 3:
        return map_coordinates(input_array, indices.T, order=1)

    if input_array.ndim == 4:
        values_4d = []
        for i in range(input_array.shape[-1]):
            values_tmp = map_coordinates(input_array[..., i], indices.T, order=1)
            values_4d.append(values_tmp)
        return np.ascontiguousarray(np.array(values_4d).T)
Example #20
0
def interp6(x, y, z, w, q, qq, v, xi, yi, zi, wi, qi, qqi, **kwargs):
    """Sample a 5D array "v". Additional kwargs
    are passed on to ``scipy.ndimage.map_coordinates``."""
    import numpy as np
    from scipy.ndimage import map_coordinates
    
    if v.shape != (x.size,y.size,z.size, w.size, q.size, qq.size):
        print 'size mismatch in interp3'
        raise ValueError
    
    def index_coords(corner_locs, interp_locs):
        index = np.arange(len(corner_locs))
        if np.all(np.diff(corner_locs) < 0):
            corner_locs, index = corner_locs[::-1], index[::-1]
        return np.interp(interp_locs, corner_locs, index)

    orig_shape = np.asarray(xi).shape
    xi, yi, zi, wi, qi, qqi = np.atleast_1d(xi, yi, zi, wi, qi, qqi)
    for arr in [xi, yi, zi, wi, qi, qqi]:
        arr.shape = -1

    output = np.empty(xi.shape, dtype=float)
    coords = [index_coords(*item) for item in zip([x, y, z, w, q, qq], [xi, yi, zi, wi, qi, qqi])]

    map_coordinates(v, coords, order=3, output=output, **kwargs)

    return output.reshape(orig_shape)
Example #21
0
    def query(self, l, b, order=1):
        l = np.asarray(l)
        b = np.asarray(b)

        if l.shape != b.shape:
            raise ValueError('l.shape must equal b.shape')

        out = np.zeros_like(l, dtype='f4')

        for pole in ['ngp', 'sgp']:
            m = (b >= 0) if pole == 'ngp' else b < 0

            if np.any(m):
                header, data = self.data[pole]
                wcs = pywcs.WCS(header)

                if not m.shape: # Support for 0-dimensional arrays (scalars). Otherwise it barfs on l[m], b[m]
                    x, y = wcs.wcs_world2pix(l, b, 0)
                    out = map_coordinates(data, [[y], [x]], order=order, mode='nearest')[0]
                    continue

                x, y = wcs.wcs_world2pix(l[m], b[m], 0)
                out[m] = map_coordinates(data, [y, x], order=order, mode='nearest')

        return out
Example #22
0
def ginterpolate (im, X, Y=None, output_type=None, order=1, 
                  mode='constant', cval=0.0, q=False) :
    """
      Emulate the IDL interface to the intepolate
      function using the ndimage.map_coordinates call
      
      @type im:   2-D image buffer
      @type X:    2-D index array with the x-location for which 
                  interpolation is desired. 
      @type Y:    2-D index array with the y-location for which 
                  interpolation is desired. 
      @type order: Default:1. Order of interpolation. The default for
                   map_coordinates is 3
      @type q:     Default False. If True, there is only X and
                   we use only the upper left quarter of the symmetric X
                   (w/r to the array center). NOTE: Currently it is slower
                   to use this option. 

      For more information see help ndimage.map_coordinates

    """
    dim = np.size(np.shape(im))
    szx = np.size(np.shape(X))
    X = np.array(X)
    if Y != None: Y = np.array(Y)

    if dim == 1:
       if szx == 1:
           X = X.reshape([1,np.size(X)])
           z = nd.map_coordinates(im,X, output=output_type, order=order,
                     mode=mode, cval=cval)
       elif szx == 2:
           lim = np.size(im)
           limy,limx = lim,lim
           if Y == None: 
               Y = X
               coords = np.array([X,Y])
               if q:
                   nx,ny = np.shape(X)
                   nx,ny=nx/2,ny/2
                   coords = np.array([X[:ny,:nx],X[:ny,:nx]])
                   limy,limx = lim/2,lim
           else:
               coords = np.array([X,Y])
           z = nd.map_coordinates(np.resize(im,[limy,limx]),coords,
                     output=output_type, order=order, mode=mode, cval=cval)
    elif dim == 2:
       if szx == 1 and Y != None:
           z = nd.map_coordinates(im,[X,Y],output=output_type, order=order,
                     mode=mode, cval=cval)
       elif szx == 2:
           if Y == None: Y = X
           z = nd.map_coordinates(im,[X,Y],output=output_type, order=order,
                     mode=mode, cval=cval)
    else:
       print 'ERROR, dimension of input buffer not supported: ',len
       return 

    return z
Example #23
0
 def vect(coord, t):
     x = [coord[0]]
     y = [coord[1]]
     z = [coord[2]]
     ux = ndimage.map_coordinates(vel[:, :, :, 0, :], [x, y, z, [t]], order=3)
     uy = ndimage.map_coordinates(vel[:, :, :, 1, :], [x, y, z, [t]], order=3)
     uz = ndimage.map_coordinates(vel[:, :, :, 2, :], [x, y, z, [t]], order=3)
     return [ux[0], uy[0], uz[0]]
Example #24
0
def polarSlice2Cube (Slice, zaxis=1, size=None, mode='nearest'):
    s=max(Slice.shape)
    if not(size):
        size=s
    g=x,y,z=np.mgrid[-s:s:size*1j,-s:s:size*1j,-s:s:size*1j]
    R=np.sqrt(x*x+y*y)
    if zaxis==1: return ndimage.map_coordinates(Slice, (R,abs(z)), mode=mode, order=1)
    else       : return ndimage.map_coordinates(Slice, (abs(z),R), mode=mode, order=1)
Example #25
0
def lin2loglog (grid, low=-3, shape=[], order=3):
    xmax,ymax=grid.shape
    if not(shape): shape=grid.shape
    oxmax,oymax=shape
    out=np.zeros(shape)
    x,y=np.mgrid[low:0:oxmax*1j, low:0:oymax*1j]
    ndimage.map_coordinates(grid, [10**x*xmax,10**y*ymax], output=out, mode='nearest', order=order)
    return out
Example #26
0
def extract_line_slice(cube, x, y, order=3, respect_nan=True):
    """
    Given an array with shape (z, y, x), extract a (z, n) slice by
    interpolating at n (x, y) points.

    All units are in *pixels*.

    .. note:: If there are NaNs in the cube, they will be treated as zeros when
              using spline interpolation.

    Parameters
    ----------
    cube : `~numpy.ndarray`
        The data cube to extract the slice from
    curve : list or tuple
        A list or tuple of (x, y) pairs, with minimum length 2
    order : int, optional
        Spline interpolation order. Set to ``0`` for nearest-neighbor
        interpolation.

    Returns
    -------
    slice : `numpy.ndarray`
        The (z, d) slice
    """

    if order == 0:

        slice = np.zeros([cube.shape[0], len(x)]) + np.nan

        x = np.round(x)
        y = np.round(y)

        ok = (x > 0) & (y > 0) & (x < cube.shape[2]) & (y < cube.shape[1])

        slice[:,ok] = cube[:, y[ok].astype(int), x[ok].astype(int)]

    elif order > 0 and order == int(order):

        nx = len(x)
        nz = cube.shape[0]

        zi = np.outer(np.arange(nz, dtype=int), np.ones(nx))
        xi = np.outer(np.ones(nz), x)
        yi = np.outer(np.ones(nz), y)

        slice = map_coordinates(np.nan_to_num(cube), [zi,yi,xi], order=order, cval=np.nan)

        if respect_nan:
            slice_bad = map_coordinates(np.nan_to_num(np.isnan(cube).astype(int)),
                                        [zi,yi,xi], order=order)
            slice[np.nonzero(slice_bad)] = np.nan

    else:

        raise TypeError("order should be a positive integer")

    return slice
Example #27
0
File: core.py Project: adrn/SFD
def ebv(coordinate, order=1):
    """
    Return SFD E(B-V) at the input coordinate(s).

    Parameters
    ----------
    coordinate : :class:`~astropy.coordinates.SkyCoord`, :class:`~astropy.coordinates.BaseCoordinateFrame`
        The coordinate(s) to compute extinction at.
    order : int (optional)
        Passed to :func:`~scipy.ndimage.map_coordinates`.

    Returns
    -------
    EBV : :class:`~numpy.ndarray`
        Extinction at each input coordinate.

    Example
    -------
    TODO
    h, w = 1000, 4000
    b, l = numpy.mgrid[0:h,0:w]
    l = 180.-(l+0.5) / float(w) * 360.
    b = 90. - (b+0.5) / float(h) * 180.
    ebv = dust.getval(l, b)
    imshow(ebv, aspect='auto', norm=matplotlib.colors.LogNorm())
    """

    ngp_filename = get_pkg_data_filename("data/SFD_dust_4096_ngp.fits")
    sgp_filename = get_pkg_data_filename("data/SFD_dust_4096_sgp.fits")

    # convert input coordinate to Galactic frame
    gal = coordinate.transform_to(coord.Galactic)
    l = gal.l.wrap_at(180*u.degree).degree
    b = gal.b.degree

    # output extinctions
    EBV = np.zeros_like(l, dtype='f4') + np.nan

    b_gtr_zero = b >= 0.
    b_les_zero = np.logical_not(b_gtr_zero)
    if np.any(b_gtr_zero): # north
        hdulist = fits.open(ngp_filename)

        w = wcs.WCS(hdulist[0].header)
        x, y = w.wcs_world2pix(l[b_gtr_zero], b[b_gtr_zero], 0)
        EBV[b_gtr_zero] = map_coordinates(hdulist[0].data, [y, x], order=order, mode='nearest')
        hdulist.close()

    if np.any(b_les_zero): # south
        hdulist = fits.open(sgp_filename)

        w = wcs.WCS(hdulist[0].header)
        x, y = w.wcs_world2pix(l[b_les_zero], b[b_les_zero], 0)
        EBV[b_les_zero] = map_coordinates(hdulist[0].data, [y, x], order=order, mode='nearest')
        hdulist.close()

    return EBV
def sample_colors(image, sample_points):
    r"""
    Sample RGB colour values from an image of shape (w, h, 3)
    at floating point (x, y) sample points.
    """
    r = map_coordinates(image[..., 0], sample_points.T)
    g = map_coordinates(image[..., 1], sample_points.T)
    b = map_coordinates(image[..., 2], sample_points.T)
    return np.vstack((r, g, b)).T
Example #29
0
   def values_in_world(self, x, y, z, interpolation_order=3):
      """ Return the values of the data at the world-space positions given by 
      x, y, z

      Parameters
      ----------

      x : number or ndarray
         x positions in world space, in other words milimeters

      y : number or ndarray
         y positions in world space, in other words milimeters.
         The shape of y should match the shape of x
         
      z : number or ndarray
         z positions in world space, in other words milimeters.
         The shape of z should match the shape of x

      interpolation_order : int, optional
         Order of the spline interplation. If 0, nearest neighboor 
         interpolation is performed.

      Returns
      -------
      values : number or ndarray
         Data values interpolated at the given world position.
         This is a number or an ndarray, depending on the shape of
         the input coordinate.
      """
      x = np.atleast_1d(x)
      y = np.atleast_1d(y)
      z = np.atleast_1d(z)
      shape = x.shape
      if not ((x.shape == y.shape) and (x.shape == z.shape)):
         raise ValueError('x, y and z shapes should be equal')
      x = x.ravel()
      y = y.ravel()
      z = z.ravel()
      xyz = np.c_[x, y, z]
      world_to_voxel = self.xyz_transform.inverse()
      ijk = world_to_voxel(xyz)

      data = self.get_data()

      if self.ndim == 3:
         values = map_coordinates(data, ijk.T,
                                  order=interpolation_order)
         values = np.reshape(values, shape)
      elif self.ndim == 4:
         values = np.empty(shape + (self.shape[3],))
         for i in range(self.shape[3]):
            tmp_values = map_coordinates(data[...,i], ijk.T,
                                         order=interpolation_order)
            tmp_values = np.reshape(tmp_values, shape)
            values[...,i] = tmp_values
      return values
Example #30
0
   def OnButton(self, evt):
       '''Handle button click event'''
       # Get title of clicked button
       label = evt.GetEventObject().GetLabel()

       if label == "Get Atmospheric Factors": # Calculate
           try:
               sampleLat = float(self.lat.GetValue())
               sampleLon = float(self.lon.GetValue())

               NCEP = load(self.repo.GetClimateDataPath())
               Temperature = NCEP[0:73,:];seaLevelPress = NCEP[73:146,:];
               LapseRate = NCEP[146:219,:];topo = NCEP[219:292,:]
               Temperature = NCEP[73:0:-1,:];seaLevelPress = NCEP[146:73:-1,:];
               LapseRate = NCEP[219:146:-1,:];topo = NCEP[292:73:-1,:]

               lat = arange(90,-91,-2.5);lon = arange(0, 361,2.5)

               #localCoords is the site coordinates relative to the NCEP data coords
               #For interpolation the field is considered to bound 1 -> nx-1 , 1 -> ny-1
               xfac = len(lat) - 1
               yfac = len(lon) - 1
               localX = (max(lat) - sampleLat) * xfac / (max(lat) - min(lat)) + 1
               localY = sampleLon / max(lon) * yfac + 1
               localCoords = array([[ localX],[ localY ]])

               AnnualMeanSLP = ndimage.map_coordinates(seaLevelPress, localCoords)
               AnnualMeanTemp = ndimage.map_coordinates(Temperature, localCoords)
               AnnualMeanLapse = ndimage.map_coordinates(LapseRate, localCoords)

               sltempVal = "%3.1f" % (float(AnnualMeanTemp))
               slprecVal = "%3.1f" % (float(AnnualMeanSLP))
               LapseRate = "%3.1f" % (float(AnnualMeanLapse*-1))

                # Ignore empty calculation
               #if not compute.strip():
               if not sltempVal:
                   return

               # Calculate result
               # result = eval(compute)

               # Add to history
               self.sltemp.Insert(str(sltempVal), 0)
               self.slprec.Insert(str(slprecVal), 0)
               self.lapse.Insert(str(LapseRate), 0)
              
               # Show result
               #self.display.SetValue(str(result))
               self.sltemp.SetValue(str(sltempVal))
               self.slprec.SetValue(str(slprecVal))
               self.lapse.SetValue(str(LapseRate))
               #self.slprec.SetValue(str(slprecVal))
           except Exception, e:
               wx.LogError(str(e))
               return
Example #31
0
def calc_offset(psflets,
                image,
                offsets,
                dx=64,
                maxcpus=multiprocessing.cpu_count()):
    """
    Function calc_offset: compute the position-dependent sub-pixel
    shift in the PSFlet spot grid using cross-correlation.

    Inputs:
    1. psflets:  ndarray, (nlam, ny, Nx), with Nx = upsamp*nx,
                 i.e. oversampled by a factor upsamp in the last 
                 dimension (perpendicular to the CHARIS dispersion
                 direction).
    2. image:    ndarray, (ny, nx)
    3. offsets:  ndarray, integer offsets at which to compute 
                 cross-correlation, shifting psflets by upsamp with
                 respect to image.

    Optional inputs:
    1. dx:       integer, (dx,dx) size of chunks on which to compute
                 cross-correlation.  Default 64 (so that 32x32
                 offsets are computed for a 2048x2048 image).
    2. maxcpus:  number of threads for OpenMP parallelization of 
                 cython code.  Default multiprocessing.cpu_count().

    Output:
    1. psflets:  ndarray, (nlam, ny, nx), PSFlet templates shifted 
                 by a position-dependent value to maximize the 
                 cross-correlation with the input image.

    """

    mask = (image.ivar > 0).astype(np.uint16)

    if psflets.dtype != 'float32':  # Ensure correct dtype, native byte order
        psflets2 = np.empty(psflets.shape, np.float32)
        psflets2[:] = psflets
        psflets = psflets2

    #####################################################################
    # Calculate the cross-correlation of the PSFlet images and the
    # actual data at the specified offsets.  Do this in dim/dx
    # subregions of the image to get a position-dependent shift.
    #####################################################################

    ny, nx = image.data.shape
    shiftarr = np.zeros(
        (int(np.ceil(ny * 1. / dx)), int(np.ceil(nx * 1. / dx))))

    outarr = np.zeros((psflets.shape[0], ny, nx))

    for i in range(0, nx, dx):

        corrvals_all = matutils.crosscorr(psflets,
                                          image.data,
                                          image.ivar,
                                          offsets,
                                          maxproc=maxcpus,
                                          m1=i,
                                          m2=i + dx)

        for j in range(0, ny, dx):

            corrvals = np.sum(corrvals_all[:, j:j + dx], axis=1)

            #############################################################
            # Calculate offset to maximize the cross-correlation by
            # fitting a parabola to the five points bracketing the
            # best value
            #############################################################

            icen = np.arange(
                offsets.shape[0])[np.where(corrvals == np.amax(corrvals))]
            imin = int(max(0, icen - 2))
            imax = int(min(offsets.shape[0], icen + 3))
            corrvals = corrvals[imin:imax]

            arr = np.ones((imax - imin, 3))
            arr[:, 1] = offsets[imin:imax]
            arr[:, 2] = offsets[imin:imax]**2
            coef = linalg.lstsq(arr, corrvals)[0]

            shift = -coef[1] / (2 * coef[2])
            shiftarr[j // dx, i // dx] = shift

    #####################################################################
    # Return the interpolated array at the requested offset
    #####################################################################

    if shiftarr.shape[0] >= 3:
        shiftarr[1:-1, 1:-1] = signal.medfilt2d(shiftarr, 3)[1:-1, 1:-1]
        shiftarr[0, 1:-1] = signal.medfilt(shiftarr[0], 3)[1:-1]
        shiftarr[-1, 1:-1] = signal.medfilt(shiftarr[-1], 3)[1:-1]
        shiftarr[1:-1, 0] = signal.medfilt(shiftarr[:, 0], 3)[1:-1]
        shiftarr[1:-1, -1] = signal.medfilt(shiftarr[:, -1], 3)[1:-1]

    x = (1. * np.arange(ny)) / dx - 0.5
    x *= x > 0
    x[np.where(x > shiftarr.shape[0] - 1)] = shiftarr.shape[0] - 1
    x, y = np.meshgrid(x, x)

    fullshiftarr = ndimage.map_coordinates(shiftarr, [y, x], order=3)

    psflets = matutils.interpcal(psflets,
                                 image.data,
                                 mask,
                                 fullshiftarr,
                                 maxproc=maxcpus)
    return psflets
    def run_on_image_setting(self, workspace, image):
        assert isinstance(workspace, cpw.Workspace)
        image_set = workspace.image_set
        measurements = workspace.measurements
        im = image_set.get_image(image.image_name.value,
                                 must_be_grayscale=True)
        #
        # Downsample the image and mask
        #
        new_shape = np.array(im.pixel_data.shape)
        if image.subsample_size.value < 1:
            new_shape = new_shape * image.subsample_size.value
            i, j = (np.mgrid[0:new_shape[0], 0:new_shape[1]].astype(float) /
                    image.subsample_size.value)
            pixels = scind.map_coordinates(im.pixel_data, (i, j), order=1)
            mask = scind.map_coordinates(im.mask.astype(float), (i, j)) > .9
        else:
            pixels = im.pixel_data
            mask = im.mask
        #
        # Remove background pixels using a greyscale tophat filter
        #
        if image.image_sample_size.value < 1:
            back_shape = new_shape * image.image_sample_size.value
            i, j = (np.mgrid[0:back_shape[0], 0:back_shape[1]].astype(float) /
                    image.image_sample_size.value)
            back_pixels = scind.map_coordinates(pixels, (i, j), order=1)
            back_mask = scind.map_coordinates(mask.astype(float), (i, j)) > .9
        else:
            back_pixels = pixels
            back_mask = mask
        radius = image.element_size.value
        back_pixels = morph.grey_erosion(back_pixels, radius, back_mask)
        back_pixels = morph.grey_dilation(back_pixels, radius, back_mask)
        if image.image_sample_size.value < 1:
            i, j = np.mgrid[0:new_shape[0], 0:new_shape[1]].astype(float)
            #
            # Make sure the mapping only references the index range of
            # back_pixels.
            #
            i *= float(back_shape[0] - 1) / float(new_shape[0] - 1)
            j *= float(back_shape[1] - 1) / float(new_shape[1] - 1)
            back_pixels = scind.map_coordinates(back_pixels, (i, j), order=1)
        pixels -= back_pixels
        pixels[pixels < 0] = 0

        #
        # For each object, build a little record
        #
        class ObjectRecord(object):
            def __init__(self, name):
                self.name = name
                self.labels = workspace.object_set.get_objects(name).segmented
                self.nobjects = np.max(self.labels)
                if self.nobjects != 0:
                    self.range = np.arange(1, np.max(self.labels) + 1)
                    self.labels = self.labels.copy()
                    self.labels[~im.mask] = 0
                    self.current_mean = fix(
                        scind.mean(im.pixel_data, self.labels, self.range))
                    self.start_mean = np.maximum(self.current_mean,
                                                 np.finfo(float).eps)

        object_records = [
            ObjectRecord(ob.objects_name.value) for ob in image.objects
        ]
        #
        # Transcribed from the Matlab module: granspectr function
        #
        # CALCULATES GRANULAR SPECTRUM, ALSO KNOWN AS SIZE DISTRIBUTION,
        # GRANULOMETRY, AND PATTERN SPECTRUM, SEE REF.:
        # J.Serra, Image Analysis and Mathematical Morphology, Vol. 1. Academic Press, London, 1989
        # Maragos,P. "Pattern spectrum and multiscale shape representation", IEEE Transactions on Pattern Analysis and Machine Intelligence, 11, N 7, pp. 701-716, 1989
        # L.Vincent "Granulometries and Opening Trees", Fundamenta Informaticae, 41, No. 1-2, pp. 57-90, IOS Press, 2000.
        # L.Vincent "Morphological Area Opening and Closing for Grayscale Images", Proc. NATO Shape in Picture Workshop, Driebergen, The Netherlands, pp. 197-208, 1992.
        # I.Ravkin, V.Temov "Bit representation techniques and image processing", Applied Informatics, v.14, pp. 41-90, Finances and Statistics, Moskow, 1988 (in Russian)
        # THIS IMPLEMENTATION INSTEAD OF OPENING USES EROSION FOLLOWED BY RECONSTRUCTION
        #
        ng = image.granular_spectrum_length.value
        startmean = np.mean(pixels[mask])
        ero = pixels.copy()
        # Mask the test image so that masked pixels will have no effect
        # during reconstruction
        #
        ero[~mask] = 0
        currentmean = startmean
        startmean = max(startmean, np.finfo(float).eps)

        footprint = np.array([[False, True, False], [True, True, True],
                              [False, True, False]])
        statistics = [image.image_name.value]
        for i in range(1, ng + 1):
            prevmean = currentmean
            ero = morph.grey_erosion(ero, mask=mask, footprint=footprint)
            rec = morph.grey_reconstruction(ero, pixels, footprint)
            currentmean = np.mean(rec[mask])
            gs = (prevmean - currentmean) * 100 / startmean
            statistics += ["%.2f" % gs]
            feature = image.granularity_feature(i)
            measurements.add_image_measurement(feature, gs)
            #
            # Restore the reconstructed image to the shape of the
            # original image so we can match against object labels
            #
            orig_shape = im.pixel_data.shape
            i, j = np.mgrid[0:orig_shape[0], 0:orig_shape[1]].astype(float)
            #
            # Make sure the mapping only references the index range of
            # back_pixels.
            #
            i *= float(new_shape[0] - 1) / float(orig_shape[0] - 1)
            j *= float(new_shape[1] - 1) / float(orig_shape[1] - 1)
            rec = scind.map_coordinates(rec, (i, j), order=1)

            #
            # Calculate the means for the objects
            #
            for object_record in object_records:
                assert isinstance(object_record, ObjectRecord)
                if object_record.nobjects > 0:
                    new_mean = fix(
                        scind.mean(rec, object_record.labels,
                                   object_record.range))
                    gss = ((object_record.current_mean - new_mean) * 100 /
                           object_record.start_mean)
                    object_record.current_mean = new_mean
                else:
                    gss = np.zeros((0, ))
                measurements.add_measurement(object_record.name, feature, gss)
        return statistics
Example #33
0
def get_profile(x, y, f, xi, yi, mode='nearest', order=3):
    """
    Interpolate regular data.

    Parameters
    ----------
    x : two dimensional np.ndarray
        an array for the :math:`x` coordinates

    y : two dimensional np.ndarray
        an array for the :math:`y` coordinates

    f : two dimensional np.ndarray
        an array with the value of the function to be interpolated
        at :math:`x,y` coordinates.

    xi : one dimension np.ndarray
        the :math:`x` coordinates of the point where we want
        the function to be interpolated.

    yi : one dimension np.ndarray
        the :math:`y` coordinates of the point where we want
        the function to be interpolated.

    order : int
        the order of the bivariate spline interpolation


    Returns
    -------
    fi : one dimension np.ndarray
        the value of the interpolating spline at :math:`xi,yi`


    Examples
    --------
    >>> import numpy as np
    >>> from oceans.ocfis import get_profile
    >>> x, y = np.meshgrid(range(360), range(91))
    >>> f = np.array(range(91 * 360)).reshape((91, 360))
    >>> Paris = [2.4, 48.9]
    >>> Rome = [12.5, 41.9]
    >>> Greenwich = [0, 51.5]
    >>> xi = Paris[0], Rome[0], Greenwich[0]
    >>> yi = Paris[1], Rome[1], Greenwich[1]
    >>> get_profile(x, y, f, xi, yi, order=3)
    array([17606, 15096, 18540])

    """
    from scipy.ndimage import map_coordinates

    x, y, f, xi, yi = list(map(np.asanyarray, (x, y, f, xi, yi)))
    conditions = np.array([xi.min() < x.min(),
                           xi.max() > x.max(),
                           yi.min() < y.min(),
                           yi.max() > y.max()])

    if conditions.any():
        warnings.warn('Warning! Extrapolation!!')

    dx = x[0, 1] - x[0, 0]
    dy = y[1, 0] - y[0, 0]

    jvals = (xi - x[0, 0]) / dx
    ivals = (yi - y[0, 0]) / dy

    coords = np.array([ivals, jvals])

    return map_coordinates(f, coords, mode=mode, order=order)
Example #34
0
    def frontalization(self, img_, facebb, p2d_):
        #we rescale the face region (twice as big as the detected face) before applying frontalisation
        #the rescaled size is WD x HT
        WD = 250
        HT = 250
        ACC_CONST = 800
        facebb = [facebb.left(), facebb.top(), facebb.width(), facebb.height()]
        w = facebb[2]
        h = facebb[3]
        fb_ = np.clip([[facebb[0] - w, facebb[1] - h],
                       [facebb[0] + 2 * w, facebb[1] + 2 * h]], [0, 0],
                      [img_.shape[1], img_.shape[0]])
        img = img_[fb_[0][1]:fb_[1][1], fb_[0][0]:fb_[1][0], :]
        p2d = copy.deepcopy(p2d_)
        p2d[:, 0] = (p2d_[:, 0] - fb_[0][0]) * float(WD) / float(img.shape[1])
        p2d[:, 1] = (p2d_[:, 1] - fb_[0][1]) * float(HT) / float(img.shape[0])
        img = cv2.resize(img, (WD, HT))
        #finished rescaling

        tem3d = np.reshape(self.refU, (-1, 3), order='F')
        bgids = tem3d[:, 1] < 0  # excluding background 3d points
        # plot3d(tem3d)
        # print tem3d.shape
        ref3dface = np.insert(tem3d, 3, np.ones(len(tem3d)), axis=1).T
        ProjM = self.get_headpose(p2d)[2]
        proj3d = ProjM.dot(ref3dface)
        proj3d[0] /= proj3d[2]
        proj3d[1] /= proj3d[2]
        proj2dtmp = proj3d[0:2]
        #The 3D reference is projected to the 2D region by the estimated pose
        #The check the projection lies in the image or not
        vlids = np.logical_and(
            np.logical_and(proj2dtmp[0] > 0, proj2dtmp[1] > 0),
            np.logical_and(proj2dtmp[0] < img.shape[1] - 1,
                           proj2dtmp[1] < img.shape[0] - 1))
        vlids = np.logical_and(vlids, bgids)
        proj2d_valid = proj2dtmp[:, vlids]

        sp_ = self.refU.shape[0:2]
        synth_front = np.zeros(sp_, np.float)
        inds = np.ravel_multi_index(np.round(proj2d_valid).astype(int),
                                    (img.shape[1], img.shape[0]),
                                    order='F')
        unqeles, unqinds, inverids, conts = np.unique(inds,
                                                      return_index=True,
                                                      return_inverse=True,
                                                      return_counts=True)
        tmp_ = synth_front.flatten()
        tmp_[vlids] = conts[inverids].astype(np.float)
        synth_front = tmp_.reshape(synth_front.shape, order='F')
        synth_front = cv2.GaussianBlur(synth_front, (17, 17),
                                       30).astype(np.float)

        rawfrontal = np.zeros((self.refU.shape[0], self.refU.shape[1], 3))
        for k in range(3):
            z = img[:, :, k]
            intervalues = ndimage.map_coordinates(img[:, :, k].T,
                                                  proj2d_valid,
                                                  order=3,
                                                  mode='nearest')
            tmp_ = rawfrontal[:, :, k].flatten()
            tmp_[vlids] = intervalues
            rawfrontal[:, :, k] = tmp_.reshape(self.refU.shape[0:2], order='F')

        mline = synth_front.shape[1] / 2
        sumleft = np.sum(synth_front[:, 0:mline])
        sumright = np.sum(synth_front[:, mline:])
        sum_diff = sumleft - sumright
        #print sum_diff
        if np.abs(sum_diff) > ACC_CONST:
            weights = np.zeros(sp_)
            if sum_diff > ACC_CONST:
                weights[:, mline:] = 1.
            else:
                weights[:, 0:mline] = 1.
            weights = cv2.GaussianBlur(weights, (33, 33),
                                       60.5).astype(np.float)
            synth_front /= np.max(synth_front)
            weight_take_from_org = 1 / np.exp(1 + synth_front)
            weight_take_from_sym = 1 - weight_take_from_org
            weight_take_from_org = weight_take_from_org * np.fliplr(weights)
            weight_take_from_sym = weight_take_from_sym * np.fliplr(weights)
            weights = np.tile(weights, (1, 3)).reshape(
                (weights.shape[0], weights.shape[1], 3), order='F')
            weight_take_from_org = np.tile(
                weight_take_from_org, (1, 3)).reshape(
                    (weight_take_from_org.shape[0],
                     weight_take_from_org.shape[1], 3),
                    order='F')
            weight_take_from_sym = np.tile(
                weight_take_from_sym, (1, 3)).reshape(
                    (weight_take_from_sym.shape[0],
                     weight_take_from_sym.shape[1], 3),
                    order='F')
            denominator = weights + weight_take_from_org + weight_take_from_sym
            frontal_sym = (
                rawfrontal * weights + rawfrontal * weight_take_from_org +
                np.fliplr(rawfrontal) * weight_take_from_sym) / denominator
        else:
            frontal_sym = rawfrontal
        return rawfrontal, frontal_sym, np.round(frontal_sym).astype(np.uint8)
Example #35
0
linename = 'NaClv=2_26-25'
linename = 'NaClv=1_18-17'  # use this to compute the continuum in the spectral extraction region
naclfn = paths.dpath(
    'moments/Orion{1}_{0}_robust{robust}.maskedclarkclean10000_medsub_K_peak.fits'
).format(linename, sourcename, robust=robust)
nacldata = fits.getdata(naclfn)
ww = wcs.WCS(fits.getheader(naclfn))
pixscale = wcs.utils.proj_plane_pixel_scales(ww)[0]

yy, xx = np.indices(np.array(nacldata.shape) * 2) - np.array([0, 101])[:, None,
                                                                       None]
rotcoords = np.dot(
    np.array([yy, xx]).T,
    [[np.cos(-38 * u.deg), -np.sin(-38 * u.deg)],
     [np.sin(-38 * u.deg), np.cos(-38 * u.deg)]])
rslt = map_coordinates(nacldata, rotcoords.T)

mn, mid, std = stats.sigma_clipped_stats(nacldata)

pl.clf()
pl.imshow(rslt, origin='lower')
pl.colorbar()

xslice = slice(36, 110)
# truncate the disk edges xslice = slice(55,95)
yslice = slice(100, 128)
naclcutout = rslt[xslice, yslice]
naclmask = naclcutout > (std * 2 + mn)
naclcutout[~naclmask] = np.nan
fig = pl.gcf()
pl.clf()
Example #36
0
def warp(image,
         inverse_map=None,
         map_args={},
         output_shape=None,
         order=1,
         mode='constant',
         cval=0.,
         clip=True):
    """Warp an image according to a given coordinate transformation.

    Parameters
    ----------
    image : ndarray
        Input image.
    inverse_map : transformation object, callable ``cr = f(cr, **kwargs)``, or ndarray
        Inverse coordinate map, which transforms coordinates in the output
        images into their corresponding coordinates in the input image.

        There are a number of different options to define this map, depending
        on the dimensionality of the input image. A 2-D image can have 2
        dimensions for gray-scale images, or 3 dimensions with color
        information.

         - For 2-D images, you can directly pass a transformation object,
           e.g. `skimage.transform.SimilarityTransform`, or its inverse.
         - For 2-D images, you can pass a ``(3, 3)`` homogeneous
           transformation matrix, e.g.
           `skimage.transform.SimilarityTransform.params`.
         - For 2-D images, a function that transforms a ``(M, 2)`` array of
           ``(col, row)`` coordinates in the output image to their
           corresponding coordinates in the input image. Extra parameters to
           the function can be specified through `map_args`.
         - For N-D images, you can directly pass an array of coordinates.
           The first dimension specifies the coordinates in the input image,
           while the subsequent dimensions determine the position in the
           output image. E.g. in case of 2-D images, you need to pass an array
           of shape ``(2, rows, cols)``, where `rows` and `cols` determine the
           shape of the output image, and the first dimension contains the
           ``(row, col)`` coordinate in the input image.
           See `scipy.ndimage.map_coordinates` for further documentation.

        Note, that a ``(3, 3)`` matrix is interpreted as a homogeneous
        transformation matrix, so you cannot interpolate values from a 3-D
        input, if the output is of shape ``(3,)``.

        See example section for usage.
    map_args : dict, optional
        Keyword arguments passed to `inverse_map`.
    output_shape : tuple (rows, cols), optional
        Shape of the output image generated. By default the shape of the input
        image is preserved.  Note that, even for multi-band images, only rows
        and columns need to be specified.
    order : int, optional
        The order of interpolation. The order has to be in the range 0-5:
         - 0: Nearest-neighbor
         - 1: Bi-linear (default)
         - 2: Bi-quadratic
         - 3: Bi-cubic
         - 4: Bi-quartic
         - 5: Bi-quintic
    mode : string, optional
        Points outside the boundaries of the input are filled according
        to the given mode ('constant', 'nearest', 'reflect' or 'wrap').
    cval : float, optional
        Used in conjunction with mode 'constant', the value outside
        the image boundaries.
    clip : bool, optional
        Whether to clip the output to the float range of ``[0, 1]``, or
        ``[-1, 1]`` for input images with negative values. This is enabled by
        default, since  higher order interpolation may produce values outside
        the given input range.

    Notes
    -----
    In case of a `SimilarityTransform`, `AffineTransform` and
    `ProjectiveTransform` and `order` in [0, 3] this function uses the
    underlying transformation matrix to warp the image with a much faster
    routine.

    Examples
    --------
    >>> from skimage.transform import warp
    >>> from skimage import data
    >>> image = data.camera()

    The following image warps are all equal but differ substantially in
    execution time. The image is shifted to the bottom.

    Use a geometric transform to warp an image (fast):

    >>> from skimage.transform import SimilarityTransform
    >>> tform = SimilarityTransform(translation=(0, -10))
    >>> warped = warp(image, tform)

    Use a callable (slow):

    >>> def shift_down(xy):
    ...     xy[:, 1] -= 10
    ...     return xy
    >>> warped = warp(image, shift_down)

    Use a transformation matrix to warp an image (fast):

    >>> matrix = np.array([[1, 0, 0], [0, 1, -10], [0, 0, 1]])
    >>> warped = warp(image, matrix)
    >>> from skimage.transform import ProjectiveTransform
    >>> warped = warp(image, ProjectiveTransform(matrix=matrix))

    You can also use the inverse of a geometric transformation (fast):

    >>> warped = warp(image, tform.inverse)

    For N-D images you can pass a coordinate array, that specifies the
    coordinates in the input image for every element in the output image. E.g.
    if you want to rescale a 3-D cube, you can do:

    >>> cube_shape = np.array([30, 30, 30])
    >>> cube = np.random.rand(*cube_shape)

    Setup the coordinate array, that defines the scaling:

    >>> scale = 0.1
    >>> output_shape = (scale * cube_shape).astype(int)
    >>> coords0, coords1, coords2 = \
    ...     np.mgrid[:output_shape[0], :output_shape[1], :output_shape[2]]
    >>> coords = np.array([coords0, coords1, coords2])

    Assume that the cube contains spatial data, where the first array element
    center is at coordinate (0.5, 0.5, 0.5) in real space, i.e. we have to
    account for this extra offset when scaling the image:

    >>> coords = (coords + 0.5) / scale - 0.5
    >>> warped = warp(cube, coords)

    """

    image = img_as_float(image)
    input_shape = np.array(image.shape)

    if output_shape is None:
        output_shape = input_shape
    else:
        output_shape = safe_as_int(output_shape)

    out = None

    if order in range(4) and not map_args:
        # use fast Cython version for specific interpolation orders and input

        matrix = None

        if isinstance(inverse_map, np.ndarray) and inverse_map.shape == (3, 3):
            # inverse_map is a transformation matrix as numpy array
            matrix = inverse_map

        elif isinstance(inverse_map, HOMOGRAPHY_TRANSFORMS):
            # inverse_map is a homography
            matrix = inverse_map.params

        elif (hasattr(inverse_map, '__name__')
              and inverse_map.__name__ == 'inverse'
              and get_bound_method_class(inverse_map) \
                  in HOMOGRAPHY_TRANSFORMS):
            # inverse_map is the inverse of a homography
            matrix = np.linalg.inv(six.get_method_self(inverse_map).params)

        if matrix is not None:
            matrix = matrix.astype(np.double)
            if image.ndim == 2:
                out = _warp_fast(image,
                                 matrix,
                                 output_shape=output_shape,
                                 order=order,
                                 mode=mode,
                                 cval=cval)
            elif image.ndim == 3:
                dims = []
                for dim in range(image.shape[2]):
                    dims.append(
                        _warp_fast(image[..., dim],
                                   matrix,
                                   output_shape=output_shape,
                                   order=order,
                                   mode=mode,
                                   cval=cval))
                out = np.dstack(dims)

    if out is None:
        # use ndimage.map_coordinates

        if (isinstance(inverse_map, np.ndarray)
                and inverse_map.shape == (3, 3)):
            # inverse_map is a transformation matrix as numpy array,
            # this is only used for order >= 4.
            inverse_map = ProjectiveTransform(matrix=inverse_map)

        if isinstance(inverse_map, np.ndarray):
            # inverse_map is directly given as coordinates
            coords = inverse_map
        else:
            # inverse_map is given as function, that transforms (N, 2)
            # destination coordinates to their corresponding source
            # coordinates. This is only supported for 2(+1)-D images.

            if image.ndim < 2 or image.ndim > 3:
                raise ValueError("Only 2-D images (grayscale or color) are "
                                 "supported, when providing a callable "
                                 "`inverse_map`.")

            def coord_map(*args):
                return inverse_map(*args, **map_args)

            if len(input_shape) == 3 and len(output_shape) == 2:
                # Input image is 2D and has color channel, but output_shape is
                # given for 2-D images. Automatically add the color channel
                # dimensionality.
                output_shape = (output_shape[0], output_shape[1],
                                input_shape[2])

            coords = warp_coords(coord_map, output_shape)

        # Pre-filtering not necessary for order 0, 1 interpolation
        prefilter = order > 1

        out = ndimage.map_coordinates(image,
                                      coords,
                                      prefilter=prefilter,
                                      mode=mode,
                                      order=order,
                                      cval=cval)

    if clip:
        # The spline filters sometimes return results outside [0, 1],
        # so clip to ensure valid data

        if np.min(image) < 0:
            min_val = -1
        else:
            min_val = 0
        max_val = 1

        clipped = np.clip(out, min_val, max_val)

        if mode == 'constant' and not (0 <= cval <= 1):
            clipped[out == cval] = cval

        out = clipped

    return out
Example #37
0
    def frontalization(self, img_, facebb, p2d_):
        #we rescale the face region (twice as big as the detected face) before applying frontalisation
        ACC_CONST = 0
        img, p2d, TransM = resize(img_, facebb, p2d_)

        tem3d = np.reshape(self.refU, (-1, 3), order='F')
        bgids = tem3d[:, 1] < 0  # excluding background 3d points
        # plot3d(tem3d)
        # print tem3d.shape
        ref3dface = np.insert(tem3d, 3, np.ones(len(tem3d)),
                              axis=1).T  # homogeneous coordinates
        _, _, ProjM = self.get_headpose(p2d)
        proj3d = ProjM.dot(ref3dface)
        proj3d[0] /= proj3d[2]  # homogeneous normalization
        proj3d[1] /= proj3d[2]  # homogeneous normalization
        proj2dtmp = proj3d[0:2]
        #The 3D reference is projected to the 2D region by the estimated pose
        #Then check the projection lies in the image or not
        vlids = np.logical_and(
            np.logical_and(proj2dtmp[0] > 0, proj2dtmp[1] > 0),
            np.logical_and(proj2dtmp[0] < img.shape[1] - 1,
                           proj2dtmp[1] < img.shape[0] - 1))
        vlids = np.logical_and(vlids, bgids)
        proj2d_valid = proj2dtmp[:,
                                 vlids]  # totally vlids points can be projected into the query image

        sp_ = self.refU.shape[0:2]
        synth_front = np.zeros(sp_, np.float)  # 320 * 320
        inds = np.ravel_multi_index(np.round(proj2d_valid).astype(int),
                                    (img.shape[1], img.shape[0]),
                                    order='F')
        unqeles, unqinds, inverids, conts = np.unique(inds,
                                                      return_index=True,
                                                      return_inverse=True,
                                                      return_counts=True)
        tmp_ = synth_front.flatten()
        tmp_[vlids] = conts[inverids].astype(np.float)
        synth_front = tmp_.reshape(synth_front.shape, order='F')
        synth_front = cv2.GaussianBlur(synth_front, (17, 17),
                                       30).astype(np.float)

        # color all the valid projected 2d points according to the query image
        rawfrontal = np.zeros((self.refU.shape[0], self.refU.shape[1], 3))
        for k in range(3):
            intervalues = ndimage.map_coordinates(img[:, :, k].T,
                                                  proj2d_valid,
                                                  order=3,
                                                  mode='nearest')
            tmp_ = rawfrontal[:, :, k].flatten()
            tmp_[vlids] = intervalues
            rawfrontal[:, :, k] = tmp_.reshape(self.refU.shape[0:2], order='F')

        mline = synth_front.shape[1] // 2
        sumleft = np.sum(synth_front[:, 0:mline])
        sumright = np.sum(synth_front[:, mline:])
        sum_diff = sumleft - sumright
        # print(sum_diff)
        if np.abs(sum_diff) > ACC_CONST:
            weights = np.zeros(sp_)
            if sum_diff > ACC_CONST:  # sumleft > sumright => face to left
                weights[:, mline:] = 1.
            else:  # sumright > sumleft => face to right
                weights[:, 0:mline] = 1.
            weights = cv2.GaussianBlur(weights, (33, 33),
                                       60.5).astype(np.float)
            synth_front /= np.max(synth_front)
            weight_take_from_org = 1 / np.exp(1 + synth_front)
            weight_take_from_sym = 1 - weight_take_from_org
            weight_take_from_org = weight_take_from_org * np.fliplr(weights)
            weight_take_from_sym = weight_take_from_sym * np.fliplr(weights)

            weights = np.tile(weights, (1, 3)).reshape(
                (weights.shape[0], weights.shape[1], 3), order='F')
            weight_take_from_org = np.tile(
                weight_take_from_org, (1, 3)).reshape(
                    (weight_take_from_org.shape[0],
                     weight_take_from_org.shape[1], 3),
                    order='F')
            weight_take_from_sym = np.tile(
                weight_take_from_sym, (1, 3)).reshape(
                    (weight_take_from_sym.shape[0],
                     weight_take_from_sym.shape[1], 3),
                    order='F')

            denominator = weights + weight_take_from_org + weight_take_from_sym
            frontal_sym = (
                rawfrontal * weights + rawfrontal * weight_take_from_org +
                np.fliplr(rawfrontal) * weight_take_from_sym) / denominator
        else:
            frontal_sym = rawfrontal
        return rawfrontal, frontal_sym, ProjM, TransM
Example #38
0
def correlate_img_to_ref_q4(node_coordss, img, ref, settings):
    # Instantiate empty arrays

    node_coords = node_coordss.copy()

    img = nd.spline_filter(img, order=settings.interpolation_order)

    pix_cord_local = [
        np.zeros((2, ref.Nref_stack[elm_nr].shape[0]), dtype=np.float64)
        for elm_nr in range(settings.mesh.n_elms)
    ]

    n_nodes = settings.mesh.n_nodes
    n_nodes_elm = settings.mesh.element_def.n_nodes

    di = np.zeros(n_nodes_elm * 2, dtype=np.float64)
    dnod = np.zeros(n_nodes * 2, dtype=np.float64)
    C = np.zeros(n_nodes * 2, dtype=np.float64)

    # Find borders of the elements
    borders = find_elm_borders_mesh(node_coords, settings.mesh,
                                    settings.mesh.n_elms)

    # Extract image within element borders with padding
    img_frames = [
        img[borders[2, el].astype(int) -
            settings.pad:borders[3, el].astype(int) + settings.pad,
            borders[0, el].astype(int) -
            settings.pad:borders[1, el].astype(int) + settings.pad]
        for el in range(settings.mesh.n_elms)
    ]

    # Normalize image frame flux
    if False:
        img_frames = map(normalized_zero_mean, img_frames)

    # Element loop
    # TODO: This implementation does handle errors very pretty...
    for it in range(settings.maxit):
        C[:] = 0.0

        for el in range(settings.mesh.n_elms):
            Ic = np.zeros_like(ref.I0_stack[el], dtype=np.float64)
            # Find current coordinates element within the elm_frame
            np.dot(ref.Nref_stack[el],
                   node_coords[0, settings.mesh.ele[:, el]] - borders[0, el] +
                   settings.pad,
                   out=pix_cord_local[el][1])
            np.dot(ref.Nref_stack[el],
                   node_coords[1, settings.mesh.ele[:, el]] - borders[2, el] +
                   settings.pad,
                   out=pix_cord_local[el][0])

            # Determine greyscale value at XYc
            nd.map_coordinates(img_frames[el],
                               pix_cord_local[el],
                               order=settings.interpolation_order,
                               prefilter=False,
                               output=Ic,
                               mode="nearest")

            # Calculate B^T * dIK
            np.dot(ref.B_stack[el], (ref.I0_stack[el] - Ic), out=di)

            # TODO: This shape is awkvard
            # Order di to match format of K
            C[(settings.mesh.ele[:, el] + 1) * 2 -
              2] += di[:settings.elm.n_nodes]
            C[(settings.mesh.ele[:, el] + 1) * 2 -
              1] += di[settings.elm.n_nodes:]

        # Calculate position increment as (B^T B)^-1 * (B^T*dIk) "Least squares solution"
        np.dot(ref.K, C, out=dnod)

        # Add increment to nodal positions
        node_coords[0, :] += dnod[::2]
        node_coords[1, :] += dnod[1::2]

        # Check for convergence
        if np.max(np.abs(dnod)) < settings.tol:
            logging.info('Converged in %s iterations' % it)
            return node_coords, Ic, True

    logging.info(
        'Did not converged in %s iterations last increment was %0.4f' %
        (it, np.max(np.abs(dnod))))
    return node_coords, Ic, False
Example #39
0
def correlate_frames(node_pos, mesh, img, ref, settings):
    """
    Parameters
    ----------
    node_pos : ndarray
       The position of the nodes
    mesh : Mesh
       The mesh object
    img : ndarray
       2d array containing the image frame
    ref : Reference
       The reference object
    settings : DICInput
       The settings which will be used during the analysis
   Returns
   -------
   updated node positions, current pixel values
    """

    logger = logging.getLogger(__name__)

    node_pos = np.copy(node_pos).astype(settings.precision)

    # Declare empty arrays
    pixel_pos = np.zeros((2, ref.n_pixels), dtype=settings.precision)
    dnod_x = np.zeros(mesh.n_nodes * 2)

    image_filtered = nd.spline_filter(
        img, order=settings.interpolation_order).transpose()

    for it in range(settings.maxit):

        # Find nodal positions within ROI
        np.dot(node_pos, ref.Nref_stack, out=pixel_pos)

        # Find pixel values for current coordinates. Use edge values if out of bounds.
        Ic = nd.map_coordinates(image_filtered,
                                pixel_pos,
                                order=settings.interpolation_order,
                                prefilter=False,
                                mode="nearest")

        # Calculate position increment as (B^T B)^-1 * (B^T*dIk) "Least squares solution"
        dnod = np.dot(ref.K, ref.I0_stack - Ic)

        # Add increment to nodal positions
        node_pos[0, :] += dnod[:mesh.n_nodes]
        node_pos[1, :] += dnod[mesh.n_nodes:]

        dnod_x += dnod

        # Check for convergence
        if np.max(np.abs(dnod)) < settings.tol:
            logger.info('Frame converged in %s iterations', it)
            return np.array(
                (dnod_x[:mesh.n_nodes], dnod_x[mesh.n_nodes:])), Ic, True

        # Reset array values
    logger.info("Frame did not converge. Largest increment was %f pixels" %
                np.max(dnod))
    return np.array((dnod_x[:mesh.n_nodes], dnod_x[mesh.n_nodes:])), Ic, False
Example #40
0
def summarise(image, *, spacing=1, using_height=False):
    """Compute statistics for every disjoint skeleton in `image`.

    **Note: this function is deprecated. Prefer** :func:`.summarize`.

    Parameters
    ----------
    image : array, shape (M, N, ..., P)
        N-dimensional array, where nonzero entries correspond to an
        object's single-pixel-wide skeleton. If the image is of type 'float',
        the values are taken to be the height at that pixel, which is used
        to compute the skeleton distances.
    spacing : float, or array-like of float, shape `(skel.ndim,)`
        A value indicating the distance between adjacent pixels. This can
        either be a single value if the data has the same resolution along
        all axes, or it can be an array of the same shape as `skel` to
        indicate spacing along each axis.
    using_height : bool, optional
        If `True`, the pixel value at each point of the skeleton will be
        considered to be a height measurement, and this height will be
        incorporated into skeleton branch lengths, endpoint coordinates,
        and euclidean distances. Used for analysis of atomic force
        microscopy (AFM) images.

    Returns
    -------
    df : pandas DataFrame
        A data frame summarising the statistics of the skeletons in
        `image`.
    """
    ndim = image.ndim
    spacing = np.ones(ndim, dtype=float) * spacing
    g, coords_img, degrees = skeleton_to_csgraph(image,
                                                 spacing=spacing,
                                                 value_is_height=using_height)
    num_skeletons, skeleton_ids = csgraph.connected_components(g,
                                                               directed=False)
    if np.issubdtype(image.dtype, np.float_) and not using_height:
        pixel_values = ndi.map_coordinates(image, coords_img.T, order=3)
        value_columns = ['mean pixel value']
        value_column_types = [float]
    else:
        pixel_values = None
        value_columns = []
        value_column_types = []
    stats = branch_statistics(g, pixel_values)
    indices0 = stats[:, 0].astype(int)
    indices1 = stats[:, 1].astype(int)
    coords_img0 = coords_img[indices0]
    coords_img1 = coords_img[indices1]
    coords_real0 = coords_img0 * spacing
    coords_real1 = coords_img1 * spacing
    if using_height:
        height_coords0 = ndi.map_coordinates(image, coords_img0.T, order=3)
        coords_real0 = np.column_stack((height_coords0, coords_real0))
        height_coords1 = ndi.map_coordinates(image, coords_img1.T, order=3)
        coords_real1 = np.column_stack((height_coords1, coords_real1))
    distances = np.sqrt(np.sum((coords_real0 - coords_real1)**2, axis=1))
    skeleton_id = skeleton_ids[stats[:, 0].astype(int)]
    table = np.column_stack((skeleton_id, stats, coords_img0, coords_img1,
                             coords_real0, coords_real1, distances))
    height_ndim = ndim if not using_height else (ndim + 1)
    columns = ([
        'skeleton-id', 'node-id-0', 'node-id-1', 'branch-distance',
        'branch-type'
    ] + value_columns + ['image-coord-src-%i' % i for i in range(ndim)] +
               ['image-coord-dst-%i' % i for i in range(ndim)] +
               ['coord-src-%i' % i for i in range(height_ndim)] +
               ['coord-dst-%i' % i
                for i in range(height_ndim)] + ['euclidean-distance'])
    column_types = ([int, int, int, float, int] + value_column_types +
                    2 * ndim * [int] + 2 * height_ndim * [float] + [float])
    data_dict = {
        col: dat.astype(dtype)
        for col, dat, dtype in zip(columns, table.T, column_types)
    }
    df = pd.DataFrame(data_dict)
    return df
final_map[ind] = 0  # do this so I can FFT it
uv = NP.fft.fftshift(NP.fft.fft2(NP.fft.fftshift(final_map.copy())))

#load previously calculated LWA PSF and convolve
with open('/data2/beards/instr_data/lwa_uv_psf.pickle') as f:
    lwa_uv_psf, gridu, gridv = pickle.load(f)
du = gridu[0, 1] - gridu[0, 0]
dv = gridv[1, 0] - gridv[0, 0]
# interpolate to GSM defined grid
gridu_gsm, gridv_gsm = NP.meshgrid(
    0.5 * (NP.arange(uv.shape[1]) - uv.shape[1] / 2),
    0.5 * (NP.arange(uv.shape[0]) - uv.shape[0] / 2))
# map_coordinates uses pixel coordinates... need to remap
ucoords = (gridu_gsm - gridu.min()) / du
vcoords = (gridv_gsm - gridv.min()) / dv
psf_matched = ndimage.map_coordinates(lwa_uv_psf, [ucoords, vcoords])
psf_image = NP.fft.fftshift(NP.real(NP.fft.ifft2(
    NP.fft.fftshift(psf_matched))))
norm_factor = NP.sum(psf_image[where(
    abs(psf_image) > 0.05 * psf_image.max())])  # normalize the PSF
psf_matched = psf_matched / norm_factor

uv_convolved = psf_matched * uv

final_map = NP.fft.fftshift(
    NP.real(NP.fft.ifft2(NP.fft.fftshift(uv_convolved))))
final_map[ind] = -inf  # reset to -inf to plot it as white

clf()
imshow(final_map,
       aspect='equal',
def cal_trans_data(pc_dict, cnt=-1):
    posfile = pc_dict[0]
    pointcloud = pc_dict[1]
    pointcloud = np.hstack([pointcloud, np.ones((pointcloud.shape[0], 1))])

    imgpos = {}
    with open(posfile) as imgpos_file:
        for line in imgpos_file:
            pos = [x for x in line.split(' ')]
            for i in range(len(pos) - 2):
                pos[i + 1] = float(pos[i + 1])
            imgpos[pos[0]] = np.reshape(np.array(pos[1:-1]), [4, 4])

    #translate pointcloud to image coordinate
    pointcloud = np.dot(np.linalg.inv(imgpos["stereo_centre"]), pointcloud.T)
    pointcloud = np.dot(G_CAMERA_POSESOURCE, pointcloud)
    uv = CAMERA_MODEL.project(pointcloud, [1280, 960])

    #print(CAMERA_MODEL.bilinear_lut[:, 1::-1].shape)
    lut = CAMERA_MODEL.bilinear_lut[:, 1::-1].T.reshape((2, 960, 1280))
    lut = np.swapaxes(lut, 2, 1)
    u = map_coordinates(lut[0, :, :], uv, order=1)
    v = map_coordinates(lut[1, :, :], uv, order=1)
    uv = np.array([u, v])

    zero0 = np.where(uv[1, :] == 0)
    zero1 = np.where(uv[0, :] == 0)
    zero_01 = np.intersect1d(zero0, zero1)
    nozero = np.setdiff1d(np.arange(4096), zero_01)
    uv = np.delete(uv, zero_01.tolist(), axis=1)
    #print(max(uv[0,:]),max(uv[1,:]))

    if cnt == 0:
        uv_show = uv / 4
        plt.scatter(np.ravel(uv_show[1, :]),
                    np.ravel(uv_show[0, :]),
                    s=5,
                    edgecolors='none',
                    cmap='jet')
        plt.xlim(0, 320)
        plt.ylim(240, 0)
        plt.xticks([])
        plt.yticks([])
        plt.savefig("test.png")
        plt.cla()

    transform_matrix = np.zeros([80 * 4096, 1])
    u = np.floor(uv[0, :] / 120)
    v = np.floor(uv[1, :] / 128)
    row = u * 10 + v
    #print(min(u),min(v),min(row))
    #print(max(u),max(v),max(row))

    row1 = (row * 4096 + nozero).astype(int).tolist()
    transform_matrix[row1] = 1
    transform_matrix = transform_matrix.reshape([80, 4096])
    '''
	aa = np.sum(transform_matrix,1).reshape([8,10])
	print(np.sum(aa))
	plt.figure(2)
	plt.imshow(aa)	
	plt.show()
	input()
	exit()
	'''

    return transform_matrix
Example #43
0
def resample(moving,
             transform=None,
             reference=None,
             mov_voxel_coords=False,
             ref_voxel_coords=False,
             dtype=None,
             interp_order=INTERP_ORDER):
    """ Resample `movimg` into voxel space of `reference` using `transform`

    Apply a transformation to the image considered as 'moving' to
    bring it into the same grid as a given `reference` image.  The
    transformation usually maps world space in `reference` to world space in
    `movimg`, but can also be a voxel to voxel mapping (see parameters below).

    This function uses scipy.ndimage except for the case `interp_order==3`,
    where a fast cubic spline implementation is used.

    Parameters
    ----------
    moving: nipy-like image
      Image to be resampled.
    transform: transform object or None
      Represents a transform that goes from the `reference` image to
      the `moving` image. None means an identity transform. Otherwise,
      it should have either an `apply` method, or an `as_affine`
      method. By default, `transform` maps between the output (world)
      space of `reference` and the output (world) space of `moving`.
      If `mov_voxel_coords` is True, maps to the *voxel* space of
      `moving` and if `ref_vox_coords` is True, maps from the *voxel*
      space of `reference`.
    reference : None or nipy-like image or tuple, optional
      The reference image defines the image dimensions and xyz affine
      to which to resample. It can be input as a nipy-like image or as
      a tuple (shape, affine). If None, use `movimg` to define these.
    mov_voxel_coords : boolean, optional
      True if the transform maps to voxel coordinates, False if it
      maps to world coordinates.
    ref_voxel_coords : boolean, optional
      True if the transform maps from voxel coordinates, False if it
      maps from world coordinates.
    interp_order: int, optional
      Spline interpolation order, defaults to 3.

    Returns
    -------
    aligned_img : Image
        Image resliced to `reference` with reference-to-movimg transform
        `transform`
    """
    # Function assumes xyz_affine for inputs
    moving = as_xyz_image(moving)
    mov_aff = xyz_affine(moving)
    if reference == None:
        reference = moving
    if isinstance(reference, (tuple, list)):
        ref_shape, ref_aff = reference
    else:
        # Expecting image. Must be an image that can make an xyz_affine
        reference = as_xyz_image(reference)
        ref_shape = reference.shape
        ref_aff = xyz_affine(reference)
    if not len(ref_shape) == 3 or not ref_aff.shape == (4, 4):
        raise ValueError('Input image should be 3D')
    data = moving.get_data()
    if dtype == None:
        dtype = data.dtype

    # Assume identity transform by default
    if transform == None:
        transform = Affine()

    # Case: affine transform
    if hasattr(transform, 'as_affine'):
        Tv = transform.as_affine()
        if not ref_voxel_coords:
            Tv = np.dot(Tv, ref_aff)
        if not mov_voxel_coords:
            Tv = np.dot(inverse_affine(mov_aff), Tv)
        if interp_order == 3:
            output = _cspline_resample3d(data, ref_shape, Tv, dtype=dtype)
            output = output.astype(dtype)
        else:
            output = np.zeros(ref_shape, dtype=dtype)
            affine_transform(data,
                             Tv[0:3, 0:3],
                             offset=Tv[0:3, 3],
                             order=interp_order,
                             cval=0,
                             output_shape=ref_shape,
                             output=output)

    # Case: non-affine transform
    else:
        Tv = transform
        if not ref_voxel_coords:
            Tv = Tv.compose(Affine(ref_aff))
        if not mov_voxel_coords:
            Tv = Affine(inverse_affine(mov_aff)).compose(Tv)
        coords = np.indices(ref_shape).transpose((1, 2, 3, 0))
        coords = np.reshape(coords, (np.prod(ref_shape), 3))
        coords = Tv.apply(coords).T
        if interp_order == 3:
            cbspline = _cspline_transform(data)
            output = np.zeros(ref_shape, dtype='double')
            output = _cspline_sample3d(output, cbspline, *coords)
            output = output.astype(dtype)
        else:
            output = map_coordinates(data,
                                     coords,
                                     order=interp_order,
                                     cval=0,
                                     output=dtype)

    return make_xyz_image(output, ref_aff, 'scanner')
Example #44
0
    def profile_line(img,
                     src,
                     dst,
                     axes,
                     linewidth=1,
                     order=1,
                     mode='constant',
                     cval=0.0):
        """Return the intensity profile of an image measured along a scan line.
        Parameters
        ----------
        img : numeric array, shape (M, N[, C])
            The image, either grayscale (2D array) or multichannel
            (3D array, where the final axis contains the channel
            information).
        src : 2-tuple of numeric scalar (float or int)
            The start point of the scan line.
        dst : 2-tuple of numeric scalar (float or int)
            The end point of the scan line.
        linewidth : int, optional
            Width of the scan, perpendicular to the line
        order : int in {0, 1, 2, 3, 4, 5}, optional
            The order of the spline interpolation to compute image values at
            non-integer coordinates. 0 means nearest-neighbor interpolation.
        mode : string, one of {'constant', 'nearest', 'reflect', 'wrap'},
                optional
            How to compute any values falling outside of the image.
        cval : float, optional
            If `mode` is 'constant', what constant value to use outside the
            image.
        Returns
        -------
        return_value : array
            The intensity profile along the scan line. The length of the
            profile is the ceil of the computed length of the scan line.
        Examples
        --------
        >>> x = np.array([[1, 1, 1, 2, 2, 2]])
        >>> img = np.vstack([np.zeros_like(x), x, x, x, np.zeros_like(x)])
        >>> img
        array([[0, 0, 0, 0, 0, 0],
               [1, 1, 1, 2, 2, 2],
               [1, 1, 1, 2, 2, 2],
               [1, 1, 1, 2, 2, 2],
               [0, 0, 0, 0, 0, 0]])
        >>> profile_line(img, (2, 1), (2, 4))
        array([ 1.,  1.,  2.,  2.])
        Notes
        -----
        The destination point is included in the profile, in contrast to
        standard numpy indexing.
        """

        import scipy.ndimage as nd
        p0 = ((src[0] - axes[0].offset) / axes[0].scale,
              (src[1] - axes[1].offset) / axes[1].scale)
        p1 = ((dst[0] - axes[0].offset) / axes[0].scale,
              (dst[1] - axes[1].offset) / axes[1].scale)
        perp_lines = Line2DROI._line_profile_coordinates(p0,
                                                         p1,
                                                         linewidth=linewidth)
        if img.ndim > 2:
            idx = [ax.index_in_array for ax in axes]
            if idx[0] < idx[1]:
                img = np.rollaxis(img, idx[0], 0)
                img = np.rollaxis(img, idx[1], 1)
            else:
                img = np.rollaxis(img, idx[1], 0)
                img = np.rollaxis(img, idx[0], 0)
            orig_shape = img.shape
            img = np.reshape(img,
                             orig_shape[0:2] + (np.product(orig_shape[2:]), ))
            pixels = [
                nd.map_coordinates(img[..., i].T,
                                   perp_lines,
                                   order=order,
                                   mode=mode,
                                   cval=cval) for i in range(img.shape[2])
            ]
            i0 = min(axes[0].index_in_array, axes[1].index_in_array)
            pixels = np.transpose(np.asarray(pixels), (1, 2, 0))
            intensities = pixels.mean(axis=1)
            intensities = np.rollaxis(
                np.reshape(intensities,
                           intensities.shape[0:1] + orig_shape[2:]), 0, i0 + 1)
        else:
            pixels = nd.map_coordinates(img,
                                        perp_lines,
                                        order=order,
                                        mode=mode,
                                        cval=cval)
            intensities = pixels.mean(axis=1)

        return intensities
Example #45
0
    def handle_interaction(self, pixel_data):
        '''Run a UI that gets an angle from the user'''
        import wx

        if pixel_data.ndim == 2:
            # make a color matrix for consistency
            pixel_data = np.dstack((pixel_data, pixel_data, pixel_data))
        pd_min = np.min(pixel_data)
        pd_max = np.max(pixel_data)
        if pd_min == pd_max:
            pixel_data[:, :, :] = 0
        else:
            pixel_data = ((pixel_data - pd_min) * 255.0 / (pd_max - pd_min))
        #
        # Make a 100 x 100 image so it's manageable
        #
        isize = 200
        i, j, k = np.mgrid[0:isize, 0:int(isize * pixel_data.shape[1] /
                                          pixel_data.shape[0]),
                           0:3].astype(float)
        i *= float(pixel_data.shape[0]) / float(isize)
        j *= float(pixel_data.shape[0]) / float(isize)
        pixel_data = scind.map_coordinates(pixel_data, (i, j, k))
        #
        # Make a dialog box that contains the image
        #
        dialog = wx.Dialog(None, title="Rotate image")
        sizer = wx.BoxSizer(wx.VERTICAL)
        dialog.SetSizer(sizer)
        sizer.Add(
            wx.StaticText(dialog,
                          label="Drag image to rotate, hit OK to continue"), 0,
            wx.ALIGN_CENTER_HORIZONTAL)
        canvas = wx.StaticBitmap(dialog)
        canvas.SetDoubleBuffered(True)
        canvas.BackgroundColour = wx.Colour(0, 0, 0, wx.ALPHA_TRANSPARENT)
        sizer.Add(
            canvas, 0,
            wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5)
        angle = [0]
        angle_text = wx.StaticText(dialog, label="Angle: %d" % angle[0])
        sizer.Add(angle_text, 0, wx.ALIGN_CENTER_HORIZONTAL)

        def imshow():
            angle_text.Label = "Angle: %d" % int(angle[0])
            angle_text.Refresh()
            my_angle = -angle[0] * np.pi / 180.0
            transform = np.array([[np.cos(my_angle), -np.sin(my_angle)],
                                  [np.sin(my_angle),
                                   np.cos(my_angle)]])
            # Make it rotate about the center
            offset = affine_offset(pixel_data.shape, transform)
            x = np.dstack((scind.affine_transform(pixel_data[:, :, 0],
                                                  transform,
                                                  offset,
                                                  order=0),
                           scind.affine_transform(pixel_data[:, :, 1],
                                                  transform,
                                                  offset,
                                                  order=0),
                           scind.affine_transform(pixel_data[:, :, 2],
                                                  transform,
                                                  offset,
                                                  order=0)))
            buff = x.astype(np.uint8).tostring()
            bitmap = wx.BitmapFromBuffer(x.shape[1], x.shape[0], buff)
            canvas.SetBitmap(bitmap)

        imshow()
        #
        # Install handlers for mouse down, mouse move and mouse up
        #
        dragging = [False]
        initial_angle = [0]
        hand_cursor = wx.StockCursor(wx.CURSOR_HAND)
        arrow_cursor = wx.StockCursor(wx.CURSOR_ARROW)

        def get_angle(event):
            center = np.array(canvas.Size) / 2
            point = np.array(event.GetPositionTuple())
            offset = point - center
            return -np.arctan2(offset[1], offset[0]) * 180.0 / np.pi

        def on_mouse_down(event):
            canvas.Cursor = hand_cursor
            dragging[0] = True
            initial_angle[0] = get_angle(event) - angle[0]
            canvas.CaptureMouse()

        wx.EVT_LEFT_DOWN(canvas, on_mouse_down)

        def on_mouse_up(event):
            if dragging[0]:
                canvas.ReleaseMouse()
                dragging[0] = False
                canvas.Cursor = arrow_cursor

        wx.EVT_LEFT_UP(canvas, on_mouse_up)

        def on_mouse_lost(event):
            dragging[0] = False
            canvas.Cursor = arrow_cursor

        wx.EVT_MOUSE_CAPTURE_LOST(canvas, on_mouse_lost)

        def on_mouse_move(event):
            if dragging[0]:
                angle[0] = get_angle(event) - initial_angle[0]
                imshow()
                canvas.Refresh(eraseBackground=False)

        wx.EVT_MOTION(canvas, on_mouse_move)
        #
        # Put the OK and Cancel buttons on the bottom
        #
        btnsizer = wx.StdDialogButtonSizer()

        btn = wx.Button(dialog, wx.ID_OK)
        btn.SetDefault()
        btnsizer.AddButton(btn)

        btn = wx.Button(dialog, wx.ID_CANCEL)
        btnsizer.AddButton(btn)
        btnsizer.Realize()

        sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
        dialog.Fit()
        result = dialog.ShowModal()
        dialog.Destroy()
        if result == wx.ID_OK:
            return angle[0]
        raise ValueError("Canceled by user in FlipAndRotate")
                                  x_step = x_res_deg, x_shift = x0_conv,
                                  y_step = y_res_deg, y_shift = y0_conv,
                                  z_step = 1, z_shift = 1.5)
s1_xyz = np.array(s1_xyz)
s1_xyz[0:2,:] = s1_xyz[0:2,:] - clip_len

comp_list = ['zz', 'xy', 'xz', 'yz', 'xx', 'yy']

print 'interpolating stresses to fault points'
for comp in comp_list:
    print 'doing {}'.format(comp)
    stress_vol = (stress_db['{}_MPa'.format(comp)][clip_len:clip_dist,
                                                   clip_len:clip_dist,:])

    s1['{}_stress'.format(comp)] = nd.map_coordinates( stress_vol,
                                    [s1_xyz[1], s1_xyz[0], s1_xyz[2]],
                                    order=interp_order)

del stress_vol                                    
stress_db.close()

print 'calculating shear and normal stresses'
s1['tau_dd_1'] = 0.
s1['tau_ss_1'] = 0.
s1['sig_nn_1'] = 0.
 
s1['tau_dd_2'] = 0.
s1['tau_ss_2'] = 0.
s1['sig_nn_2'] = 0.

stress_tens_xyz = {}
Example #47
0
def get_pars_fr(wavst,
                flxst,
                model_patht='../../data/COELHO2014/',
                npools=4,
                fixG=1.0):
    for order in range(len(flxst)):
        flxst[order] = clean_strong_lines(wavst[order], flxst[order], mode=1)

    t0 = time.time()

    global wavs, flxs
    global model_path

    wavs, flxs = wavst.copy(), flxst.copy()
    model_path = model_patht

    gt = np.array([6000, 7000, 8000, 9000, 10000])
    gg = np.array([2.5, 3.0, 3.5, 4.0, 4.5])
    if fixG != -1:
        gg = np.array([fixG])
    gz = np.array([-1, -0.5, 0.0, 0.2])
    gr = np.array([10., 50., 100., 150., 200., 250., 300.])

    #"""
    tr = np.tile(gr, len(gt) * len(gg) * len(gz))
    tg = np.repeat(np.tile(gg, len(gt)), len(gr) * len(gz))
    tz = np.repeat(np.tile(gz, len(gt) * len(gg)), len(gr))
    tt = np.repeat(gt, len(gg) * len(gr) * len(gz))
    tot = np.vstack((tt, tg, tz, tr)).T

    #for pars in tot:
    #       pars = [8000,4.0,-0.5,40.0]
    #       print pars, multiccf(pars)

    p = Pool(npools)
    vals = np.array((p.map(multiccf, list(tot))))
    p.terminate()
    I = np.argmin(vals)
    best_vals = tot[I]
    bt, bg, bz, br = best_vals[0], best_vals[1], best_vals[2], best_vals[3]
    #"""
    t1 = time.time()
    print(bt, bg, bz, br, (t1 - t0) / 60., 'mins')

    #bt,bg,bz,br = 7000.,4.5, 0.2, 100.0
    gt = np.arange(bt - 1000, bt + 1001, 250)
    I = np.where((gt >= 6000) & (gt <= 10000))[0]
    gt = gt[I]
    gr = np.arange(br - 60., br + 61., 20.)
    I = np.where(gr >= 10)[0]
    gr = gr[I]

    tr = np.tile(gr, len(gt) * len(gg) * len(gz))
    tg = np.repeat(np.tile(gg, len(gt)), len(gr) * len(gz))
    tz = np.repeat(np.tile(gz, len(gt) * len(gg)), len(gr))
    tt = np.repeat(gt, len(gg) * len(gr) * len(gz))
    tot = np.vstack((tt, tg, tz, tr)).T

    p = Pool(npools)
    vals = np.array((p.map(multiccf, list(tot))))
    p.terminate()
    I = np.argmin(vals)
    best_vals = tot[I]
    bt, bg, bz, br = best_vals[0], best_vals[1], best_vals[2], best_vals[3]
    t2 = time.time()
    print(bt, bg, bz, br, (t2 - t1) / 60., 'mins')
    #np.savetxt('temp_grid.txt',vals)

    if fixG == -1:
        grid = np.reshape(vals, (len(gt), len(gg), len(gz), len(gr)))
        tckt = interpolate.splrep(gt, np.arange(len(gt)), k=1)
        tckg = interpolate.splrep(gg, np.arange(len(gg)), k=1)
        tckz = interpolate.splrep(gz, np.arange(len(gz)), k=1)
        tckr = interpolate.splrep(gr, np.arange(len(gr)), k=1)

        itckt = interpolate.splrep(np.arange(len(gt)), gt, k=1)
        itckg = interpolate.splrep(np.arange(len(gg)), gg, k=1)
        itckz = interpolate.splrep(np.arange(len(gz)), gz, k=1)
        itckr = interpolate.splrep(np.arange(len(gr)), gr, k=1)

        st = np.arange(gt[0], gt[-1] + 1, 10.)
        sg = np.arange(gg[0], gg[-1] + 0.01, 0.1)
        sz = np.arange(gz[0], gz[-1] + 0.01, 0.1)
        sr = np.arange(gr[0], gr[-1] + 1., 5.)

        st = interpolate.splev(st, tckt)
        sg = interpolate.splev(sg, tckg)
        sz = interpolate.splev(sz, tckz)
        sr = interpolate.splev(sr, tckr)

        tr2 = np.tile(sr, len(st) * len(sg) * len(sz))
        tg2 = np.repeat(np.tile(sg, len(st)), len(sr) * len(sz))
        tz2 = np.repeat(np.tile(sz, len(st) * len(sg)), len(sr))
        tt2 = np.repeat(st, len(sg) * len(sr) * len(sz))
        tot2 = np.vstack((tt2, tg2, tz2, tr2))

        zi = ndimage.map_coordinates(grid, tot2, order=3, mode='nearest')
        I = np.argmin(zi)
        minval = tot2[:, I]

        mint = interpolate.splev(minval[0], itckt)
        ming = interpolate.splev(minval[1], itckg)
        minz = interpolate.splev(minval[2], itckz)
        minr = interpolate.splev(minval[3], itckr)

    else:
        grid = np.reshape(vals, (len(gt), len(gz), len(gr)))
        tckt = interpolate.splrep(gt, np.arange(len(gt)), k=1)
        tckz = interpolate.splrep(gz, np.arange(len(gz)), k=1)
        tckr = interpolate.splrep(gr, np.arange(len(gr)), k=1)

        itckt = interpolate.splrep(np.arange(len(gt)), gt, k=1)
        itckz = interpolate.splrep(np.arange(len(gz)), gz, k=1)
        itckr = interpolate.splrep(np.arange(len(gr)), gr, k=1)

        st = np.arange(gt[0], gt[-1] + 1, 10.)
        sz = np.arange(gz[0], gz[-1] + 0.01, 0.1)
        sr = np.arange(gr[0], gr[-1] + 1., 5.)

        st = interpolate.splev(st, tckt)
        sz = interpolate.splev(sz, tckz)
        sr = interpolate.splev(sr, tckr)

        tr2 = np.tile(sr, len(st) * len(sz))
        tz2 = np.repeat(np.tile(sz, len(st)), len(sr))
        tt2 = np.repeat(st, len(sr) * len(sz))
        tot2 = np.vstack((tt2, tz2, tr2))

        zi = ndimage.map_coordinates(grid, tot2, order=3, mode='nearest')
        I = np.argmin(zi)
        minval = tot2[:, I]

        mint = interpolate.splev(minval[0], itckt)
        ming = fixG
        minz = interpolate.splev(minval[1], itckz)
        minr = interpolate.splev(minval[2], itckr)

    #d = {'grid':grid, 'zi':zi, 'tot2':tot2, 'gt':gt, 'gg':gg, 'gz':gz, 'gr':gr}
    #pickle.dump(d,open('temp_dict.pkl'))

    return float(mint), float(ming), float(minz), float(minr)
Example #48
0
def _correct_mesh_orientation(volume,
                              actual_verts,
                              faces,
                              spacing=(1., 1., 1.),
                              gradient_direction='descent'):
    """
    Correct orientations of mesh faces.

    Parameters
    ----------
    volume : (M, N, P) array of doubles
        Input data volume to find isosurfaces. Will be cast to `np.float64`.
    actual_verts : (F, 3, 3) array of floats
        Array with (face, vertex, coords) index coordinates.
    faces : (F, 3) array of ints
        List of length-3 lists of integers, referencing vertex coordinates as
        provided in `verts`.
    spacing : length-3 tuple of floats
        Voxel spacing in spatial dimensions corresponding to numpy array
        indexing dimensions (M, N, P) as in `volume`.
    gradient_direction : string
        Controls if the mesh was generated from an isosurface with gradient
        descent toward objects of interest (the default), or the opposite.
        The two options are:
        * descent : Object was greater than exterior
        * ascent : Exterior was greater than object

    Returns
    -------
    faces_corrected (F, 3) array of ints
        Corrected list of faces referencing vertex coordinates in `verts`.

    Notes
    -----
    Certain applications and mesh processing algorithms require all faces
    to be oriented in a consistent way. Generally, this means a normal vector
    points "out" of the meshed shapes. This algorithm corrects the output from
    `skimage.measure.marching_cubes_classic` by flipping the orientation of
    mis-oriented faces.

    Because marching cubes could be used to find isosurfaces either on
    gradient descent (where the desired object has greater values than the
    exterior) or ascent (where the desired object has lower values than the
    exterior), the ``gradient_direction`` kwarg allows the user to inform this
    algorithm which is correct. If the resulting mesh appears to be oriented
    completely incorrectly, try changing this option.

    The arguments expected by this function are the exact outputs from
    `skimage.measure.marching_cubes_classic` except `actual_verts`, which is an
    uncorrected version of the fancy indexing operation `verts[faces]`.
    Only `faces` is corrected and returned as the vertices do not change,
    only the order in which they are referenced.

    This algorithm assumes ``faces`` provided are exclusively triangles.

    See Also
    --------
    skimage.measure.marching_cubes_classic
    skimage.measure.mesh_surface_area

    """
    # Calculate gradient of `volume`, then interpolate to vertices in `verts`
    grad_x, grad_y, grad_z = np.gradient(volume)

    a = actual_verts[:, 0, :] - actual_verts[:, 1, :]
    b = actual_verts[:, 0, :] - actual_verts[:, 2, :]

    # Find triangle centroids
    centroids = (actual_verts.sum(axis=1) / 3.).T

    del actual_verts

    # Interpolate face centroids into each gradient axis
    grad_centroids_x = ndi.map_coordinates(grad_x, centroids)
    grad_centroids_y = ndi.map_coordinates(grad_y, centroids)
    grad_centroids_z = ndi.map_coordinates(grad_z, centroids)

    # Combine and normalize interpolated gradients
    grad_centroids = np.c_[grad_centroids_x, grad_centroids_y,
                           grad_centroids_z]
    grad_centroids = (grad_centroids /
                      (np.sum(grad_centroids**2, axis=1)**0.5)[:, np.newaxis])

    # Find normal vectors for each face via cross product
    crosses = np.cross(a, b)
    crosses = crosses / (np.sum(crosses**2, axis=1)**(0.5))[:, np.newaxis]

    # Take dot product
    dotproducts = (grad_centroids * crosses).sum(axis=1)

    # Find mis-oriented faces
    if 'descent' in gradient_direction:
        # Faces with incorrect orientations have dot product < 0
        indices = (dotproducts < 0).nonzero()[0]
    elif 'ascent' in gradient_direction:
        # Faces with incorrection orientation have dot product > 0
        indices = (dotproducts > 0).nonzero()[0]
    else:
        raise ValueError("Incorrect input %s in `gradient_direction`, see "
                         "docstring." % (gradient_direction))

    # Correct orientation and return, without modifying original data
    faces_corrected = faces.copy()
    faces_corrected[indices] = faces_corrected[indices, ::-1]

    return faces_corrected
Example #49
0
def test_warp_coords_example():
    image = astronaut().astype(np.float32)
    assert 3 == image.shape[2]
    tform = SimilarityTransform(translation=(0, -10))
    coords = warp_coords(tform, (30, 30, 3))
    map_coordinates(image[:, :, 0], coords[:2])
Example #50
0
    def make(self, key):
        from scipy.spatial import distance
        import bisect

        # Set some params
        min_distance = 40
        max_height = 100

        # Create list of units
        units = []  # stands for matched units
        for field in stack.Registration & key:
            # Edge case: when two channels are registered, we don't know which to use
            if len(stack.Registration.proj(ignore='scan_channel') & field) > 1:
                msg = ('More than one channel was registered for {animal_id}-'
                       '{scan_session}-{scan_idx} field {field}'.format(**field))
                raise PipelineException(msg)

            # Get registered grid
            field_key = {'animal_id': field['animal_id'],
                         'session': field['scan_session'], 'scan_idx': field['scan_idx'],
                         'field': field['field']}
            um_per_px = (meso.ScanInfo.Field & field_key).microns_per_pixel
            grid = (stack.Registration & field).get_grid(type='affine', desired_res=um_per_px)

            # Create cell objects
            for channel_key in (meso.ScanSet & field_key &
                                {'segmentation_method': key['segmentation_method']}):  # *
                field_masks = meso.ScanSet.Unit & channel_key
                unit_keys, xs, ys = (meso.ScanSet.UnitInfo & field_masks).fetch('KEY',
                        'px_x', 'px_y')
                px_coords = np.stack([ys, xs])
                xs, ys, zs = [ndimage.map_coordinates(grid[..., i], px_coords, order=1)
                              for i in range(3)]
                units += [StackMatching.MatchedUnit(*args, key_hash(channel_key)) for args in
                          zip(unit_keys, xs, ys, zs)]
            # * Separating masks per channel allows masks in diff channels to be matched
        print(len(units), 'initial units')

        def find_close_units(centroid, centroids, min_distance):
            """ Finds centroids that are closer than min_distance to centroid. """
            dists = distance.cdist(np.expand_dims(centroid, 0), centroids)
            indices = np.flatnonzero(dists < min_distance)
            return indices, dists[0, indices]

        def is_valid(unit1, unit2, max_height):
            """ Checks that units belong to different fields and that the resulting unit
            would not be bigger than 20 microns."""
            different_fields = len(set(unit1.plane_ids) & set(unit2.plane_ids)) == 0
            acceptable_height = (max(unit1.zs + unit2.zs) - min(
                unit1.zs + unit2.zs)) < max_height
            return different_fields and acceptable_height

        # Create distance matrix
        # For memory efficiency we use an adjacency list with only the units at less than 10 microns
        centroids = np.stack([u.centroid for u in units])
        distance_list = []  # list of triples (distance, unit1, unit2)
        for i in range(len(units)):
            indices, distances = find_close_units(centroids[i], centroids[i + 1:],
                                                  min_distance)
            for dist, j in zip(distances, i + 1 + indices):
                if is_valid(units[i], units[j], max_height):
                    bisect.insort(distance_list, (dist, units[i], units[j]))
        print(len(distance_list), 'possible pairings')

        # Join units
        while (len(distance_list) > 0):
            # Get next pair of units
            d, unit1, unit2 = distance_list.pop(0)

            # Remove them from lists
            units.remove(unit1)
            units.remove(unit2)
            f = lambda x: (unit1 not in x[1:]) and (unit2 not in x[1:])
            distance_list = list(filter(f, distance_list))

            # Join them
            unit1.join_with(unit2)

            # Recalculate distances
            centroids = [u.centroid for u in units]
            indices, distances = find_close_units(unit1.centroid, centroids, min_distance)
            for dist, j in zip(distances, indices):
                if is_valid(unit1, units[j], max_height):
                    bisect.insort(distance_list, (d, unit1, units[j]))

            # Insert new unit
            units.append(unit1)
        print(len(units), 'number of final masks')

        # Insert
        self.insert1({**key, 'min_distance': min_distance, 'max_height': max_height})
        for munit_id, munit in zip(itertools.count(start=1), units):
            new_unit = {**key, 'munit_id': munit_id, 'munit_x': munit.centroid[0],
                        'munit_y': munit.centroid[1], 'munit_z': munit.centroid[2]}
            self.Unit().insert1(new_unit)
            for subunit_key in munit.keys:
                new_match = {**key, 'munit_id': munit_id, **subunit_key,
                             'scan_session': subunit_key['session']}
                self.Match().insert1(new_match, ignore_extra_fields=True)
Example #51
0
def properties2d(image, resolution=None, verbose=1):
    label_img = measure.label(np.transpose(image))
    regions = measure.regionprops(label_img)
    areas = [r.area for r in regions]
    ix = np.argsort(areas)
    if len(regions) != 0:
        sc_region = regions[ix[-1]]
        try:
            ratio_minor_major = sc_region.minor_axis_length / sc_region.major_axis_length
        except ZeroDivisionError:
            ratio_minor_major = 0.0

        area = sc_region.area
        diameter = sc_region.equivalent_diameter
        major_l = sc_region.major_axis_length
        minor_l = sc_region.minor_axis_length
        if resolution is not None:
            area *= resolution[0] * resolution[1]
            # TODO: compute length depending on resolution. Here it assume the patch has the same X and Y resolution
            diameter *= resolution[0]
            major_l *= resolution[0]
            minor_l *= resolution[0]

            size_grid = 8.0 / resolution[0]  # assuming the maximum spinal cord radius is 8 mm
        else:
            size_grid = int(2.4 * sc_region.major_axis_length)

        """
        import matplotlib.pyplot as plt
        plt.imshow(label_img)
        plt.text(1, 1, sc_region.orientation, color='white')
        plt.show()
        """

        y0, x0 = sc_region.centroid
        orientation = sc_region.orientation

        resolution_grid = 0.25
        x_grid, y_grid = np.mgrid[-size_grid:size_grid:resolution_grid, -size_grid:size_grid:resolution_grid]
        coordinates_grid = np.array(zip(x_grid.ravel(), y_grid.ravel()))
        coordinates_grid_image = np.array([[x0 + math.cos(orientation) * coordinates_grid[i, 0], y0 - math.sin(orientation) * coordinates_grid[i, 1]] for i in range(coordinates_grid.shape[0])])

        from scipy.ndimage import map_coordinates
        square = map_coordinates(image, coordinates_grid_image.T, output=np.float32, order=0, mode='constant', cval=0.0)
        square_image = square.reshape((len(x_grid), len(x_grid)))

        size_half = square_image.shape[1] / 2
        left_image = square_image[:, :size_half]
        right_image = np.fliplr(square_image[:, size_half:])

        dice_symmetry = np.sum(left_image[right_image == 1]) * 2.0 / (np.sum(left_image) + np.sum(right_image))

        """
        import matplotlib.pyplot as plt
        plt.imshow(square_image)
        plt.text(3, 3, dice, color='white')
        plt.show()
        """

        sc_properties = {'area': area,
                         'bbox': sc_region.bbox,
                         'centroid': sc_region.centroid,
                         'eccentricity': sc_region.eccentricity,
                         'equivalent_diameter': diameter,
                         'euler_number': sc_region.euler_number,
                         'inertia_tensor': sc_region.inertia_tensor,
                         'inertia_tensor_eigvals': sc_region.inertia_tensor_eigvals,
                         'minor_axis_length': minor_l,
                         'major_axis_length': major_l,
                         'moments': sc_region.moments,
                         'moments_central': sc_region.moments_central,
                         'orientation': sc_region.orientation * 180.0 / math.pi,
                         'perimeter': sc_region.perimeter,
                         'ratio_minor_major': ratio_minor_major,
                         'solidity': sc_region.solidity,  # convexity measure
                         'symmetry': dice_symmetry
                         }
    else:
        sc_properties = None

    return sc_properties
Example #52
0
 def process_frames(self, data):
     mat_corrected = np.reshape(
         map_coordinates(data[0], self.indices, order=1, mode='reflect'),
         (self.height, self.width))
     return mat_corrected[self.crop:self.height - self.crop,
                          self.crop:self.width - self.crop]
def regular_prior_interpolator(old_prior, new_prior, filter_size=None):

    old_nodes_z, old_nodes_y, old_nodes_x = calculate_node_spacing(
        old_prior[:, 1:4])

    # Figure out spacing from first two nodes positions
    if len(old_nodes_z) == 1:
        old_z_spacing = 1
    else:
        old_z_spacing = old_nodes_z[1] - old_nodes_z[0]
    old_y_spacing = old_nodes_y[1] - old_nodes_y[0]
    old_x_spacing = old_nodes_x[1] - old_nodes_x[0]
    try:
        logging.log.info(
            "regular_prior_interpolator: Prior node spacing (z,y,x) is:\t{:.0f} {:.0f} {:.0f}"
            .format(old_z_spacing, old_y_spacing, old_x_spacing))
    except:
        print "regular_prior_interpolator: Prior node spacing (z,y,x) is:\t{:.0f} {:.0f} {:.0f}".format(
            old_z_spacing, old_y_spacing, old_x_spacing)

    # Reshape prior field to a three dimensional arrays
    z_field = old_prior[:, 4].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
    y_field = old_prior[:, 5].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
    x_field = old_prior[:, 6].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
    z_rot = old_prior[:, 7].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
    y_rot = old_prior[:, 8].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
    x_rot = old_prior[:, 9].reshape(
        (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))

    #Replacing the Inf in the prior with the median of finte values around (in None replace with zero)
    inf_positions = numpy.where(numpy.isinf(x_field))

    for inf_number in range(len(inf_positions[0])):
        z = inf_positions[0][inf_number]
        y = inf_positions[1][inf_number]
        x = inf_positions[2][inf_number]

        try:
            z_field[z, y, x] = numpy.media(z_field[where(
                numpy.isfinite(z_filed[z - 1:z + 2, y - 1:y + 2,
                                       z - 1:x + 2]))])
            y_field[z, y, x] = numpy.media(y_field[where(
                numpy.isfinite(y_filed[z - 1:z + 2, y - 1:y + 2,
                                       z - 1:x + 2]))])
            x_field[z, y, x] = numpy.media(x_field[where(
                numpy.isfinite(x_filed[z - 1:z + 2, y - 1:y + 2,
                                       z - 1:x + 2]))])
        except:
            pass

    z_field[numpy.where(numpy.isinf(z_field))] = 0
    y_field[numpy.where(numpy.isinf(y_field))] = 0
    x_field[numpy.where(numpy.isinf(x_field))] = 0

    if filter_size is not None and filter_size > 0:
        try:
            logging.log.info(
                "regular_prior_interpolator: Smoothing kinematics field")
        except:
            print "regular_prior_interpolator: Smoothing kinematics field"
        # 2014-07-18 -- Edward Ando
        # Changing the median filter for the field from scipy.ndimage.filters.median_filter
        #   (which seems to propagate NaNs) to our own, home-developed median filter:
        z_field = median_filter_nans(numpy.squeeze(z_field),
                                     filter_size).reshape(
                                         (len(old_nodes_z), len(old_nodes_y),
                                          len(old_nodes_x)))
        y_field = median_filter_nans(numpy.squeeze(y_field),
                                     filter_size).reshape(
                                         (len(old_nodes_z), len(old_nodes_y),
                                          len(old_nodes_x)))
        x_field = median_filter_nans(numpy.squeeze(x_field),
                                     filter_size).reshape(
                                         (len(old_nodes_z), len(old_nodes_y),
                                          len(old_nodes_x)))
        z_rot = median_filter_nans(numpy.squeeze(z_rot), filter_size).reshape(
            (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
        y_rot = median_filter_nans(numpy.squeeze(y_rot), filter_size).reshape(
            (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))
        x_rot = median_filter_nans(numpy.squeeze(x_rot), filter_size).reshape(
            (len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)))

    # Normalise coordinates of new prior nodes positions
    #   (subtract position of old top corner and divide by old node spacing), to get into the SHAPE => SIZE
    #   of the old prior for interpolation.
    new_prior_normalised = numpy.zeros((new_prior.shape[0], 3))
    new_prior_normalised[:, 0] = (new_prior[:, 1] -
                                  old_nodes_z[0]) / old_z_spacing
    new_prior_normalised[:, 1] = (new_prior[:, 2] -
                                  old_nodes_y[0]) / old_y_spacing
    new_prior_normalised[:, 2] = (new_prior[:, 3] -
                                  old_nodes_x[0]) / old_x_spacing

    # Interpolate each prior field for each new node
    # 2014-07-23 Edward Andò:
    #   map_coordinates does not handle NaNs, and cannot handle masked arrays for the moment,
    #   ...so we will seek and destroy the NaNs in the displacement fields before doing a map_coordinates
    # This means for each NaN position, we will grow a window until we get a real value,
    #   and then we'll use that window do make a median to fill in our NaN measurement.

    # Figure out NaN positions... (they will be in the same place for every field)
    nan_positions = numpy.where(numpy.isnan(x_field))

    # A mask of ones and zeros in order to quickly work out the smallest window size for the filter
    mask = numpy.ones((len(old_nodes_z), len(old_nodes_y), len(old_nodes_x)),
                      dtype='bool')
    mask[nan_positions] = False

    number_of_nans = len(nan_positions[0])

    if number_of_nans > 0:
        try:
            logging.log.warn(
                "regular_prior_interpolator(): {:.0f} NaNs detected, replacing them with a median value of the smallest window that touches real data"
                .format(number_of_nans))
        except:
            print "regular_prior_interpolator(): {:.0f} NaNs detected, replacing them with a median value of the smallest window that touches real data".format(
                number_of_nans)

    for nan_number in range(number_of_nans):
        z = nan_positions[0][nan_number]
        y = nan_positions[1][nan_number]
        x = nan_positions[2][nan_number]

        z_top = z
        y_top = y
        x_top = x

        z_bot = z
        y_bot = y
        x_bot = x

        window_sum = 0
        step = 0

        while window_sum == 0:
            step += 1
            #print "step = ", step
            if z_top >= 0: z_top -= step
            if y_top >= 0: y_top -= step
            if x_top >= 0: x_top -= step

            if z_bot <= len(old_nodes_z): z_bot += step
            if y_bot <= len(old_nodes_y): y_bot += step
            if x_bot <= len(old_nodes_x): x_bot += step

            window_sum = numpy.sum(   mask[ z_top:z_bot+1,\
                                            y_top:y_bot+1,\
                                            x_top:x_bot+1   ] )

            local_mask = numpy.where( mask[ z_top:z_bot+1,\
                                            y_top:y_bot+1,\
                                            x_top:x_bot+1   ] )

        z_field[ z, y, x ] = numpy.median( z_field[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )
        y_field[ z, y, x ] = numpy.median( y_field[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )
        x_field[ z, y, x ] = numpy.median( x_field[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )

        z_rot[ z, y, x ] = numpy.median( z_rot[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )
        y_rot[ z, y, x ] = numpy.median( y_rot[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )
        x_rot[ z, y, x ] = numpy.median( x_rot[ z_top:z_bot+1,\
                                                    y_top:y_bot+1,\
                                                    x_top:x_bot+1   ][local_mask] )

    new_z_field = ndimage.map_coordinates(z_field,
                                          new_prior_normalised.T,
                                          order=1,
                                          mode='nearest',
                                          prefilter=False).T
    new_y_field = ndimage.map_coordinates(y_field,
                                          new_prior_normalised.T,
                                          order=1,
                                          mode='nearest').T
    new_x_field = ndimage.map_coordinates(x_field,
                                          new_prior_normalised.T,
                                          order=1,
                                          mode='nearest').T

    new_z_rot = ndimage.map_coordinates(z_rot,
                                        new_prior_normalised.T,
                                        order=1,
                                        mode='nearest',
                                        prefilter=False).T
    new_y_rot = ndimage.map_coordinates(y_rot,
                                        new_prior_normalised.T,
                                        order=1,
                                        mode='nearest').T
    new_x_rot = ndimage.map_coordinates(x_rot,
                                        new_prior_normalised.T,
                                        order=1,
                                        mode='nearest').T

    # Update and return new prior guesses array
    new_prior[:, 4] = new_z_field
    new_prior[:, 5] = new_y_field
    new_prior[:, 6] = new_x_field
    new_prior[:, 7] = new_z_rot
    new_prior[:, 8] = new_y_rot
    new_prior[:, 9] = new_x_rot

    return new_prior
Example #54
0
def simulate_slice(
    map_r,
    psize,
    n_particles,
    N_crop=None,
    snr=0.1,
    do_snr=True,
    do_ctf=True,
    df_min=15000,
    df_max=20000,
    df_diff_min=100,
    df_diff_max=500,
    df_ang_min=0,
    df_ang_max=360,
    kv=300,
    cs=2.0,
    ac=0.1,
    phase=0,
    bf=0,
    do_log=True,
    random_seed=0,
):
    """
    Simulates a particle stack from a 3D voxelized array using the Fourier slice theorem (projection assumption).

    Parameters
    ----------
        map_r : numpy.ndarray, shape (N,N,N)
            3D real space map of shape
        psize : float
            pixel size in Angstroms
        n_particles: int
            number of particles to simulate
        N_crop : in
            number of pixels to crop to
        snr : float
            signal to noise ratio. defined as the std(signal) / std(noise). the signal is the projections (with ctf if that's included)
        do_snr : bool
            add nosie when True
        do_ctf : bool
            add ctf when True
        df_min : float
            defocus range min
        df_max : float
            defocus range max
        df_diff_min : float
            defocus difference range min
        df_diff_max : float
            defocus difference range max
        df_ang_min : float
            angle of astigmatism range min
        df_ang_max : float
            angle of astigmatism range max
        kv : float
            voltate of microscope in kilo electron volts (typicaly 120, 200, 300 on electron microscopes)
        cs : float
            spherical aberation constant in mm
        ac : float
            amplitude contrast
        phase : float
            ctf phase
        bf : float
            B-factor for CTF envelope. no envelope when 0
        do_log : bool
            log progress if True. TODO: add to logger instead of print
        random_seed : int
            random_seed for np.random.seed(random_seed)

    Returns
    -------
        projs_r: numpy.ndarray, shape (n_particles,N_crop,N_crop)
            particle stack of simulated projections
        projs_r_noise : numpy.ndarray, shape (n_particles,N_crop,N_crop)
            particle stack of simulated projections with noise
        meta_data_df : pandas.DataFrame
            metadata of simulated particles, including sampled ctf
    """
    assert len(map_r.shape) == 3
    assert np.unique(map_r.shape).size == 1
    N = map_r.shape[0]
    assert N % 2 == 0, "even pixel length"

    map_f = fourier.do_fft(map_r, d=3)

    N = map_f.shape[0]
    xyz = coords.coords_n_by_d(np.arange(-N // 2, N // 2), d=3)
    idx_z0 = xyz[:, -1] == 0
    xy0 = xyz[idx_z0]

    if random_seed is not None:
        np.random.seed(random_seed)
    rots, qs = coords.uniform_rotations(n_particles)

    projs_f = np.zeros((n_particles, N, N), dtype=np.complex64)
    for idx in range(n_particles):
        if do_log and idx % max(1, (n_particles // 10)) == 0:
            print(idx)
        rot = rots[idx, :, :]
        xy0_rot = rot.dot(xy0.T).T
        projs_f[idx] = (
            map_coordinates(map_f.real, xy0_rot.T + N // 2, order=1).astype(
                np.complex64
            )
            + 1j
            * map_coordinates(map_f.imag, xy0_rot.T + N // 2, order=1).astype(
                np.complex64
            )
        ).reshape(
            N, N
        )  # important to keep order=1 for speed. linear is good enough

    if do_ctf:
        ctfs, df1s, df2s, df_ang_deg = transfer.random_ctfs(
            N=N,
            psize=psize,
            n_particles=n_particles,
            df_min=df_min,
            df_max=df_max,
            df_diff_min=df_diff_min,
            df_diff_max=df_diff_max,
            df_ang_min=df_ang_min,
            df_ang_max=df_ang_max,
            kv=kv,
            cs=cs,
            ac=ac,
            phase=phase,
            bf=bf,
            do_log=do_log,
        )

        projs_f *= ctfs

    if N_crop is not None:
        i, f = N // 2 - N_crop // 2, N // 2 + N_crop // 2
        projs_r = fourier.do_ifft(projs_f[:, i:f, i:f], d=2, batch=True)
        psize *= N / N_crop
    else:
        projs_r = fourier.do_ifft(projs_f, d=2, batch=True)

    if do_snr:
        signal = np.std(projs_r)
        noise = signal / snr
        projs_r_noise = np.random.normal(loc=projs_r, scale=noise)
    else:
        projs_r_noise = projs_r

    meta_data_d = {
        "N": N_crop,
        "psize": psize,
        "snr": snr,
        "rotation_quaternion": [np.array2string(q) for q in qs],
    }
    if do_ctf:
        meta_data_d.update(
            {
                "df1_A": df1s,
                "df2_A": df2s,
                "df_ang_deg": df_ang_deg,
                "kev": kv,
                "ac": ac,
                "cs_mm": cs,
            }
        )
    meta_data_df = pd.DataFrame(meta_data_d)

    return (projs_r, projs_r_noise, meta_data_df)
Example #55
0
def mobius_fast_interpolation(image,
                              M,
                              mode,
                              output_height=None,
                              output_width=None,
                              user_defined=False,
                              start_points=None,
                              end_points=None):

    image = np.array(image)
    original_image = image
    height = image.shape[0]
    width = image.shape[1]

    # User can pick output size
    if output_height == None:
        output_height = height
    if output_width == None:
        output_width = width
    if user_defined == True:
        # Method one
        # You pick starting and ending point
        a, b, c, d, original_points, new_points = getabcd_1fix(
            height, width, start_points, end_points)
    else:
        # Method two
        # Randomly generated starting the ending point
        a, b, c, d, original_points, new_points = madmissable_abcd(
            M, height, width)
    e = [complex(0, 0)] * height * width
    z = np.array(e).reshape(height, width)
    for i in range(0, height):
        for j in range(0, width):
            z[i, j] = complex(i, j)
    i = np.array(list(range(0, height)) * width).reshape(width, height).T
    j = np.array(list(range(0, width)) * height).reshape(height, width)

    r = ones((output_height, output_width, 3), dtype=uint8) * 255 * 0
    w = (a * z + b) / (c * z + d)
    first = real(w) * 1
    second = imag(w) * 1
    first = first.astype(int)
    second = second.astype(int)

    f1 = first >= 0
    f2 = first < output_height
    f = f1 & f2
    s1 = second >= 0
    s2 = second < output_width
    s = s1 & s2

    combined = s & f

    r[first[combined], second[combined], :] = image[i[combined],
                                                    j[combined], :]

    r_interpolated = r.copy()
    u = [True] * output_height * output_width
    canvas = np.array(u).reshape(output_height, output_width)
    canvas[first[combined], second[combined]] = False
    converted_empty_index = np.where(canvas == True)
    converted_first = converted_empty_index[0]
    converted_second = converted_empty_index[1]

    new = converted_first.astype(complex)
    new.imag = converted_second

    ori = (d * new - b) / (-c * new + a)

    p = np.hstack([ori.real, ori.real, ori.real])
    k = np.hstack([ori.imag, ori.imag, ori.imag])
    zero = np.zeros_like(ori.real)
    one = np.ones_like(ori.real)
    two = np.ones_like(ori.real) * 2
    third = np.hstack([zero, one, two])
    number_of_interpolated_point = len(one)
    e = number_of_interpolated_point
    interpolated_value_unfinished = map_coordinates(image, [p, k, third],
                                                    order=1,
                                                    mode=mode,
                                                    cval=0)
    t = interpolated_value_unfinished

    interpolated_value = np.stack([t[0:e], t[e:2 * e], t[2 * e:]]).T

    r_interpolated[converted_first, converted_second, :] = interpolated_value

    new_image = Image.fromarray(r_interpolated)
    uninterpolated_image = Image.fromarray(r)

    figure(figsize=(15, 10))
    subplot(1, 3, 1)
    title('Original')
    imshow(original_image)
    subplot(1, 3, 2)
    title('No interpolation')
    imshow(r)
    subplot(1, 3, 3)
    # figure()
    title('With interpolation')
    imshow(r_interpolated)

    return new_image, uninterpolated_image
#samples used
sampleNumber = (p - 1) * mu
print("Samples used:", sampleNumber, ", proportion:",
      sampleNumber / float(N * N))

#-------------
# Measure finite slice
from scipy import ndimage

print("Measuring slices")
drtSpace = np.zeros((p + 1, p), floatType)
for lines, mValues in zip(subsetsLines, subsetsMValues):
    for i, line in enumerate(lines):
        u, v = line
        sliceReal = ndimage.map_coordinates(np.real(fftLenaShifted), [u, v])
        sliceImag = ndimage.map_coordinates(np.imag(fftLenaShifted), [u, v])
        slice = sliceReal + 1j * sliceImag
        #    print("slice", i, ":", slice)
        finiteProjection = fftpack.ifft(
            slice)  # recover projection using slice theorem
        drtSpace[mValues[i], :] = finiteProjection
#print("drtSpace:", drtSpace)


#-------------------------------
#define MLEM
def ossirt_expand_complex(iterations,
                          t,
                          p,
                          g_j,
Example #57
0
    def __call__(self, m):
        if self.random_state.uniform() < self.execution_probability:
            if (m.ndim == 3):
                dz = gaussian_filter(self.random_state.randn(*m.shape),
                                     self.sigma,
                                     mode="constant",
                                     cval=0) * self.alpha
                dy = gaussian_filter(self.random_state.randn(*m.shape),
                                     self.sigma,
                                     mode="constant",
                                     cval=0) * self.alpha
                dx = gaussian_filter(self.random_state.randn(*m.shape),
                                     self.sigma,
                                     mode="constant",
                                     cval=0) * self.alpha

                z_dim, y_dim, x_dim = m.shape
                z, y, x = np.meshgrid(np.arange(z_dim),
                                      np.arange(y_dim),
                                      np.arange(x_dim),
                                      indexing='ij')
                indices = z + dz, y + dy, x + dx
                return map_coordinates(m,
                                       indices,
                                       order=self.spline_order,
                                       mode='reflect')

            else:
                z_dim, y_dim, x_dim = m[0, :, :, :].shape

                dz = gaussian_filter(
                    self.random_state.randn(*m[0, :, :, :].shape),
                    self.sigma,
                    mode="constant",
                    cval=0) * self.alpha
                dy = gaussian_filter(
                    self.random_state.randn(*m[0, :, :, :].shape),
                    self.sigma,
                    mode="constant",
                    cval=0) * self.alpha
                dx = gaussian_filter(
                    self.random_state.randn(*m[0, :, :, :].shape),
                    self.sigma,
                    mode="constant",
                    cval=0) * self.alpha

                z, y, x = np.meshgrid(np.arange(z_dim),
                                      np.arange(y_dim),
                                      np.arange(x_dim),
                                      indexing='ij')

                indices = z + dz, y + dy, x + dx

                channels = [
                    map_coordinates(m[c, :, :, :],
                                    indices,
                                    order=self.spline_order,
                                    mode='reflect') for c in range(m.shape[0])
                ]
                m = np.stack(channels, axis=0)

                # save_as_h5('ElasticDeformation', m)

        return m
Example #58
0
    def _single_session_fit(self, vols, quality=None, affine_correction=None):
        """
        Realigns volumes (vols) from a single session.

        Parameters
        ----------
        vols: list of `nibabel.Nifti1Image` objects
            the volumes to realign

        quality: float, optional (default None)
            to override instance value

        affine_correction: 2D array of shape (4, 4), optional (default None)
            affine transformation to be applied to vols before realignment
            (this is useful in multi-session realignment)

        Returns
        -------
        2D array of shape (n_scans, len(self.lkp)
            the estimated realignment parameters

        """

        # sanitize input
        if quality is None:
            quality = self.quality

        if affine_correction is None:
            affine_correction = np.eye(4)

        # load first vol
        vols = load_vols(vols)
        n_scans = len(vols)
        vol_0 = vols[0]

        # single vol ?
        if n_scans < 2:
            return np.array([get_initial_motion_params()])

        # affine correction
        vol_0 = nibabel.Nifti1Image(
            vol_0.get_data(), np.dot(affine_correction, vol_0.get_affine()))

        # voxel dimensions on the working grid
        skip = np.sqrt(np.sum(vol_0.get_affine()[:3, :3]**2,
                              axis=0))**(-1) * self.sep

        # build working grid
        dim = vol_0.shape
        x1, x2, x3 = np.mgrid[0:dim[0] - .5 - 1:skip[0],
                              0:dim[1] - .5 - 1:skip[1],
                              0:dim[2] - .5 - 1:skip[2]].reshape((3, -1))

        # smooth 0th volume to absorb noise before differentiating
        sref_vol = smooth_image(vol_0, self.fwhm).get_data()

        # resample the smoothed reference volume unto doped working grid
        G = ndimage.map_coordinates(
            sref_vol,
            [x1, x2, x3],
            order=self.interp,
            mode='wrap',
        ).reshape(x1.shape)

        # compute gradient of reference volume
        Gx, Gy, Gz = np.gradient(sref_vol)

        # resample gradient unto working grid
        Gx = ndimage.map_coordinates(
            Gx,
            [x1, x2, x3],
            order=self.interp,
            mode='wrap',
        ).reshape(x1.shape)
        Gy = ndimage.map_coordinates(
            Gy,
            [x1, x2, x3],
            order=self.interp,
            mode='wrap',
        ).reshape(x1.shape)
        Gz = ndimage.map_coordinates(
            Gz,
            [x1, x2, x3],
            order=self.interp,
            mode='wrap',
        ).reshape(x1.shape)

        # compute rate of change of chi2 w.r.t. parameters
        A0 = _compute_rate_of_change_of_chisq(vol_0.get_affine(), [x1, x2, x3],
                                              [Gx, Gy, Gz],
                                              lkp=self.lkp)

        # compute intercept vector for LSPs
        b = G.ravel()

        # garbage-collect unused local variables
        del sref_vol, Gx, Gy, Gz

        # Remove voxels that contribute very little to the final estimate.
        # It's essentially sufficient to remove voxels that contribute the
        # least to the determinant of the inverse convariance matrix
        # (i.e of the precision matrix)
        if n_scans > 2:
            self._log(("Eliminating unimportant voxels (target quality: %s)"
                       "...") % quality)
            alpha = np.vstack((A0.T, b)).T
            alpha = np.dot(alpha.T, alpha)
            det0 = scipy.linalg.det(alpha)
            det1 = det0  # det1 / det0 is a precision measure
            n_eliminated_voxels = 0
            while det1 / det0 > quality:
                # determine unimportant voxels to eliminate
                dets = np.ndarray(A0.shape[0])
                for t in range(A0.shape[0]):
                    tmp = np.hstack((A0[t, ...], b[t])).reshape(
                        (1, A0.shape[1] + 1))
                    dets[t] = scipy.linalg.det(alpha - np.dot(tmp.T, tmp))
                msk = np.argsort(det1 - dets)
                msk = msk[:np.round(len(dets) / 10.)]

                # eliminate unimportant voxels
                n_eliminated_voxels += len(msk)
                self._log("\tEliminating %i voxels (current quality = %s)..." %
                          (len(msk), det1 / det0))
                A0 = np.delete(A0, msk, axis=0)
                b = np.delete(b, msk, axis=0)
                x1 = np.delete(x1, msk, axis=0)
                x2 = np.delete(x2, msk, axis=0)
                x3 = np.delete(x3, msk, axis=0)

                # updates for next iteration
                alpha = np.vstack((A0.T, b)).T
                alpha = np.dot(alpha.T, alpha)
                det1 = scipy.linalg.det(alpha)
            self._log("...done; eliminated %i voxels.\r\n" %
                      n_eliminated_voxels)

        # register the volumes to the reference volume
        self._log("Registering volumes to reference ( = volume 1)...")
        rp = np.ndarray((n_scans, 12))
        rp[0,
           ...] = get_initial_motion_params()  # don't mov the reference image
        for t in range(1, n_scans):
            self._log("\tRegistering volume %i/%i..." % (t + 1, n_scans))

            # load volume t
            vol = vols[t]
            vol = nibabel.Nifti1Image(
                vol.get_data(), np.dot(affine_correction, vol.get_affine()))

            # initialize final rp for this vol
            rp[t, ...] = get_initial_motion_params()

            # smooth volume t
            V = smooth_image(vol, self.fwhm).get_data()

            # intialize motion params for this vol
            rp[t, ...] = get_initial_motion_params()

            # global optical flow problem with affine motion model: run
            # Gauss-Newton iterated LS (this loop should normally converge
            # after about as few as 5 iterations)
            dim = np.hstack((V.shape, [1, 1]))
            dim = dim[:3]
            ss = INFINITY
            countdown = -1
            iteration = None
            for iteration in range(self.n_iterations):
                # starting point
                q = get_initial_motion_params()

                # pass from volume t's grid to that of the reference
                # volume (0)
                y1, y2, y3 = transform_coords(np.zeros(6), vol_0.get_affine(),
                                              vol.get_affine(), [x1, x2, x3])

                # sanity mask: some voxels might have fallen out of business;
                # and zap'em
                msk = np.nonzero((y1 >= 0) & (y1 < dim[0]) & (y2 >= 0)
                                 & (y2 < dim[1]) & (y3 >= 0)
                                 & (y3 < dim[2]))[0]

                # if mask is too small, then we're screwed anyway
                if len(msk) < 32:
                    raise RuntimeError(
                        ("Almost all voxels have fallen out of the FOV. Only "
                         "%i voxels survived. Registration can't work." %
                         len(msk)))

                # warp: resample volume t on this new grid
                F = ndimage.map_coordinates(V, [y1[msk], y2[msk], y3[msk]],
                                            order=self.interp,
                                            mode='wrap')

                # formulate and solve LS problem for updating p
                A = A0[msk, ...].copy()
                b1 = b[msk].copy()
                sc = np.sum(b1) / np.sum(F)
                b1 -= F * sc
                q_update = scipy.linalg.lstsq(np.dot(A.T, A), np.dot(A.T,
                                                                     b1))[0]

                # update q
                q[self.lkp] += q_update
                rp[t, self.lkp] -= q_update

                # update affine matrix for volume t by applying M_q
                vol = apply_realignment_to_vol(vol, q)

                # compute convergence criterion variables
                pss = ss
                ss = np.sum(b1**2) / len(b1)

                # compute relative gain over last iteration
                relative_gain = np.abs(
                    (pss - ss) / pss) if np.isfinite(pss) else INFINITY

                # verbose
                token = "\t" + "".join(['%-12.4g ' % z for z in q[self.lkp]])
                token += '|  %.5g' % relative_gain
                self._log(token)

                # check whether we've stopped converging altogether
                if relative_gain < self.tol and countdown == -1:
                    countdown = 2

                # countdown
                if countdown != -1:
                    # converge
                    if countdown == 0:
                        break
                    countdown -= 1

            # what happened ?
            comments = " after %i iterations" % (iteration + 1)
            if iteration + 1 == self.n_iterations:
                comments = "did not coverge" + comments
            else:
                if relative_gain < self.tol:
                    comments = "converged" + comments
                else:
                    comments = "stopped converging" + comments

            self._log("")

        return rp
Example #59
0
def to_worm_frame(images,
                  center_tck,
                  width_tck=None,
                  width_margin=20,
                  sample_distance=None,
                  standard_length=None,
                  standard_width=None,
                  zoom=1,
                  reflect_centerline=False,
                  order=3,
                  dtype=None,
                  **kwargs):
    """Transform images from the lab reference frame to the worm reference frame.

    The width of the output image is defined by the center_tck, which defines
    the length of the worm and thus the width of the image. The height of the
    image can be specified either directly by the sample_distance parameter,
    or can be computed from a width_tck that defines the location of the sides
    of the worm (a fixed width_margin is added so that the image extends a bit
    past the worm).

    The size and shape of the output worm can be standardized to a "unit worm"
    by use of the "standard_length" and "standard_width" parameters; see below.

    Parameters:
        images: single numpy array, or list/tuple/3d array of multiple images to
            be transformed.
        center_tck: centerline spline defining the pose of the worm in the lab
            frame.
        width_tck: width spline defining the distance from centerline to worm
            edges. Optional; uses are as follows: (1) if sample_distance is not
            specified, a width_tck must be specified in order to calculate the
            output image height; (2) if standard_width is specified, a width_tck
            must also be specified to define the transform from this worm's
            width profile to the standardized width profile.
        width_margin: if sample_distance is not specified, width_margin is used
            to define the distance (in image pixels) that the output image will
            extend past the edge of the worm (at its widest). If a zoom is
            specified, note that the margin pixels will be zoomed too.
        sample_distance: number of pixels to sample in each direction
            perpendicular to the centerline. The height of the output image is
            int(round(2 * sample_distance * zoom)).
        standard_length: if not specified, the width of the output image is
            int(round(arc_length)*zoom), where arc_length is the path integral
            along center_tck (i.e. the length from beginning to end). If
            standard_length is specified, then the length of the output image is
            int(round(standard_length*zoom)). The full length of the worm will
            be compressed or expanded as necessary to bring it to the specified
            standard_length.
        standard_width: a width spline specifying the "standardized" width
            profile for the output image. If specified, the actual width profile
            must also be provided as width_tck. In this case, the output image
            will be compressed/expanded perpendicular to the centerline as needed
            to make the actual widths conform to the standard width profile.
        zoom: zoom factor, can be any real number > 0.
        reflect_centerline: reflect worm over its centerline.
        order: image interpolation order (0 = nearest neighbor, 1 = linear,
            3 = cubic). Cubic is best, but slowest.
        dtype: if None, use dtype of input images for output. Otherwise, use
            the specified dtype.
        kwargs: additional keyword arguments to pass to ndimage.map_coordinates.

    Returns: single image or list of images (depending on whether the input is a
        single image or list/tuple/3d array).
    """

    assert width_tck is not None or sample_distance is not None
    if standard_width is not None:
        assert width_tck is not None

    if standard_length is None:
        length = spline_geometry.arc_length(center_tck)
    else:
        length = standard_length
    x_samples = int(round(length * zoom))

    if sample_distance is None:
        wtck = standard_width if standard_width is not None else width_tck
        sample_distance = interpolate.spline_interpolate(
            wtck, num_points=x_samples).max() + width_margin
    y_samples = int(round(2 * sample_distance * zoom))

    # basic plan:
    # 1) get the centerline and the perpendiculars to it.
    # 2) define positions along each perpendicular at which to sample the input images.
    # (This is the "offset_distances" variable).

    x = numpy.arange(
        x_samples,
        dtype=float) + 0.5  # want to sample at pixel centers, not edges
    y = numpy.ones_like(x) * (y_samples / 2)
    worm_frame_centerline = numpy.transpose([x, y])
    centerline, perpendiculars, spline_y = _lab_centerline_and_perps(
        worm_frame_centerline, (x_samples, y_samples), center_tck, width_tck,
        standard_width, zoom)
    # if the far edges of the top and bottom pixels are sample_distance from the centerline,
    # figure out the position of the *centers* of the top and bottom of the pixels.
    # i.e. correct for fencepost error
    sample_max = sample_distance * (y_samples - 1) / y_samples
    offsets = numpy.linspace(
        -sample_max, sample_max, y_samples
    )  # distances along each perpendicular across the width of the sample swath
    offset_distances = numpy.multiply.outer(
        perpendiculars.T, offsets)  # shape = (2, x_samples, y_samples)
    centerline = centerline.T[:, :, numpy.
                              newaxis]  # from shape = (x_samples, 2) to shape = (2, x_samples, 1)
    if reflect_centerline:
        offset_distances *= -1
    sample_coordinates = centerline + offset_distances  # shape = (2, x_samples, y_samples)

    unpack_list = False
    if isinstance(images, numpy.ndarray):
        if images.ndim == 3:
            images = list(images)
        else:
            unpack_list = True
            images = [images]
    # subtract half-pixel offset because map_coordinates treats (0,0) as the middle
    # of the top-left pixel, not the far corner of that pixel.
    worm_frame = [
        ndimage.map_coordinates(image,
                                sample_coordinates -
                                _HALF_PX_OFFSET.reshape(2, 1, 1),
                                order=order,
                                output=dtype,
                                **kwargs) for image in images
    ]
    if unpack_list:
        worm_frame = worm_frame[0]
    return worm_frame
Example #60
0
def undrift(imgstack, optflow):
    t_dim, c_dim, y_dim, x_dim = imgstack.shape

    TILE_SIZE = 16

    checker_board = numpy.zeros((t_dim, y_dim, x_dim), numpy.uint8)
    block_1 = numpy.ones((TILE_SIZE, TILE_SIZE), numpy.uint8)
    block_2 = numpy.ones((TILE_SIZE, TILE_SIZE), numpy.uint8)

    block_1 *= 32
    block_2 *= 128
    block = numpy.c_[numpy.r_[block_1, block_2], numpy.r_[block_2, block_1]]

    checker_board[0, :(y_dim // (2 * TILE_SIZE)) * 2 *
                  TILE_SIZE, :(x_dim // (2 * TILE_SIZE)) * 2 *
                  TILE_SIZE] = numpy.tile(block,
                                          (y_dim // (2 * TILE_SIZE), x_dim //
                                           (2 * TILE_SIZE)))

    grid_visu = numpy.zeros((t_dim, c_dim + 1, y_dim, x_dim), numpy.uint8)
    grid_visu[:, :c_dim, :, :] = imgstack
    grid_visu[:, -1, :, :] = checker_board

    result = numpy.zeros((t_dim, c_dim, y_dim, x_dim), imgstack.dtype)

    def shift_func_forward(xy, of):
        return (
            xy[0] - of[1, xy[0].astype(numpy.int32).clip(0, y_dim - 1),
                       xy[1].astype(numpy.int32).clip(0, x_dim - 1)],
            xy[1] - of[0, xy[0].astype(numpy.int32).clip(0, y_dim - 1),
                       xy[1].astype(numpy.int32).clip(0, x_dim - 1)],
        )

    def shift_func_backward(xy, of):
        return (
            xy[0] + of[1, xy[0].astype(numpy.int32).clip(0, y_dim - 1),
                       xy[1].astype(numpy.int32).clip(0, x_dim - 1)],
            xy[1] + of[0, xy[0].astype(numpy.int32).clip(0, y_dim - 1),
                       xy[1].astype(numpy.int32).clip(0, x_dim - 1)],
        )

    result[0, :c_dim] = imgstack[0, :c_dim]

    xxyy = numpy.meshgrid(numpy.arange(x_dim), numpy.arange(y_dim))[::-1]
    xxyy2 = numpy.meshgrid(numpy.arange(x_dim), numpy.arange(y_dim))[::-1]
    for k in tqdm(range(1, t_dim),
                  desc="{:40s}".format('  -- Un-drift movie')):
        xxyy = shift_func_backward(xxyy, of=optflow[k - 1, ...])
        xxyy2 = shift_func_forward(xxyy2, of=optflow[k - 1, ...])

        for c in range(c_dim):
            img = imgstack[k, c, :, :]

            result[k, c, :, :] = ndi.map_coordinates(img, xxyy)

            # coords_in_input      = shift_func_forward((xx, yy), of=optflow[:k+1, ...].sum(0))
            grid_visu[k,
                      -1, :, :] = ndi.map_coordinates(grid_visu[0, -1, :, :],
                                                      xxyy2)

    return result, grid_visu