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 rotateIndices2DNew(shape, rot, orig=None, dtype=N.float64): """ shape: 2D rot: anti-clockwise orig: (y, x) return: yi, xi """ # FIX ME Rot is something wrong!! 081027 shape = N.asarray(shape, N.int) if orig is None: y, x = shape / 2. else: y, x = orig print(y, x) if not rot: yi, xi = N.indices(shape, dtype=N.float64) yi -= y - 0.5 # remove pix center xi -= x - 0.5 return yi, xi # twice as large window # mo = N.abs(N.mod(shape, 2) + [-1,-1]) s2 = shape * 2 #+ mo # always odd for even shape, even for odd shape yi, xi = N.indices(s2, dtype=N.float32) mm = N.ceil(shape / 2.) #(s2 -1 - shape)//2 # offset always int yi -= mm[0] xi -= mm[1] pxc = imgGeo.RotateXY((0.5, 0.5), rot) # remove pix center yi += pxc[0] xi += pxc[1] y0, x0 = shape / 2. #N.ceil(shape / 2) # img center yc = y0 - y # delta rotation center xc = x0 - x yi = U.trans2d(yi, None, (xc, yc, rot, 1, 0, 1)) xi = U.trans2d(xi, None, (xc, yc, rot, 1, 0, 1)) yi = U.trans2d(yi, None, (-xc, -yc, 0, 1, 0, 1)) xi = U.trans2d(xi, None, (-xc, -yc, 0, 1, 0, 1)) yi = yi.astype(dtype) xi = xi.astype(dtype) yi -= y xi -= x yi = imgFilters.cutOutCenter(yi, shape) xi = imgFilters.cutOutCenter(xi, shape) return yi, xi
def rotateIndices2DNew(shape, rot, orig=None, dtype=N.float64): """ shape: 2D rot: anti-clockwise orig: (y, x) return: yi, xi """ # FIX ME Rot is something wrong!! 081027 shape = N.asarray(shape, N.int) if orig is None: y, x = shape / 2. else: y, x = orig print(y,x) if not rot: yi,xi = N.indices(shape, dtype=N.float64) yi -= y - 0.5 # remove pix center xi -= x - 0.5 return yi,xi # twice as large window # mo = N.abs(N.mod(shape, 2) + [-1,-1]) s2 = shape * 2 #+ mo # always odd for even shape, even for odd shape yi, xi = N.indices(s2, dtype=N.float32) mm = N.ceil(shape / 2.)#(s2 -1 - shape)//2 # offset always int yi -= mm[0] xi -= mm[1] pxc = imgGeo.RotateXY((0.5,0.5), rot) # remove pix center yi += pxc[0] xi += pxc[1] y0, x0 = shape / 2. #N.ceil(shape / 2) # img center yc = y0 - y # delta rotation center xc = x0 - x yi = U.trans2d(yi, None, (xc,yc,rot,1,0,1)) xi = U.trans2d(xi, None, (xc,yc,rot,1,0,1)) yi = U.trans2d(yi, None, (-xc,-yc,0,1,0,1)) xi = U.trans2d(xi, None, (-xc,-yc,0,1,0,1)) yi = yi.astype(dtype) xi = xi.astype(dtype) yi -= y xi -= x yi = imgFilters.cutOutCenter(yi, shape) xi = imgFilters.cutOutCenter(xi, shape) return yi, xi
def _indLD(win, y, x): """ return yi, xi, LD """ try: len(win) yi, xi = N.indices(int(win)) except TypeError: yi, xi = N.indices((int(win), int(win))) yx = N.asarray((y, x)) LD = yx - win / 2. + 0.5 # use pixel center yi += LD[0] xi += LD[1] return yi, xi, LD
def _indLD(win, y, x): """ return yi, xi, LD """ try: len(win) yi, xi = N.indices(int(win)) except TypeError: yi, xi = N.indices((int(win), int(win))) yx = N.asarray((y, x)) LD = yx - win/2. + 0.5 # use pixel center yi += LD[0] xi += LD[1] return yi, xi, LD
def indicesFromSlice(slicelist, dtype=N.float64): """ return inds, LD """ shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) inds = N.indices(shape, dtype) for i, ld in enumerate(LD): inds[i] += ld return inds, LD
def indicesFromSlice(slicelist, dtype=N.float64): """ return inds, LD """ shape = [] LD = [] for sl in slicelist: if isinstance(sl, slice): shape.append(sl.stop - sl.start) LD.append(sl.start) inds = N.indices(shape, dtype) for i, ld in enumerate(LD): inds[i] += ld return inds, LD
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 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 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 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, 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
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
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