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 gaussianArr2D( shape=(256, 256), sigma=[2., 2.], peakVal=None, orig=None, rot=0): """ >1.5x faster implemetation than gaussianArrND shape: (y,x) sigma: scaler or [sigmay, sigmax] orig: (y,x) rot: scaler anti-clockwise return N.float32 """ shape = N.asarray(shape, N.uint) try: if len(sigma) == len(shape): sy = 2 * (sigma[0] * sigma[0]) sx = 2 * (sigma[1] * sigma[1]) elif len(sigma) == 1: sx = sy = 2 * (sigma[0] * sigma[0]) else: raise ValueError, 'sigma must be scaler or [sigmay, sigmax]' except TypeError: # sigma scaler sx = sy = 2 * (sigma * sigma) # print y, x if rot: yyi, xxi = imgFit.rotateIndices2D(shape, rot, orig, N.float32) else: if orig is None: y, x = shape / 2. - 0.5 # pixel center remove else: y, x = N.subtract(orig, 0.5) # pixel center remove yi, xi = N.indices(shape, dtype=N.float32) yyi = y - yi xxi = x - xi k1 = -(yyi) * (yyi) / (sy) - (xxi) * (xxi) / (sx) if peakVal: k0 = peakVal else: k0 = 1. / ((sx + sy) / 2. * ((2 * N.pi)**0.5)) return k0 * N.exp(k1)
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 getSphericalAbbe(arr3D, kmin=2, kmax=60, plot=False): """ compare frequency above and below the focus return amplitude var(above)/var(below) """ afz = getFourierZprofile(arr3D) # get z profile around the reasonable frequency aa = N.abs(N.average(afz[:, kmin:kmax], axis=1)) # previously it was N.average(N.abs(afz[:,kmin:kmax]), axis=1), but that seems wrong... # findMax inds = N.indices(aa.shape, dtype=N.float64) v, _0, _1, z = U.findMax(aa) parm, check = imgFit.fitGaussianND(aa, [z], window=len(aa)) if check == 5: raise RuntimeError, 'Peak not found check=%i' % check gg = imgFit.yGaussianND(parm, inds, 3) amg = aa - gg z0 = parm[2] mask = (parm[-1] * 3) / 2. # sigma * 3 / 2 ms0 = N.ceil(z0 - mask) ms1 = N.ceil(z0 + mask) amg[ms0:ms1] = 0 below = N.var(amg[:ms0]) above = N.var(amg[ms1:]) if plot: Y.ploty(N.array((aa, gg, amg))) print 'below: ', below print 'above: ', above print ms0, ms1, z0 return above / (above + below) #above / below
def Xcorr(a, b, highpassSigma=2.5, wiener=0.2, cutoffFreq=3, forceSecondPeak=None, acceptOrigin=True, maskSigmaFact=1., removeY=None, removeX=None, ret=None, normalize=True, gFit=True, lap=None, win=11): """ returns (y,x), image if ret is True, returns [v, yx, image] to get yx cordinate of the image, yx += N.divide(picture.shape, 2) a, b: 2D array highpassSigma: sigma value used for highpass pre-filter wiener: wiener value used for highpass pre-filter cutoffFreq: kill lowest frequency component from 0 to this level forceSecondPeak: If input is n>0 (True is 1), pick up n-th peak acceptOrigin: If None, result at origin is rejected, look for the next peak maskSigmaFact: Modifier to remove previous peak to look for another peak removeYX: Rremove given number of pixel high intensity lines of the Xcorr Y: Vertical, X: Horizontal normalize: intensity normalized gFit: peak is fitted to 2D gaussian array, if None use center of mass win: window for gFit if b is a + (y,x) then, answer is (-y,-x) """ shapeA = N.asarray(a.shape) shapeB = N.asarray(b.shape) shapeM = N.max([shapeA, shapeB], axis=0) shapeM = N.where(shapeM % 2, shapeM + 1, shapeM) center = shapeM / 2. arrs = [a, b] arrsS = ['a', 'b'] arrsF = [] for i, arr in enumerate(arrs): if arr.dtype not in [N.float32, N.float64]: arr = N.asarray(arr, N.float32) # this convolution has to be done beforehand to remove 2 pixels at the edge if lap == 'nothing': pass elif lap: arr = arr_Laplace(arr, mask=2) else: arr = arr_sorbel(arr, mask=1) if N.sometrue(shapeA < shapeM): arr = paddingMed(arr, shapeM) if normalize: mi, ma, me, sd = U.mmms(arr) arr = (arr - me) / sd if i == 1: arr = F.shift(arr) af = F.rfft(arr) af = highPassF(af, highpassSigma, wiener, cutoffFreq) arrsF.append(af) # start cross correlation af, bf = arrsF bf = bf.conjugate() cf = af * bf # go back to space domain c = F.irfft(cf) # c = _changeOrigin(cr) # removing lines if removeX: yi, xi = N.indices((removeX, shapeM[-1])) #sx)) yi += center[-2] - removeX / 2. #sy/2 - removeX/2 c[yi, xi] = 0 if removeY: yi, xi = N.indices((shapeM[-2], removeY)) #sy, removeY)) xi += center[-1] - removeY / 2. #sx/2 - removeY/2 c[yi, xi] = 0 # find the first peak if gFit: v, yx, s = findMaxWithGFit(c, win=win) #, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win + 2) #, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx = N.add(yx, 0.5) #yx += 0.5 else: vzyx = U.findMax(c) v = vzyx[0] yx = vzyx[-2:] s = 2.5 yx -= center if N.alltrue(N.abs(yx) < 1.0) and not acceptOrigin: forceSecondPeak = True # forceSecondPeak: if not forceSecondPeak: forceSecondPeak = 0 for i in range(int(forceSecondPeak)): print '%i peak was removed' % (i + 1) #, sigma: %.2f' % (i+1, s) yx += center g = gaussianArr2D(c.shape, sigma=s / maskSigmaFact, peakVal=v, orig=yx) c = c - g #c = mask_gaussian(c, yx[0], yx[1], v, s) if gFit: v, yx, s = findMaxWithGFit(c, win=win) #, window=win, gFit=gFit) if v == 0: v, yx, s = findMaxWithGFit(c, win=win + 2) #, window=win+2, gFit=gFit) if v == 0: v = U.findMax(c)[0] yx -= (center - 0.5) else: vzyx = U.findMax(c) v = vzyx[0] if not gFit: yx = centerOfMass(c, vzyx[-2:]) - center if lap is not 'nothing': c = paddingValue(c, shapeM + 2) if ret == 2: return yx, af, bf.conjugate() elif ret: return v, yx, c else: return yx, c