def nanFilter(af, kernel=3): """ 3D phase contrast filter often creates 'nan' this filter removes nan by averaging surrounding pixels return af """ af = af.copy() shape = N.array(af.shape) radius = N.subtract(kernel, 1) // 2 box = kernel * af.ndim nan = N.isnan(af) nids = N.array(N.nonzero(nan)).T for nidx in nids: slc = [slice(idx,idx+1) for idx in nidx] slices = [] for dim in range(af.ndim): slc2 = slice(slc[dim].start - radius, slc[dim].stop + radius) while slc2.start < 0: slc2 = slice(slc2.start + 1, slc2.stop) while slc2.stop > shape[dim]: slc2 = slice(slc2.start, slc2.stop -1) slices.append(slc2) val = af[slices] nanlocal = N.isnan(val) ss = N.sum(N.where(nanlocal, 0, val)) / float((box - N.sum(nanlocal))) af[slc] = ss return af
def nanFilter(af, kernel=3): """ 3D phase contrast filter often creates 'nan' this filter removes nan by averaging surrounding pixels return af """ af = af.copy() shape = N.array(af.shape) radius = N.subtract(kernel, 1) // 2 box = kernel * af.ndim nan = N.isnan(af) nids = N.array(N.nonzero(nan)).T for nidx in nids: slc = [slice(idx, idx + 1) for idx in nidx] slices = [] for dim in range(af.ndim): slc2 = slice(slc[dim].start - radius, slc[dim].stop + radius) while slc2.start < 0: slc2 = slice(slc2.start + 1, slc2.stop) while slc2.stop > shape[dim]: slc2 = slice(slc2.start, slc2.stop - 1) slices.append(slc2) val = af[slices] nanlocal = N.isnan(val) ss = N.sum(N.where(nanlocal, 0, val)) / float((box - N.sum(nanlocal))) af[slc] = ss return af
def __init__(self, fns): """ fns """ # input types self.img = load(fns) # copy attributes self.nt = self.img.nt self.nw = self.img.nw self.nz = self.img.nz self.ny = self.img.ny self.nx = self.img.nx self.dtype = self.img.dtype self.hdr = self.img.hdr self.dirname = os.path.dirname(self.img.filename) #path) self.file = self.path = os.path.basename(self.img.filename) #path) self.shape = N.asarray( mrcIO.shapeFromNum(self.hdr.Num, self.nw, self.nt, self.hdr.ImgSequence)) self.ndim = int(self.nz > 1) + int(self.nw > 1) + int(self.nt > 1) + 2 zwt = ['z', 'w', 't'] num = [self.nz, self.nw, self.nt] maxdim = max(num) self.maxaxs = zwt[num.index(maxdim)] # slicing parameter self.ignor_color_axis = False self.sld_axs = 't' # cropping region self.cropbox_l = N.array([0, 0, 0], N.int32) self.cropbox_u = N.array([self.nz, self.ny, self.nx], N.int32) self.setMstUse( False) # this has to be False since original shape cannot be known self.tSlice = 0 self.setIndices(range(self.nw), range(self.nt), range(self.nz), self.hdr.ImgSequence, self.dtype) self.sliceIdx = [self.nz // 2, self.ny // 2, self.nx // 2] self.selectZsecs() # output self.byteorder = '=' self.interporder = imgResample.ORDER # viewer self.vid = None self._rub = None self.vid_single = None # aui self.t = 0 self.w = 0 self.z = self.nz // 2 self.y = self.ny // 2 self.x = self.nx // 2
def apodize(img, napodize=10, doZ=True): """ softens the edges of a singe xy section to reduce edge artifacts and improve the fits return copy of the img """ img = img.copy() img = img.astype(N.float32) # casting rule # determine napodize shape = N.array(img.shape) // 2 napodize = N.where(shape < napodize, shape, napodize) if doZ and img.ndim >= 3 and img.shape[0] > 3: rr = range(-3, 0) else: rr = range(-2, 0) for idx in rr: fact = N.arange(1. / napodize[idx], napodize[idx], 1. / napodize[idx], dtype=N.float32)[:napodize[idx]] for napo in range(napodize[idx]): slc0 = [Ellipsis, slice(napo, napo + 1) ] + [slice(None)] * abs(idx + 1) if not napo: slc1 = [Ellipsis, slice(-(napo + 1), None) ] + [slice(None)] * abs(idx + 1) else: slc1 = [Ellipsis, slice(-(napo + 1), -(napo)) ] + [slice(None)] * abs(idx + 1) img[slc0] *= fact[napo] img[slc1] *= fact[napo] #img[slc0] = img[slc0] * fact[napo] # casting rule #img[slc1] = img[scl1] * fact[napo] return img
def findMaxWithGFit(img, sigma=0.5, win=11): ''' find sub-pixel peaks from input img using n-dimensional Guassian fitting sigma: scaler or [simgaZ,sigmaY..] window: a window where the Guassian fit is performed on return [v, zyx, sigma] ''' vzyx = N.array(U.findMax(img)) ndim = img.ndim try: ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win) except IndexError: # too close to the edge imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:])) sigma = imgFit._scalerToSeq(sigma, ndim) return vzyx[0:1], vzyx[-ndim:], list(sigma) if check == 5 or N.any(ret[2:2 + ndim] > (vzyx[-ndim:] + win)) or N.any( ret[2:2 + ndim] < (vzyx[-ndim:] - win)): imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) sigma = imgFit._scalerToSeq(sigma, ndim) return [vzyx[0:1], vzyx[-ndim:], sigma] #x= (vzyx[0:1] + [vzyx[-ndim:]] + [sigma]) # print x # return x else: v = ret[1] zyx = ret[2:2 + ndim] sigma = ret[2 + ndim:2 + ndim * 2] return [v, zyx, sigma]
def _doBilinear2D(a2d, tyx=(0,0), r=0, mag=1, anismag=1, dyx=(0,0), mr=0, b2d=None): if b2d is None: b2d = N.empty_like(a2d) else: b2d = N.ascontiguousarray(b2d) a2d = a2d.copy() # otherwise, the following code will mess up the input if N.any(dyx[-2:]) or mr: temp = b2d target = a2d U.trans2d(target, temp, (dyx[-1], dyx[-2], mr, 1, 0, 1)) else: temp = a2d target = b2d # rot mag first to make consistent with affine magaxis = 1 # only this axis works if r or mag != 1 or anismag != 1: U.trans2d(temp, target, (0, 0, r, mag, magaxis, anismag)) else: target[:] = temp[:] # then translate tyx2 = N.array(tyx) # copy tyx2[-2:] -= dyx[-2:] if N.any(tyx2[-2:]) or mr: U.trans2d(target, temp, (tyx2[-1], tyx2[-2], -mr, 1, 0, 1)) else: temp[:] = target[:] #a[z] = temp[:] return temp
def mask_gaussianND(arr, zyx, v, sigma=2., ret=None, rot=0, clipZero=True): ''' subtract elliptical gaussian at y,x with peakVal v if ret, return arr, else, arr itself is edited ''' from . import imgGeo zyx = N.asarray(zyx) ndim = arr.ndim shape = N.array(arr.shape) try: if len(sigma) != ndim: raise ValueError('len(sigma) must be the same as len(shape)') else: sigma = N.asarray(sigma) except TypeError:#(TypeError, ValueError): sigma = N.asarray([sigma]*ndim) # prepare small window slc = imgGeo.nearbyRegion(shape, N.floor(zyx), sigma * 10) inds, LD = imgFit.rotateIndicesND(slc, dtype=N.float32, rot=rot) param = (0, v,) + tuple(zyx) + tuple(sigma) sidx = 2 + ndim g = imgFit.yGaussianND(N.asarray(param), inds, sidx).astype(arr.dtype.type) roi = arr[slc] if clipZero: g = N.where(g > roi, roi, g) if ret: e = N.zeros_like(arr) e[slc] = g # this may be faster than copy() return arr - e else: arr[slc] -= g
def apodize(img, napodize=10, doZ=True): """ softens the edges of a singe xy section to reduce edge artifacts and improve the fits return copy of the img """ img = img.copy() img = img.astype(N.float32) # casting rule # determine napodize shape = N.array(img.shape) // 2 napodize = N.where(shape < napodize, shape, napodize) if doZ and img.ndim >= 3 and img.shape[0] > 3: rr = list(range(-3,0)) else: rr = list(range(-2,0)) for idx in rr: fact = N.arange(1./napodize[idx],napodize[idx],1./napodize[idx], dtype=N.float32)[:napodize[idx]] for napo in range(napodize[idx]): slc0 = [Ellipsis,slice(napo, napo+1)] + [slice(None)] * abs(idx+1) if not napo: slc1 = [Ellipsis,slice(-(napo+1),None)] + [slice(None)] * abs(idx+1) else: slc1 = [Ellipsis,slice(-(napo+1),-(napo))] + [slice(None)] * abs(idx+1) img[slc0] *= fact[napo] img[slc1] *= fact[napo] #img[slc0] = img[slc0] * fact[napo] # casting rule #img[slc1] = img[scl1] * fact[napo] return img
def findMaxWithGFit(img, sigma=0.5, win=11): ''' find sub-pixel peaks from input img using n-dimensional Guassian fitting sigma: scaler or [simgaZ,sigmaY..] window: a window where the Guassian fit is performed on return [v, zyx, sigma] ''' vzyx = N.array(U.findMax(img)) ndim = img.ndim try: ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma, win) except IndexError: # too close to the edge imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:])) sigma = imgFit._scalerToSeq(sigma, ndim) return vzyx[0:1], vzyx[-ndim:], list(sigma) if check == 5 or N.any(ret[2:2+ndim] > (vzyx[-ndim:] + win)) or N.any(ret[2:2+ndim] < (vzyx[-ndim:] - win)): imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) sigma = imgFit._scalerToSeq(sigma, ndim) return [vzyx[0:1], vzyx[-ndim:], sigma] #x= (vzyx[0:1] + [vzyx[-ndim:]] + [sigma]) # print x # return x else: v = ret[1] zyx = ret[2:2+ndim] sigma = ret[2+ndim:2+ndim*2] return [v,zyx,sigma]
def centerOfMass(img, yx, window=5): """ find peak by center of mass in a 2D image img: a 2D image array yx: (y,x) in the image window: a window where CM calculation is performed on return yx """ # prepare small image s = N.array([window,window]) c = s/2. yx = N.round_(yx) yx -= c yi, xi = N.indices(s) yi += yx[0] xi += yx[1] cc = img[yi,xi] # calculate center of mass yxi = N.indices(s) yxi *= cc yxi = yxi.T vv = N.sum(yxi, axis=0) vv = N.sum(vv, axis=0) yxs = vv / float(N.sum(cc)) yxs += yx return yxs
def centerOfMass(img, yx, window=5): """ find peak by center of mass in a 2D image img: a 2D image array yx: (y,x) in the image window: a window where CM calculation is performed on return yx """ # prepare small image s = N.array([window, window]) c = s / 2. yx = N.round_(yx) yx -= c yi, xi = N.indices(s) yi += yx[0] xi += yx[1] cc = img[yi, xi] # calculate center of mass yxi = N.indices(s) yxi *= cc yxi = yxi.T vv = N.sum(yxi, axis=0) vv = N.sum(vv, axis=0) yxs = vv / float(N.sum(cc)) yxs += yx return yxs
def cutOutCenter(arr, windowSize, sectWise=None, interpolate=True): """ windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) sectWise: conern only XY of windowSize """ shape = N.array(arr.shape) center = shape / 2. return pointsCutOutND(arr, [center], windowSize, sectWise, interpolate)[0]
def paddingFourier(arr, shape, value=0, interpolate=True): """ arr: assuming origin at 0, rfft product (half x size), up to 3D shape: target shape value: the value to fill in empty part interpolate: shift by interpolation if necessary return array with target shape """ # prepare buffer dtype = arr.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calc and shift shapeS = N.array(arr.shape) shapeL = N.asarray(shape) halfS = shapeS / 2. subpx_shift = halfS % 1 if interpolate and N.sometrue(subpx_shift): arr = U.nd.shift(arr, subpx_shift) halfS = [int(s) for s in halfS] # create empty list for slices nds = arr.ndim - 1 choices = ['slice(halfS[%i])', 'slice(-halfS[%i], None)'] nchoices = len(choices) nds2 = nds**2 slcs = [] for ns in range(nds2): slcs.append([]) for n in range(nchoices * nds): slcs[ns].append( [Ellipsis]) # Ellipsis help to make arbitray number of list # fill the empty list by slice (here I don't know how to use 4D..) for i in range(nds2): for d in range(nds): for x in range(nds): for c, choice in enumerate(choices): if d == 0 and x == 0: idx = x * (nchoices) + c else: # how can I use 4D?? idx = x * (nchoices) + (nchoices - 1) - c exec('content=' + choice % d) slcs[i][idx] += [content] # cutout and paste for slc in slcs: for s in slc: s.append(slice(int(shapeS[-1]))) #print s canvas[s] = arr[s] return canvas
def transformMatrix(rot=0.0, mag=1.0): """ retrn invmat """ rotRadian = N.pi / 180. * rot cosTheta = N.cos(rotRadian) sinTheta = N.sin(rotRadian) affmatrix = N.array([[cosTheta, sinTheta], [-sinTheta, cosTheta]]) * mag invmat = N.linalg.inv(affmatrix) return invmat
def transformMatrix(rot=0.0, mag=1.0): """ retrn invmat """ rotRadian = N.pi / 180. * rot cosTheta = N.cos(rotRadian) sinTheta = N.sin(rotRadian) affmatrix = N.array([ [cosTheta, sinTheta], [-sinTheta, cosTheta] ]) * mag invmat = N.linalg.inv(affmatrix) return invmat
def logpolar_cv(img, center=None, mag=1): des = N.zeros_like(img) if center is None: center = N.divide(img.shape, 2) # cv.fromarray: array can be 2D or 3D only cimg = cv.fromarray(img) cdes = cv.fromarray(des) cv.LogPolar(cimg, cdes, tuple(center), mag)#, cv.CV_WARP_FILL_OUTLIERS) return N.array(cdes)
def logpolar_cv(img, center=None, mag=1): des = N.zeros_like(img) if center is None: center = N.divide(img.shape, 2) # cv.fromarray: array can be 2D or 3D only cimg = cv.fromarray(img) cdes = cv.fromarray(des) cv.LogPolar(cimg, cdes, tuple(center), mag) #, cv.CV_WARP_FILL_OUTLIERS) return N.array(cdes)
def paddingFourier(arr, shape, value=0, interpolate=True): """ arr: assuming origin at 0, rfft product (half x size), up to 3D shape: target shape value: the value to fill in empty part interpolate: shift by interpolation if necessary return array with target shape """ # prepare buffer dtype = arr.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calc and shift shapeS = N.array(arr.shape) shapeL = N.asarray(shape) halfS = shapeS / 2. subpx_shift = halfS % 1 if interpolate and N.sometrue(subpx_shift): arr = U.nd.shift(arr, subpx_shift) halfS = [int(s) for s in halfS] # create empty list for slices nds = arr.ndim - 1 choices = ['slice(halfS[%i])', 'slice(-halfS[%i], None)'] nchoices = len(choices) nds2 = nds**2 slcs = [] for ns in range(nds2): slcs.append([]) for n in range(nchoices*nds): slcs[ns].append([Ellipsis]) # Ellipsis help to make arbitray number of list # fill the empty list by slice (here I don't know how to use 4D..) for i in range(nds2): for d in range(nds): for x in range(nds): for c, choice in enumerate(choices): if d == 0 and x == 0: idx = x*(nchoices) + c else: # how can I use 4D?? idx = x*(nchoices) + (nchoices-1) - c exec('content=' + choice % d) slcs[i][idx] += [content] # cutout and paste for slc in slcs: for s in slc: s.append(slice(int(shapeS[-1]))) #print s canvas[s] = arr[s] return canvas
def _findMaxXcor(c, win, gFit=True, niter=2): if gFit: for i in range(niter): v, zyx, s = findMaxWithGFit(c, win=win + (i * 2)) if v: if N.any(zyx > N.array(c.shape)) or N.any(zyx < 0): vzyx = N.array(U.findMax(c)) #continue v = vzyx[0] zyx = vzyx[-c.ndim:] + 0.5 # pixel center s = 2.5 else: break if not v: v = U.findMax(c)[0] else: vzyx = U.findMax(c) v = vzyx[0] zyx = N.array(vzyx[-c.ndim:]) + 0.5 # pixel center s = 2.5 return v, zyx, s
def _findMaxXcor(c, win, gFit=True, niter=2): if gFit: for i in range(niter): v, zyx, s = findMaxWithGFit(c, win=win+(i*2)) if v: if N.any(zyx > N.array(c.shape)) or N.any(zyx < 0): vzyx = N.array(U.findMax(c))#continue v = vzyx[0] zyx = vzyx[-c.ndim:] + 0.5 # pixel center s = 2.5 else: break if not v: v = U.findMax(c)[0] else: vzyx = U.findMax(c) v = vzyx[0] zyx = N.array(vzyx[-c.ndim:]) + 0.5 # pixel center s = 2.5 return v, zyx, s
def radialaverage(data, center=None, useMaxShape=False): """ data: ND array center: coordinate of center of radii useMinShape: the output uses the maximum shape available return 1D array """ if center is None: center = N.array(data.shape) // 2 if len(center) != data.ndim: raise ValueError( 'dimension of center (%i) does not match the dimension of data (%i)' % (len(center), data.ndim)) zyx = N.indices((data.shape)) r = N.zeros(data.shape, N.float32) for i, t in enumerate(zyx): r += (t - center[i])**2 r = N.sqrt(r) #y, x = N.indices((data.shape)) #r = N.sqrt((x - center[0])**2 + (y - center[1])**2) # distance from the center r = r.astype(N.int) if data.dtype.type in (N.complex64, N.complex128): rbin = N.bincount(r.ravel(), data.real.ravel()) ibin = N.bincount(r.ravel(), data.imag.ravel()) tbin = N.empty(rbin.shape, data.dtype.type) tbin.real = rbin tbin.imag = ibin else: tbin = N.bincount(r.ravel(), data.ravel()) nr = N.bincount(r.ravel()) radialprofile = tbin / nr.astype(N.float32) if not useMaxShape: minShape = min(list(N.array(data.shape) - center) + list(center)) radialprofile = radialprofile[:minShape] return radialprofile
def zoomFourier(arr, factor, use_abs=False): shape = N.array(arr.shape) target = [int(s) for s in shape * factor] #target[-1] //= 2 #target[-1] += 1 af = F.fft(arr) ap = paddingFourier(af, target) afp = F.ifft(ap) factor = target / shape if use_abs: return N.abs(afp) * N.product(factor) else: return N.real(afp) * N.product(factor)
def _smoothBorder(arr, start, stop, smooth, value): """ start, stop: [z,y,x] """ # prepare coordinates shape = N.array(arr.shape) start = N.ceil(start).astype(N.int16) stop = N.ceil(stop).astype(N.int16) smooth_start = start - smooth smooth_stop = stop + smooth smooth_start = N.where(smooth_start < 0, 0, smooth_start) smooth_stop = N.where(smooth_stop > shape, shape, smooth_stop) #print smooth_start, smooth_stop import copy sliceTemplate = [slice(None, None, None)] * arr.ndim shapeTemplate = list(shape) for d in range(arr.ndim): smooth_shape = shapeTemplate[:d] + shapeTemplate[d + 1:] # make an array containing the edge value edges = N.empty([2] + smooth_shape, N.float32) # start side slc = copy.copy(sliceTemplate) slc[d] = slice(start[d], start[d] + 1, None) edges[0] = arr[slc].reshape(smooth_shape) # stop side slc = copy.copy(sliceTemplate) slc[d] = slice(stop[d] - 1, stop[d], None) edges[1] = arr[slc].reshape(smooth_shape) edges = (edges - value) / float( smooth + 1) # this value can be array?? # both side for s, side in enumerate([start, stop]): if s == 0: rs = list(range(smooth_start[d], start[d])) rs.sort(reverse=True) elif s == 1: rs = list(range(stop[d], smooth_stop[d])) # smoothing for f, i in enumerate(rs): slc = copy.copy(sliceTemplate) slc[d] = slice(i, i + 1, None) edgeArr = edges[s].reshape(arr[slc].shape) #arr[slc] += edgeArr * (smooth - f) arr[slc] = arr[slc] + edgeArr * (smooth - f) # casting rule arr = N.ascontiguousarray(arr) return arr
def radialaverage(data, center=None, useMaxShape=False): """ data: ND array center: coordinate of center of radii useMinShape: the output uses the maximum shape available return 1D array """ if center is None: center = N.array(data.shape) // 2 if len(center) != data.ndim: raise ValueError('dimension of center (%i) does not match the dimension of data (%i)' % (len(center), data.ndim)) zyx = N.indices((data.shape)) r = N.zeros(data.shape, N.float32) for i, t in enumerate(zyx): r += (t - center[i])**2 r = N.sqrt(r) #y, x = N.indices((data.shape)) #r = N.sqrt((x - center[0])**2 + (y - center[1])**2) # distance from the center r = r.astype(N.int) if data.dtype.type in (N.complex64, N.complex128): rbin = N.bincount(r.ravel(), data.real.ravel()) ibin = N.bincount(r.ravel(), data.imag.ravel()) tbin = N.empty(rbin.shape, data.dtype.type) tbin.real = rbin tbin.imag = ibin else: tbin = N.bincount(r.ravel(), data.ravel()) nr = N.bincount(r.ravel()) radialprofile = tbin / nr.astype(N.float32) if not useMaxShape: minShape = min(list(N.array(data.shape) - center) + list(center)) radialprofile = radialprofile[:minShape] return radialprofile
def _smoothBorder(arr, start, stop, smooth, value): """ start, stop: [z,y,x] """ # prepare coordinates shape = N.array(arr.shape) start = N.ceil(start).astype(N.int16) stop = N.ceil(stop).astype(N.int16) smooth_start = start - smooth smooth_stop = stop + smooth smooth_start = N.where(smooth_start < 0, 0, smooth_start) smooth_stop = N.where(smooth_stop > shape, shape, smooth_stop) #print smooth_start, smooth_stop import copy sliceTemplate = [slice(None,None,None)] * arr.ndim shapeTemplate = list(shape) for d in range(arr.ndim): smooth_shape = shapeTemplate[:d] + shapeTemplate[d+1:] # make an array containing the edge value edges = N.empty([2] + smooth_shape, N.float32) # start side slc = copy.copy(sliceTemplate) slc[d] = slice(start[d], start[d]+1, None) edges[0] = arr[slc].reshape(smooth_shape) # stop side slc = copy.copy(sliceTemplate) slc[d] = slice(stop[d]-1, stop[d], None) edges[1] = arr[slc].reshape(smooth_shape) edges = (edges - value) / float(smooth + 1) # this value can be array?? # both side for s, side in enumerate([start, stop]): if s == 0: rs = list(range(smooth_start[d], start[d])) rs.sort(reverse=True) elif s == 1: rs = list(range(stop[d], smooth_stop[d])) # smoothing for f,i in enumerate(rs): slc = copy.copy(sliceTemplate) slc[d] = slice(i,i+1,None) edgeArr = edges[s].reshape(arr[slc].shape) #arr[slc] += edgeArr * (smooth - f) arr[slc] = arr[slc] + edgeArr * (smooth - f) # casting rule arr = N.ascontiguousarray(arr) return arr
def shiftFullFFT(arr, delta=None): """ returns new array: arr shifted by delta (tuple) it uses fft (not rfft), multiplying with "shift array", ifft delta defaults to half of arr.shape """ shape = arr.shape if delta is None: delta = N.array(shape) / 2. elif not hasattr(delta, '__len__'): delta = (delta, ) * len(shape) elif len(shape) != len(delta): raise ValueError("shape and delta not same dimension") return F.ifft(F.fourierShiftArr(shape, delta) * F.fft(arr))
def shiftFullFFT(arr, delta=None): """ returns new array: arr shifted by delta (tuple) it uses fft (not rfft), multiplying with "shift array", ifft delta defaults to half of arr.shape """ shape = arr.shape if delta is None: delta = N.array(shape) / 2. elif not hasattr(delta, '__len__'): delta = (delta,)*len(shape) elif len(shape) != len(delta): raise ValueError("shape and delta not same dimension") return F.ifft(F.fourierShiftArr(shape, delta) * F.fft(arr))
def img2polar2D(img, center, final_radius=None, initial_radius=None, phase_width=360, return_idx=False): """ img: array center: coordinate y, x final_radius: ending radius initial_radius: starting radius phase_width: npixles / circle return_idx: return transformation coordinates (y,x) """ if img.ndim > 2 or len(center) > 2: raise ValueError( 'this function only support 2D, you entered %i-dim array and %i-dim center coordinate' % (img.ndim, len(center))) if initial_radius is None: initial_radius = 0 if final_radius is None: rad0 = N.ceil(N.array(img.shape) - center) final_radius = min((int(min(rad0)), int(min(N.ceil(center))))) if phase_width is None: phase_width = N.sum(img.shape[-2:]) * 2 theta, R = np.meshgrid(np.linspace(0, 2 * np.pi, phase_width), np.arange(initial_radius, final_radius)) Ycart, Xcart = polar2cart2D(R, theta, center) Ycart = N.where(Ycart >= img.shape[0], img.shape[0] - 1, Ycart) Xcart = N.where(Xcart >= img.shape[1], img.shape[1] - 1, Xcart) Ycart = Ycart.astype(int) Xcart = Xcart.astype(int) polar_img = img[Ycart, Xcart] polar_img = np.reshape(polar_img, (final_radius - initial_radius, phase_width)) if return_idx: return polar_img, Ycart, Xcart else: return polar_img
def selectYX(self, yxMM): """ yxMM: ([ymin,ymax],[xmin,xmax]) or (*,sliceY,sliceX) stores region info """ if type(yxMM[-1]) == slice: self._yxSlice = yxMM[-2:] self._yxslice2crop() else: self._yxSlice = slice(yxMM[0][0], yxMM[0][1]), slice(yxMM[1][0], yxMM[1][1]) self._yxslice2crop() sy, sx = self._yxSlice y0, y1 = sy.start, sy.stop x0, x1 = sx.start, sx.stop self._yxSize = N.array((y1 - y0, x1 - x0)) return
def paddingValue(img, shape, value=0, shift=None, smooth=0, interpolate=True): """ shape: in the same dimension as img value: value in padded region, can be scaler or array with the shape shift: scaler or in the same dimension as img and shape (default 0) smooth: scaler value to smoothen border (here value must be scaler) interpolate: shift array by subpixel interpolation to adjust center return: padded array with shape """ # create buffer dtype = img.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calculate position shape = N.array(shape) shapeS = img.shape center = N.divide(shape, 2) if shift is None: shift = 0 #[0] * len(shapeS) shapeL = shape #N.add(shapeS, center+shift) #start, stop = (shapeL - shapeS)/2., (shapeL + shapeS)/2. start = N.round_((shapeL - shapeS) / 2.).astype(N.int) stop = shapeS + start slc = [slice(start[d], stop[d], None) for d in range(img.ndim)] #slc = [slice(int(round(start[d])), int(round(stop[d])), None) for d in range(img.ndim)] #print slc, shapeS, shapeL # shift if necessary if interpolate: subpx_shift = start % 1 # should be 0.5 or 0 if N.sometrue(subpx_shift): img = U.nd.shift(img, subpx_shift) # padding canvas[slc] = img if smooth: canvas = _smoothBorder(canvas, start, stop, smooth, value) canvas = N.ascontiguousarray(canvas) #print shapeS, shapeL, slc return canvas
def paddingValue(img, shape, value=0, shift=None, smooth=0, interpolate=True): """ shape: in the same dimension as img value: value in padded region, can be scaler or array with the shape shift: scaler or in the same dimension as img and shape (default 0) smooth: scaler value to smoothen border (here value must be scaler) interpolate: shift array by subpixel interpolation to adjust center return: padded array with shape """ # create buffer dtype = img.dtype.type canvas = N.empty(shape, dtype) canvas[:] = value # calculate position shape = N.array(shape) shapeS = img.shape center = N.divide(shape, 2) if shift is None: shift = 0#[0] * len(shapeS) shapeL = shape#N.add(shapeS, center+shift) #start, stop = (shapeL - shapeS)/2., (shapeL + shapeS)/2. start = N.round_((shapeL - shapeS)/2.).astype(N.int) stop = shapeS + start slc = [slice(start[d], stop[d], None) for d in range(img.ndim)] #slc = [slice(int(round(start[d])), int(round(stop[d])), None) for d in range(img.ndim)] #print slc, shapeS, shapeL # shift if necessary if interpolate: subpx_shift = start % 1 # should be 0.5 or 0 if N.sometrue(subpx_shift): img = U.nd.shift(img, subpx_shift) # padding canvas[slc] = img if smooth: canvas = _smoothBorder(canvas, start, stop, smooth, value) canvas = N.ascontiguousarray(canvas) #print shapeS, shapeL, slc return canvas
def highPassF(af, highpassSigma=2.5, wiener=0.2, cutoffFreq=3): """ fourie space operations af: array after rfft half_nyx: half shape required for highpass filter highpassSigma: highpass filter, if 0, highpass is not done wiener: wiener coefficient for highpass filte cutoffFreq: band-pass around origin return: array BEFORE irfft WARNING: af will be changed, so use copy() if necessary """ global _G, _G_SHAPE if highpassSigma: shape = N.array(af.shape) shape[-1] = (shape[-1] - 1) * 2 szyx = shape / 2. if _G is not None and N.alltrue(_G_SHAPE == shape): g = _G else: g = imgFilters.gaussianArrND(shape, highpassSigma, peakVal=1, orig=szyx) g = F.shift(g)[..., :af.shape[-1]] _G = g _G_SHAPE = N.asarray(g.shape) g += wiener af /= g # kill DC af.flat[0] = 0 # kill lowest freq in YX for d in range(af.ndim - 2, af.ndim): upperdim = ':,' * d exec('af[%s0:cutoffFreq] = 0' % upperdim) return af
def img2polar2D(img, center, final_radius=None, initial_radius = None, phase_width = 360, return_idx=False): """ img: array center: coordinate y, x final_radius: ending radius initial_radius: starting radius phase_width: npixles / circle return_idx: return transformation coordinates (y,x) """ if img.ndim > 2 or len(center) > 2: raise ValueError('this function only support 2D, you entered %i-dim array and %i-dim center coordinate' % (img.ndim, len(center))) if initial_radius is None: initial_radius = 0 if final_radius is None: rad0 = N.ceil(N.array(img.shape) - center) final_radius = min((int(min(rad0)), int(min(N.ceil(center))))) if phase_width is None: phase_width = N.sum(img.shape[-2:]) * 2 theta , R = np.meshgrid(np.linspace(0, 2*np.pi, phase_width), np.arange(initial_radius, final_radius)) Ycart, Xcart = polar2cart2D(R, theta, center) Ycart = N.where(Ycart >= img.shape[0], img.shape[0]-1, Ycart) Xcart = N.where(Xcart >= img.shape[1], img.shape[1]-1, Xcart) Ycart = Ycart.astype(int) Xcart = Xcart.astype(int) polar_img = img[Ycart,Xcart] polar_img = np.reshape(polar_img,(final_radius-initial_radius,phase_width)) if return_idx: return polar_img, Ycart, Xcart else: return polar_img
def splitImage(a, ncpu=8, mergin=10): axis, regions = chopYX(N.array(a.shape[-2:]), ncpu) dzyx = [] arrs = [] slc = [slice(None) for d in range(a.ndim)] axis = axis + (a.ndim - 2) for i, region in enumerate(regions): if i: start = region[0] - mergin else: start = region[0] if i < (len(regions) - 1): stop = region[1] + mergin else: stop = region[1] slc[axis] = slice(start, stop) arrs.append(a[slc]) dd = [0 for i in range(a.ndim)] dd[axis] = -region[0] dzyx.append(dd) return arrs, axis, dzyx
def splitImage(a, ncpu=8, mergin=10): axis, regions = chopYX(N.array(a.shape[-2:]), ncpu) dzyx = [] arrs = [] slc = [slice(None) for d in range(a.ndim)] axis = axis + (a.ndim-2) for i, region in enumerate(regions): if i: start = region[0] - mergin else: start = region[0] if i < (len(regions) -1): stop = region[1] + mergin else: stop = region[1] slc[axis] = slice(start, stop) arrs.append(a[slc]) dd = [0 for i in range(a.ndim)] dd[axis] = -region[0] dzyx.append(dd) return arrs, axis, dzyx
def highPassF(af, highpassSigma=2.5, wiener=0.2, cutoffFreq=3): """ fourie space operations af: array after rfft half_nyx: half shape required for highpass filter highpassSigma: highpass filter, if 0, highpass is not done wiener: wiener coefficient for highpass filte cutoffFreq: band-pass around origin return: array BEFORE irfft WARNING: af will be changed, so use copy() if necessary """ global _G, _G_SHAPE if highpassSigma: shape = N.array(af.shape) shape[-1] = (shape[-1] - 1) * 2 szyx = shape / 2. if _G is not None and N.alltrue(_G_SHAPE == shape): g = _G else: g = imgFilters.gaussianArrND(shape, highpassSigma, peakVal=1, orig=szyx) g = F.shift(g)[...,:af.shape[-1]] _G = g _G_SHAPE = N.asarray(g.shape) g += wiener af /= g # kill DC af.flat[0] = 0 # kill lowest freq in YX for d in range(af.ndim-2, af.ndim): upperdim = ':,' * d exec('af[%s0:cutoffFreq] = 0' % upperdim) return af
def phaseContrastFilter(a, inFourier=False, removeNan=True, nyquist=0.6): global GAUSS if inFourier: af = a.copy() else: af = F.rfft(a) # here is the phase contrast amp = N.abs(af) afa = af / amp if removeNan: afa = nanFilter(afa) # lowpass gaussian filter of phase image if nyquist: # since this takes long time, gaussian array is re-used if possible if GAUSS is not None and GAUSS[0] == nyquist and GAUSS[ 1].shape == afa.shape: nq, gf = GAUSS else: #sigma = af.shape[-1] * nyquist #gf = F.gaussianArr(afa.shape, sigma, peakVal=1, orig=0, wrap=(1,)*(afa.ndim-1)+(0,))#, dtype=afa.dtype.type) gshape = N.array(af.shape) if inFourier: gshape[-1] *= 2 sigma = gshape * nyquist gf = imgFilters.gaussianArrND(gshape, sigma, peakVal=1) gf = N.fft.fftshift(gf)[Ellipsis, :af.shape[-1]] GAUSS = (nyquist, gf) afa *= gf if inFourier: ap = afa else: ap = F.irfft(afa) return ap
def iteration(a, b, niter=5, phaseContrast=PHASE, nyquist=NYQUIST, gFit=True, win=11, ret=None, searchRad=None, npad=4): """ iterative xcorr if ret is None: reutrn zyx elif ret is 1: retunr zyx, N.array((a0, b0)) """ zyx, c = Xcorr(a, b, phaseContrast, nyquist, gFit, win, searchRad=searchRad, npad=npad) for i in range(niter): b0 = imgResample.trans3D_affine(b, zyx) slc = _makeSlice(zyx) b0 = b0[slc] a0 = a[slc] zyx0, c = Xcorr(a0, b0, phaseContrast, nyquist, gFit, win, searchRad=searchRad, npad=npad) zyx += zyx0 if ret is None: return zyx elif ret is 1: return zyx, N.array((a0, b0)) elif ret is True: return zyx, c
def mask_gaussianND(arr, zyx, v, sigma=2., ret=None, rot=0, clipZero=True): ''' subtract elliptical gaussian at y,x with peakVal v if ret, return arr, else, arr itself is edited ''' from . import imgGeo zyx = N.asarray(zyx) ndim = arr.ndim shape = N.array(arr.shape) try: if len(sigma) != ndim: raise ValueError('len(sigma) must be the same as len(shape)') else: sigma = N.asarray(sigma) except TypeError: #(TypeError, ValueError): sigma = N.asarray([sigma] * ndim) # prepare small window slc = imgGeo.nearbyRegion(shape, N.floor(zyx), sigma * 10) inds, LD = imgFit.rotateIndicesND(slc, dtype=N.float32, rot=rot) param = ( 0, v, ) + tuple(zyx) + tuple(sigma) sidx = 2 + ndim g = imgFit.yGaussianND(N.asarray(param), inds, sidx).astype(arr.dtype.type) roi = arr[slc] if clipZero: g = N.where(g > roi, roi, g) if ret: e = N.zeros_like(arr) e[slc] = g # this may be faster than copy() return arr - e else: arr[slc] -= g
def keepShape(a, shape, difmod=None): canvas = N.zeros(shape, a.dtype.type) if difmod is None: dif = (shape - N.array(a.shape, N.float32)) / 2. mod = N.ceil(N.mod(dif, 1)) else: dif, mod = difmod dif = N.where(dif > 0, N.ceil(dif), N.floor(dif)) # smaller aoff = N.where(dif < 0, 0, dif) aslc = [slice(dp, shape[i] - dp + mod[i]) for i, dp in enumerate(aoff)] # larger coff = N.where(dif > 0, 0, -dif) cslc = [slice(dp, a.shape[i] - dp + mod[i]) for i, dp in enumerate(coff)] canvas[aslc] = a[cslc] if difmod is None: return canvas, mod else: return canvas
def phaseContrastFilter(a, inFourier=False, removeNan=True, nyquist=0.6): global GAUSS if inFourier: af = a.copy() else: af = F.rfft(a) # here is the phase contrast amp = N.abs(af) afa = af / amp if removeNan: afa = nanFilter(afa) # lowpass gaussian filter of phase image if nyquist: # since this takes long time, gaussian array is re-used if possible if GAUSS is not None and GAUSS[0] == nyquist and GAUSS[1].shape == afa.shape: nq, gf = GAUSS else: #sigma = af.shape[-1] * nyquist #gf = F.gaussianArr(afa.shape, sigma, peakVal=1, orig=0, wrap=(1,)*(afa.ndim-1)+(0,))#, dtype=afa.dtype.type) gshape = N.array(af.shape) if inFourier: gshape[-1] *= 2 sigma = gshape * nyquist gf = imgFilters.gaussianArrND(gshape, sigma, peakVal=1) gf = N.fft.fftshift(gf)[Ellipsis, :af.shape[-1]] GAUSS = (nyquist, gf) afa *= gf if inFourier: ap = afa else: ap = F.irfft(afa) return ap
def keepShape(a, shape, difmod=None): canvas = N.zeros(shape, a.dtype.type) if difmod is None: dif = (shape - N.array(a.shape, N.float32)) / 2. mod = N.ceil(N.mod(dif, 1)) else: dif, mod = difmod dif = N.where(dif > 0, N.ceil(dif), N.floor(dif)) # smaller aoff = N.where(dif < 0, 0, dif) aslc = [slice(dp, shape[i]-dp+mod[i]) for i, dp in enumerate(aoff)] # larger coff = N.where(dif > 0, 0, -dif) cslc = [slice(dp, a.shape[i]-dp+mod[i]) for i, dp in enumerate(coff)] canvas[aslc] = a[cslc] if difmod is None: return canvas, mod else: return canvas
def rotateIndicesND(slicelist, dtype=N.float64, rot=0, mode=2): """ slicelist: even shape works much better than odd shape rot: counter-clockwise, xy-plane mode: testing different ways of doing, (1 or 2 and the same result) return inds, LD """ global INDS_DIC shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) shapeTuple = tuple(shape + [rot]) if shapeTuple in INDS_DIC: inds = INDS_DIC[shapeTuple] else: shape = N.array(shape) ndim = len(shape) odd_even = shape % 2 s2 = N.ceil(shape * (2**0.5)) if mode == 1: # everything is even s2 = N.where(s2 % 2, s2 + 1, s2) elif mode == 2: # even & even or odd & odd for d, s in enumerate(shape): if (s % 2 and not s2[d] % 2) or (not s % 2 and s2[d] % 2): s2[d] += 1 cent = s2 / 2. dif = (s2 - shape) / 2. dm = dif % 1 # print s2, cent, dif, dm slc = [Ellipsis] + [ slice(int(d), int(d) + shape[i]) for i, d in enumerate(dif) ] # This slice is float which shift array when cutting out!! s2 = tuple([int(ss) for ss in s2]) # numpy array cannot use used for slice inds = N.indices(s2, N.float32) ind_shape = inds.shape nz = N.product(ind_shape[:-2]) nsec = nz / float(ndim) if ndim > 2: inds = N.reshape(inds, (nz, ) + ind_shape[-2:]) irs = N.empty_like(inds) for d, ind in enumerate(inds): idx = int(d // nsec) c = cent[idx] if rot and inds.ndim > 2: U.trans2d(ind - c, irs[d], (0, 0, rot, 1, 0, 1)) irs[d] += c - dif[idx] else: irs[d] = ind - dif[idx] if len(ind_shape) > 2: irs = N.reshape(irs, ind_shape) irs = irs[slc] if mode == 1 and N.sometrue(dm): inds = N.empty_like(irs) # print 'translate', dm for d, ind in enumerate(irs): U.trans2d(ind, inds[d], (-dm[1], -dm[0], 0, 1, 0, 1)) else: inds = irs INDS_DIC[shapeTuple] = inds r_inds = N.empty_like(inds) for d, ld in enumerate(LD): r_inds[d] = inds[d] + ld return r_inds, LD
def trans3D_spline(a, tzyx=(0, 0, 0), r=0, mag=1, dzyx=(0, 0), rzy=0, mr=0, reshape=False, ncpu=1, **splinekwds): """ mag: scalar_for_yx or [y,x] or [z,y,x] mr: rotational direction of yx-zoom in degrees ncpu: no usage """ splinekwds['prefilter'] = splinekwds.get('prefilter', True) splinekwds['order'] = splinekwds.get('order', 3) ndim = a.ndim shape = N.array(a.shape, N.float32) tzyx = N.asarray(tzyx, N.float32) # rotation axis if ndim == 3: axes = (1, 2) else: axes = (1, 0) # magnification try: if len(mag) == 1: # same as scalar mag = [1] * (ndim - 2) + list(mag) * 2 else: mag = [1] * (ndim - 2) * (3 - len(mag)) + list(mag) except: # scalar -> convert to yx mag only mag = [1] * (ndim - 2) + ([mag] * ndim)[:2] mag = N.asarray(mag) try: dzyx = N.array([0] * (ndim - 2) * (3 - len(dzyx)) + list(dzyx)) except: # scalar pass if mr: a = U.nd.rotate(a, mr, axes=axes, reshape=reshape, **splinekwds) splinekwds['prefilter'] = False if N.any(dzyx): a = U.nd.shift(a, -dzyx, **splinekwds) splinekwds['prefilter'] = False if r: a = U.nd.rotate(a, -r, axes=axes, reshape=reshape, **splinekwds) splinekwds['prefilter'] = False if N.any(mag != 1): a = U.nd.zoom(a, zoom=mag, **splinekwds) splinekwds['prefilter'] = False if not reshape: dif = (shape - N.array(a.shape, N.float32)) / 2. mod = N.ceil(N.mod(dif, 1)) tzyx[-ndim:] -= (mod / 2.) if rzy and ndim >= 3: # is this correct?? havn't tried yet a = U.nd.rotate(a, -rzy, axes=(0, 1), reshape=reshape, **splinekwds) if N.any(dzyx): a = U.nd.shift(a, dzyx, **splinekwds) if mr: a = U.nd.rotate(a, -mr, axes=axes, reshape=reshape, **splinekwds) if reshape: a = U.nd.shift(a, tzyx[-ndim:], **splinekwds) else: tzyx0 = N.where(mag >= 1, tzyx[-ndim:], 0) if N.any(tzyx0[-ndim:]): a = U.nd.shift(a, tzyx0[-ndim:], **splinekwds) if N.any(mag != 1) and not reshape: a = keepShape(a, shape, (dif, mod)) old = """ canvas = N.zeros(shape, a.dtype.type) #dif = (shape - N.array(a.shape, N.float32)) / 2 #mod = N.ceil(N.mod(dif, 1)) dif = N.where(dif > 0, N.ceil(dif), N.floor(dif)) # smaller aoff = N.where(dif < 0, 0, dif) aslc = [slice(dp, shape[i]-dp+mod[i]) for i, dp in enumerate(aoff)] # larger coff = N.where(dif > 0, 0, -dif) cslc = [slice(dp, a.shape[i]-dp+mod[i]) for i, dp in enumerate(coff)] canvas[aslc] = a[cslc] a = canvas""" if not reshape: tzyx0 = N.where(mag < 1, tzyx[-ndim:], 0) if N.any(mag != 1): tzyx0[-ndim:] -= (mod / 2.) if N.any(tzyx0[-ndim:]): a = U.nd.shift(a, tzyx0[-ndim:], **splinekwds) return a
def trans3D_spline(a, tzyx=(0,0,0), r=0, mag=1, dzyx=(0,0), rzy=0, mr=0, reshape=False, ncpu=1, **splinekwds): """ mag: scalar_for_yx or [y,x] or [z,y,x] mr: rotational direction of yx-zoom in degrees ncpu: no usage """ splinekwds['prefilter'] = splinekwds.get('prefilter', True) splinekwds['order'] = splinekwds.get('order', 3) ndim = a.ndim shape = N.array(a.shape, N.float32) tzyx = N.asarray(tzyx, N.float32) # rotation axis if ndim == 3: axes = (1,2) else: axes = (1,0) # magnification try: if len(mag) == 1: # same as scalar mag = [1] * (ndim-2) + list(mag) * 2 else: mag = [1] * (ndim-2) * (3-len(mag)) + list(mag) except: # scalar -> convert to yx mag only mag = [1] * (ndim-2) + ([mag] * ndim)[:2] mag = N.asarray(mag) try: dzyx = N.array([0] * (ndim-2) * (3-len(dzyx)) + list(dzyx)) except: # scalar pass if mr: a = U.nd.rotate(a, mr, axes=axes, reshape=reshape, **splinekwds) splinekwds['prefilter'] = False if N.any(dzyx): a = U.nd.shift(a, -dzyx, **splinekwds) splinekwds['prefilter'] = False if r: a = U.nd.rotate(a, -r, axes=axes, reshape=reshape, **splinekwds) splinekwds['prefilter'] = False if N.any(mag != 1): a = U.nd.zoom(a, zoom=mag, **splinekwds) splinekwds['prefilter'] = False if not reshape: dif = (shape - N.array(a.shape, N.float32)) / 2. mod = N.ceil(N.mod(dif, 1)) tzyx[-ndim:] -= (mod / 2.) if rzy and ndim >= 3: # is this correct?? havn't tried yet a = U.nd.rotate(a, -rzy, axes=(0,1), reshape=reshape, **splinekwds) if N.any(dzyx): a = U.nd.shift(a, dzyx, **splinekwds) if mr: a = U.nd.rotate(a, -mr, axes=axes, reshape=reshape, **splinekwds) if reshape: a = U.nd.shift(a, tzyx[-ndim:], **splinekwds) else: tzyx0 = N.where(mag >= 1, tzyx[-ndim:], 0) if N.any(tzyx0[-ndim:]): a = U.nd.shift(a, tzyx0[-ndim:], **splinekwds) if N.any(mag != 1) and not reshape: a = keepShape(a, shape, (dif, mod)) old=""" canvas = N.zeros(shape, a.dtype.type) #dif = (shape - N.array(a.shape, N.float32)) / 2 #mod = N.ceil(N.mod(dif, 1)) dif = N.where(dif > 0, N.ceil(dif), N.floor(dif)) # smaller aoff = N.where(dif < 0, 0, dif) aslc = [slice(dp, shape[i]-dp+mod[i]) for i, dp in enumerate(aoff)] # larger coff = N.where(dif > 0, 0, -dif) cslc = [slice(dp, a.shape[i]-dp+mod[i]) for i, dp in enumerate(coff)] canvas[aslc] = a[cslc] a = canvas""" if not reshape: tzyx0 = N.where(mag < 1, tzyx[-ndim:], 0) if N.any(mag != 1): tzyx0[-ndim:] -= (mod / 2.) if N.any(tzyx0[-ndim:]): a = U.nd.shift(a, tzyx0[-ndim:], **splinekwds) return a
def getShift(shift, ZYX, erosionZYX=0): """ shift: zyxrmm return [zmin,zmax,ymin,ymax,xmin,xmax] """ # erosion try: if len(erosionZYX) == 3: erosionZ = erosionZYX[0] erosionYX = erosionZYX[1:] elif len(erosionZYX) == 2: erosionZ = 0 erosionYX = erosionZYX elif len(erosionZYX) == 1: erosionZ = 0 erosionYX = erosionZYX[0] except TypeError: # scalar erosionZ = erosionZYX erosionYX = erosionZYX # magnification magZYX = N.ones((3, ), N.float32) magZYX[3 - len(shift[4:]):] = shift[4:] if len(shift[4:]) == 1: magZYX[1] = shift[4] # rotation r = shift[3] # target shape ZYX = N.asarray(ZYX, N.float32) ZYXm = ZYX * magZYX # Z z = N.where(shift[0] < 0, N.floor(shift[0]), N.ceil(shift[0])) ztop = ZYXm[0] + z nz = N.ceil(N.where(ztop > ZYX[0], ZYX[0], ztop)) z += erosionZ nz -= erosionZ if z < 0: z = 0 if nz < 0: nz = z + 1 zyx0 = N.ceil((ZYX - ZYXm) / 2.) #print zyx0 #if zyx0[0] > 0: # z -= zyx0[0] # nz += zyx0[0] zs = N.array([z, nz]) # YX #try: # if len(erosionYX) != 2: # raise ValueError, 'erosion is only applied to lateral dimension' #except TypeError: # erosionYX = (erosionYX, erosionYX) yxShift = N.where(shift[1:3] < 0, N.floor(shift[1:3]), N.ceil(shift[1:3])) # rotate the magnified center xyzm = N.ceil(ZYXm[::-1]) / 2. xyr = imgGeo.RotateXY(xyzm[:-1], r) xyr -= xyzm[:-1] yx = xyr[::-1] leftYX = N.ceil(N.abs(yx)) rightYX = -N.ceil(N.abs(yx)) # then translate leftYXShift = (leftYX + yxShift) + zyx0[1:] leftYXShift = N.where(leftYXShift < 0, 0, leftYXShift) rightYXShift = (rightYX + yxShift) - zyx0[1:] YXmax = N.where(ZYXm[1:] > ZYX[1:], ZYXm[1:], ZYX[1:]) rightYXShift = N.where(rightYXShift > 0, YXmax, rightYXShift + YXmax) # deal with - idx rightYXShift = N.where(rightYXShift > ZYX[1:], ZYX[1:], rightYXShift) leftYXShift += erosionYX rightYXShift -= erosionYX # (z0,z1,y0,y1,x0,x1) tempZYX = N.array( (zs[0], zs[1], int(N.ceil(leftYXShift[0])), int(rightYXShift[0]), int(N.ceil(leftYXShift[1])), int(rightYXShift[1]))) return tempZYX
def pointsCutOutND(arr, posList, windowSize=100, sectWise=None, interpolate=True): """ array: nd array posList: ([(z,)y,x]...) windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) if arr.ndim > 2, and len(windowSize) == 2, then cut out section-wise (higher dimensions stay the same) sectWise: conern only XY of windowSize (higher dimensions stay the same) interpolate: shift array by subpixel interpolation to adjust center return: list of array centered at each pos in posList """ shape = N.array(arr.shape) center = shape / 2. # prepare N-dimensional window size try: len(windowSize) # seq if sectWise: windowSize = windowSize[-2:] if len(windowSize) != arr.ndim: dim = len(windowSize) windowSize = tuple(shape[:-dim]) + tuple(windowSize) except TypeError: # scaler if windowSize < 1 and windowSize > 0: # percentage w = shape * windowSize if sectWise: w[:-2] = shape[:-2] windowSize = w.astype(N.uint16) else: windowSize = N.where(shape >= windowSize, windowSize, shape) if sectWise: windowSize = arr.shape[:-2] + tuple(windowSize[-2:]) windowSize = N.asarray(windowSize) # cutout individual position arrList=[] for pos in posList: # prepare N-dimensional coordinate n = len(pos) if n != len(windowSize): temp = center.copy() center[-n:] = pos pos = center # calculate idx ori = pos - (windowSize / 2.) # float value oidx = N.ceil(ori) # idx subpxl = oidx - ori # subpixel mod if interpolate and N.sometrue(subpxl): # comit to make shift SHIFT = 1 else: SHIFT = 0 # prepare slice # when comitted to make shift, first cut out window+1, # then make subpixle shift, and then cutout 1 edge slc = [Ellipsis] # Ellipsis is unnecessary, just in case... slc_edge = [slice(1,-1,None)] * arr.ndim for d in range(arr.ndim): start = oidx[d] - SHIFT if start < 0: start = 0 slc_edge[d] = slice(0, slc_edge[d].stop, None) stop = oidx[d] + windowSize[d] + SHIFT if stop > shape[d]: stop = shape[d] slc_edge[d] = slice(slc_edge[d].start, shape[d], None) slc += [slice(int(start), int(stop), None)] # cutout, shift and cutout #print(slc, slc_edge) try: canvas = arr[slc] if SHIFT: # 20180214 subpixel shift +0.5 was fixed #raise RuntimeError('check') if sectWise: subpxl[-2:] = N.where(windowSize[-2:] > 1, subpxl[-2:]-0.5, subpxl[-2:]) else: subpxl[-n:] = N.where(windowSize[-n:] > 1, subpxl[-n:]-0.5, subpxl[-n:]) canvas = U.nd.shift(canvas, subpxl) canvas = canvas[slc_edge] check = 1 except IndexError: print('position ', pos, ' was skipped') check = 0 raise if check: arrList += [N.ascontiguousarray(canvas)] return arrList
def pointsCutOut3D(arr, posList, windowSize=100, d2=None, interpolate=True, removeWrongShape=True): """ array: nd array posList: ([(z,)y,x]...) windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) if arr.ndim > 2, and len(windowSize) == 2, then cut out section-wise (higher dimensions stay the same) d2: conern only XY of windowSize (higher dimensions stay the same) interpolate: shift array by subpixel interpolation to adjust center return: list of array centered at each pos in posList """ shape = N.array(arr.shape) center = shape / 2. if arr.ndim <= 2: ndim_arr = arr.ndim else: ndim_arr = 3 # prepare N-dimensional window size try: len(windowSize) # seq if d2: windowSize = windowSize[-2:] if len(windowSize) != arr.ndim: dim = len(windowSize) windowSize = tuple(shape[:-dim]) + tuple(windowSize) except TypeError: # scaler if windowSize < 1 and windowSize > 0: # percentage w = shape * windowSize if d2: w[:-2] = shape[:-2] elif ndim_arr > 3: w[:-3] = shape[:-3] windowSize = w.astype(N.uint) else: windowSize = N.where(shape >= windowSize, windowSize, shape) if d2: windowSize[:-2] = shape[:-2] windowSize = N.asarray(windowSize) halfWin = windowSize / 2 #ndim_win = len(windowSize) margin = int(interpolate) # cutout individual position arrList = [] for pos in posList: ndim_pos = len(pos) # calculate idx dif = pos +0.5 - halfWin[-ndim_pos:] dif = N.round_(dif) dif = dif.astype(N.int) starts = dif - margin starts = N.where(starts < 0, 0, starts) stops = dif + windowSize[-ndim_pos:] + margin stops = N.where(stops > shape[-ndim_pos:], shape[-ndim_pos:], stops) #if removeWrongShape and (N.any((starts) < 0) or N.any((stops) > shape[-ndim_pos:])): # continue slc = [Ellipsis] for dim, s0 in enumerate(starts): s1 = stops[dim] slc.append(slice(s0, s1)) cpa = arr[slc] if interpolate: dif = pos + 0.5 - halfWin[-ndim_pos:] sub = (arr.ndim - len(dif)) * [0] + list(dif) sub = N.array(sub) sar = U.nd.shift(cpa, sub % 1) slc = [Ellipsis] for d in range(ndim_arr): slc.append(slice(margin, -margin)) cpa = sar[slc] arrList.append(cpa) if removeWrongShape: if d2 and arr.ndim == 2: arrList = N.array([a for a in arrList if N.all(a.shape[-2:] == windowSize[-2:])]) else: arrList = N.array([a for a in arrList if N.all(a.shape[-3:] == windowSize[-3:])]) return arrList
def Xcorr(a, b, phaseContrast=PHASE, nyquist=NYQUIST, removeEdge=0, gFit=True, win=11, ret=None, searchRad=None): """ sigma uses F.gaussianArr in the Fourier domain if ret is None: return zyx, xcf elif ret is 2: return s, v, zyx, xcf elif ret: return v, zyx, xcf """ #print 'phase contrast: %s' % str(phaseContrast) #global DATA # correct odd shape particularly Z axis a = N.squeeze(a) b = N.squeeze(b) a = imgFilters.evenShapeArr(a) b = imgFilters.evenShapeArr(b) shape = N.array(a.shape) # apodize a = apodize(a) b = apodize(b) # fourier transform af = F.rfft(a.astype(N.float32)) bf = F.rfft(b.astype(N.float32)) del a, b # phase contrast filter (removing any intensity information) if phaseContrast: afa = phaseContrastFilter(af, True, nyquist=nyquist) bfa = phaseContrastFilter(bf, True, nyquist=nyquist) else: afa = af bfa = bf del af, bf # removing edge if gaussian is not sufficient targetShape = shape - N.multiply(removeEdge, 2) if removeEdge: ap = imgFilters.cutOutCenter(F.irfft(afa), targetShape) bp = imgFilters.cutOutCenter(F.irfft(bfa), targetShape) afa = F.rfft(ap) bfa = F.rfft(bp) del ap, bp # shift array delta = targetShape / 2. shiftarr = F.fourierRealShiftArr(tuple(targetShape), delta) bfa *= shiftarr # cross correlation bfa = bfa.conjugate() c = cc = F.irfft(afa * bfa) center = N.divide(c.shape, 2) if searchRad: slc = imgGeo.nearbyRegion(c.shape, center, searchRad) cc = N.zeros_like(c) cc[slc] = c[slc] v, zyx, s = _findMaxXcor(cc, win, gFit=gFit) zyx -= center if ret == 2: return s, v, zyx, c elif ret: return v, zyx, c else: return zyx, c
def paddAndApo(img, npad=4, shape=None): if shape is None: shape = N.array(img.shape) else: shape = N.array(shape) return imgFilters.paddingMed(img, shape + (npad * 2), smooth=npad)
def pointsCutOutND(arr, posList, windowSize=100, sectWise=None, interpolate=True): """ array: nd array posList: ([(z,)y,x]...) windowSize: scalar (in pixel or as percent < 1.) or ((z,)y,x) if arr.ndim > 2, and len(windowSize) == 2, then cut out section-wise (higher dimensions stay the same) sectWise: conern only XY of windowSize (higher dimensions stay the same) interpolate: shift array by subpixel interpolation to adjust center return: list of array centered at each pos in posList """ shape = N.array(arr.shape) center = shape / 2. # prepare N-dimensional window size try: len(windowSize) # seq if sectWise: windowSize = windowSize[-2:] if len(windowSize) != arr.ndim: dim = len(windowSize) windowSize = tuple(shape[:-dim]) + tuple(windowSize) except TypeError: # scaler if windowSize < 1 and windowSize > 0: # percentage w = shape * windowSize if sectWise: w[:-2] = shape[:-2] windowSize = w.astype(N.uint16) else: windowSize = N.where(shape >= windowSize, windowSize, shape) if sectWise: windowSize = arr.shape[:-2] + windowSize[-2:] windowSize = N.asarray(windowSize) # cutout individual position arrList = [] for pos in posList: # prepare N-dimensional coordinate n = len(pos) if n != len(windowSize): temp = center.copy() center[-n:] = pos pos = center # calculate idx ori = pos - (windowSize / 2.) # float value oidx = N.ceil(ori) # idx subpxl = oidx - ori # subpixel mod if interpolate and N.sometrue(subpxl): # comit to make shift SHIFT = 1 else: SHIFT = 0 # prepare slice # when comitted to make shift, first cut out window+1, # then make subpixle shift, and then cutout 1 edge slc = [Ellipsis] # Ellipsis is unnecessary, just in case... slc_edge = [slice(1, -1, None)] * arr.ndim for d in range(arr.ndim): start = oidx[d] - SHIFT if start < 0: start = 0 slc_edge[d] = slice(0, slc_edge[d].stop, None) stop = oidx[d] + windowSize[d] + SHIFT if stop > shape[d]: stop = shape[d] slc_edge[d] = slice(slc_edge[d].start, shape[d], None) slc += [slice(int(start), int(stop), None)] # cutout, shift and cutout try: canvas = arr[slc] if SHIFT: canvas = U.nd.shift(canvas, subpxl) canvas = canvas[slc_edge] check = 1 except IndexError: print('position ', pos, ' was skipped') check = 0 raise if check: arrList += [N.ascontiguousarray(canvas)] return arrList
def Xcorr(a, b, phaseContrast=PHASE, nyquist=NYQUIST, gFit=True, win=11, ret=None, searchRad=None, npad=4): """ sigma uses F.gaussianArr in the Fourier domain if ret is None: return zyx, xcf elif ret is 2: return s, v, zyx, xcf elif ret is 3: return zyx, xcf, a_phase_cotrast, b_phase_contrast elif ret: return v, zyx, xcf """ #print 'phase contrast: %s' % str(phaseContrast) #global DATA # correct odd shape particularly Z axis a = N.squeeze(a) b = N.squeeze(b) a = imgFilters.evenShapeArr(a) b = imgFilters.evenShapeArr(b) shape = N.array(a.shape) # padding strange shape #nyx = max(shape[-2:]) #pshape = N.array(a.shape[:-2] + (nyx,nyx)) # apodize a = paddAndApo(a, npad) #, pshape) #apodize(a) b = paddAndApo(b, npad) #, pshape) #apodize(b) # fourier transform af = F.rfft(a.astype(N.float32)) bf = F.rfft(b.astype(N.float32)) del a, b # phase contrast filter (removing any intensity information) if phaseContrast: afa = phaseContrastFilter(af, True, nyquist=nyquist) bfa = phaseContrastFilter(bf, True, nyquist=nyquist) else: afa = af bfa = bf del af, bf #targetShape = shape + (npad * 2) targetShape = shape + (npad * 2) # shift array delta = targetShape / 2. shiftarr = F.fourierRealShiftArr(tuple(targetShape), delta) bfa *= shiftarr # cross correlation bfa = bfa.conjugate() c = cc = F.irfft(afa * bfa) center = N.divide(c.shape, 2) if searchRad: slc = imgGeo.nearbyRegion(c.shape, center, searchRad) cc = N.zeros_like(c) cc[slc] = c[slc] v, zyx, s = _findMaxXcor(cc, win, gFit=gFit) zyx -= center c = imgFilters.cutOutCenter(c, N.array(c.shape) - (npad * 2), interpolate=False) #c = imgFilters.cutOutCenter(c, shape, interpolate=False) if ret == 3: return zyx, c, F.irfft(afa), F.irfft(bfa) elif ret == 2: return s, v, zyx, c elif ret: return v, zyx, c else: return zyx, c
def rotateIndicesND(slicelist, dtype=N.float64, rot=0, mode=2): """ slicelist: even shape works much better than odd shape rot: counter-clockwise, xy-plane mode: testing different ways of doing, (1 or 2 and the same result) return inds, LD """ global INDS_DIC shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) shapeTuple = tuple(shape+[rot]) if shapeTuple in INDS_DIC: inds = INDS_DIC[shapeTuple] else: shape = N.array(shape) ndim = len(shape) odd_even = shape % 2 s2 = N.ceil(shape * (2**0.5)) if mode == 1: # everything is even s2 = N.where(s2 % 2, s2 + 1, s2) elif mode == 2: # even & even or odd & odd for d, s in enumerate(shape): if (s % 2 and not s2[d] % 2) or (not s % 2 and s2[d] % 2): s2[d] += 1 cent = s2 / 2. dif = (s2 - shape) / 2. dm = dif % 1 # print s2, cent, dif, dm slc = [Ellipsis] + [slice(int(d), int(d)+shape[i]) for i, d in enumerate(dif)] # This slice is float which shift array when cutting out!! s2 = tuple([int(ss) for ss in s2]) # numpy array cannot use used for slice inds = N.indices(s2, N.float32) ind_shape = inds.shape nz = N.product(ind_shape[:-2]) nsec = nz / float(ndim) if ndim > 2: inds = N.reshape(inds, (nz,)+ind_shape[-2:]) irs = N.empty_like(inds) for d, ind in enumerate(inds): idx = int(d//nsec) c = cent[idx] if rot and inds.ndim > 2: U.trans2d(ind - c, irs[d], (0,0,rot,1,0,1)) irs[d] += c - dif[idx] else: irs[d] = ind - dif[idx] if len(ind_shape) > 2: irs = N.reshape(irs, ind_shape) irs = irs[slc] if mode == 1 and N.sometrue(dm): inds = N.empty_like(irs) # print 'translate', dm for d, ind in enumerate(irs): U.trans2d(ind, inds[d], (-dm[1], -dm[0], 0, 1, 0, 1)) else: inds = irs INDS_DIC[shapeTuple] = inds r_inds = N.empty_like(inds) for d, ld in enumerate(LD): r_inds[d] = inds[d] + ld return r_inds, LD
def Xcorr(a, b, phaseContrast=PHASE, nyquist=NYQUIST, gFit=True, win=11, ret=None, searchRad=None, npad=4): """ sigma uses F.gaussianArr in the Fourier domain if ret is None: return zyx, xcf elif ret is 2: return s, v, zyx, xcf elif ret is 3: return zyx, xcf, a_phase_cotrast, b_phase_contrast elif ret: return v, zyx, xcf """ #print 'phase contrast: %s' % str(phaseContrast) #global DATA # correct odd shape particularly Z axis a = N.squeeze(a) b = N.squeeze(b) a = imgFilters.evenShapeArr(a) b = imgFilters.evenShapeArr(b) shape = N.array(a.shape) # padding strange shape #nyx = max(shape[-2:]) #pshape = N.array(a.shape[:-2] + (nyx,nyx)) # apodize a = paddAndApo(a, npad)#, pshape) #apodize(a) b = paddAndApo(b, npad)#, pshape) #apodize(b) # fourier transform af = F.rfft(a.astype(N.float32)) bf = F.rfft(b.astype(N.float32)) del a, b # phase contrast filter (removing any intensity information) if phaseContrast: afa = phaseContrastFilter(af, True, nyquist=nyquist) bfa = phaseContrastFilter(bf, True, nyquist=nyquist) else: afa = af bfa = bf del af, bf #targetShape = shape + (npad * 2) targetShape = shape + (npad * 2) # shift array delta = targetShape / 2. shiftarr = F.fourierRealShiftArr(tuple(targetShape), delta) bfa *= shiftarr # cross correlation bfa = bfa.conjugate() #c = cc = F.irfft(afa * bfa) c = F.irfft(afa * bfa) # 20180214 the padded region was cutout before finding the peak. c = cc = imgFilters.cutOutCenter(c, N.array(c.shape) - (npad * 2), interpolate=False) #cc = c center = N.divide(c.shape, 2) if searchRad: slc = imgGeo.nearbyRegion(c.shape, center, searchRad) cc = N.zeros_like(c) cc[slc] = c[slc] v, zyx, s = _findMaxXcor(cc, win, gFit=gFit) #return cc #print(zyx, center) zyx -= center #c = imgFilters.cutOutCenter(c, N.array(c.shape) - (npad * 2), interpolate=False) #c = imgFilters.cutOutCenter(c, shape, interpolate=False) if ret == 3: return zyx, c, F.irfft(afa), F.irfft(bfa) elif ret == 2: return s, v, zyx, c elif ret: return v, zyx, c else: return zyx, c