def prepImg4Affine(fn, w=None, phaseContrast=True): an = aligner.Chromagnon(fn) an.findBestChannel() an.setRefImg() ref = an.img.get3DArr(w=an.refwave, t=0) prefyx = N.max(ref, axis=0) if w is None: waves = range(an.img.nw) waves.remove(an.refwave) w = waves[0] img = an.img.get3DArr(w=w, t=0) pimgyx = N.max(img, axis=0) yx, c = xcorr.Xcorr(prefyx, pimgyx, phaseContrast=phaseContrast) xs = N.round_(an.refxs - yx[1]).astype(N.int) if xs.max() >= an.img.nx: xsbool = (xs < an.img.nx) xsinds = N.nonzero(xsbool)[0] xs = xs[xsinds] imgyz = alignfuncs.prep2D(img.T, zs=xs) yz = alignfuncs.iterationXcor(imgyz, an.refyz, maxErr=an.maxErrZ, niter=an.niter, phaseContrast=an.phaseContrast, echofunc=an.echofunc) zs = N.round_(an.refzs - yz[1]).astype(N.int) if zs.max() >= an.img.nz: zsbool = (zs < an.img.nz) zsinds = N.nonzero(zsbool)[0] zs = zs[zsinds] imgyx = alignfuncs.prep2D(img, zs=zs) a1234 = alignfuncs.chopImg(imgyx) b1234 = alignfuncs.chopImg(an.refyx) ab = zip(a1234, b1234) yxcs = [xcorr.Xcorr(a, b, phaseContrast=phaseContrast) for a, b in ab] yxs = [yx for yx, c in yxcs] cqs = [c.max() - c[c.shape[0] // 4].std() for yx, c in yxcs] return ab, cqs, [c for yx, c in yxcs], yxs, an
def xcorNonLinear(arr, ref, npxls=32, threshold=None, phaseContrast=True, cthre=CTHRE, pxlshift_allow=0.5): """ arr: image to be registered ref: iamge to find the alignment parameter nplxs: number of pixels to divide (y,x) or scaler threshold: threshold value to decide if the region is to be cross correlated pahseContrast: phase contrast filter in cross correlation return (yx_arr, px_analyzed_arr[bool,var,cqual], result_arr) """ try: if len(npxls) != len(arr.shape): raise ValueError, 'length of the list of npxls must be the same as len(shape)' except TypeError: npxls = [npxls for d in range(len(arr.shape))] tslcs, arrs = chopImage2D(arr, npxls) rslcs, refs = chopImage2D(ref, npxls) if threshold is None: variance = (arr.var() + ref.var()) / 2. threshold = variance * 0.1 nsplit = (len(tslcs), len(tslcs[0])) yxs = N.zeros((2, ) + tuple(nsplit), N.float32) regions = N.zeros((3, ) + tuple(nsplit), N.float32) cs = N.zeros_like(arr) for y, ay in enumerate(arrs): for x, a in enumerate(ay): b = refs[y][x] av = imgFilters.cutOutCenter(a, 0.5, interpolate=False) bv = imgFilters.cutOutCenter(b, 0.5, interpolate=False) var = (N.var(av) + N.var(bv)) / 2. # crop to throw away the tip object regions[1, y, x] = var if var > threshold: yx, c = xcorr.Xcorr(a, b, phaseContrast=phaseContrast) cs[tslcs[y][x]] = c csd = c[:c.shape[0] // 4].std() cqual = c.max() - csd regions[2, y, x] = cqual if cqual >= cthre: # 0.3 is the max if N.abs(yx).max() < pxlshift_allow: #print yx.max() yxs[:, y, x] = yx regions[0, y, x] = 1 #else: #print 'yx too large', yx del c del arrs, refs #, c return yxs, regions, cs
def prepImg4AffineZ(fn, w=None, phaseContrast=True): an = aligner.Chromagnon(fn) an.findBestChannel() an.setRefImg() ref = an.img.get3DArr(w=an.refwave, t=0) prefyx = U.project(ref) #prefyz = U.project(ref, -1) if w is None: waves = range(an.img.nw) waves.remove(an.refwave) w = waves[0] img = an.img.get3DArr(w=w, t=0) pimgyx = U.project(img) #pimgyz = U.project(img, -1) #yz, c = xcorr.Xcorr(prefyz, pimgyz, phaseContrast=phaseContrast) yx, c = xcorr.Xcorr(prefyx, pimgyx, phaseContrast=phaseContrast) xs = N.round_(an.refxs - yx[1]).astype(N.int) if xs.max() >= an.img.nx: xsbool = (xs < an.img.nx) xsinds = N.nonzero(xsbool)[0] xs = xs[xsinds] imgyz = alignfuncs.prep2D(img.T, zs=xs) a1234 = alignfuncs.chopImg(an.refyz) b1234 = alignfuncs.chopImg(imgyz) ab = zip(a1234, b1234) yxcs = [xcorr.Xcorr(a, b, phaseContrast=phaseContrast) for a, b in ab] yxs = [yx for yx, c in yxcs] cqs = [c.max() - c[c.shape[0] // 4].std() for yx, c in yxcs] return ab, cqs, [c for yx, c in yxcs], yxs, an
def iterationXcor(a2d, ref, maxErr=0.01, niter=20, phaseContrast=True, initguess=None, echofunc=None): """ find out translation along X axis this function is used for alignment of the Z axis parameters are the same as 'iteration' return [ty,tx] """ shape = N.array(a2d.shape) yxs = N.zeros((2, ), N.float32) if initguess is not None: yxs[:] = initguess #if echofunc: # echofunc('initguess Xcorr: %s' % yxs) print 'initguess Xcorr:', yxs for i in xrange(niter): if i == 0 and initguess is None: b = a2d c = ref #startYX = [0,0] else: b = applyShift(a2d, [0] + list(yxs) + [0, 1, 1]) #, offset) # cut out shiftZYX = cutoutAlign.getShift([0] + list(yxs) + [0, 1, 1], [0] + list(shape)) maxcutY = max(shiftZYX[2], shape[0] - shiftZYX[3]) maxcutX = max(shiftZYX[4], shape[1] - shiftZYX[5]) slc = [ slice(int(shiftZYX[2]), int(shiftZYX[3])), slice(int(shiftZYX[4]), int(shiftZYX[5])) ] b = b[slc] c = ref[slc] yx = xcorr.Xcorr(c, b, phaseContrast=phaseContrast)[0] yxs += yx print 'xcorr', i, yxs #if echofunc: # echofunc('xcorr %i: %s' % (i, yx)) if yx[1] < maxErr: break return yxs
def estimate2D(a2d, ref, center=None, phaseContrast=True, cqthre=CTHRE / 10., max_shift_pxl=5): """ return [ty,tx,r,my,mx] """ if center is None: shape = N.array(a2d.shape) center = shape // 2 # quadratic cross correlation a1234 = chopImg(ref, center) b1234 = chopImg(a2d, center) ab = zip(a1234, b1234) try: yxcs = [ xcorr.Xcorr(a, b, phaseContrast=phaseContrast, searchRad=max_shift_pxl) for a, b in ab ] except IndexError: return N.array((0, 0, 0, 1, 1), N.float32), [0, 0], range(4) except (ValueError, ZeroDivisionError): raise AlignError yxs = [yx for yx, c in yxcs] # quality check cqvs = [c.max() - c[c.shape[0] // 4].std() for yx, c in yxcs] del yxcs, ab, c cqs = [cv > cqthre for cv in cqvs] ids = [idx for idx, cq in enumerate(cqs) if cq == False] # translation tyx = getTranslation(yxs) # magnification myx = getMagnification(yxs, center) # rotation theta, offset = getRotation(yxs, center) return list(tyx) + [theta] + list(myx), offset, ids
def testCorrelation(arr, win=64): from Priithon.all import U half = win / 2. arr = arr.copy() for i in range(10): v, z, y, x = U.findMax(arr) if y - half >= 0 and y + half < arr.shape[ 0] and x - half >= 0 and x + half < arr.shape[1]: a = arr[y - half:y + half, x - half:x + half] break else: arr[y, x] = 0 b = a.copy() yx, c = xcorr.Xcorr(a, b, phaseContrast=True) cme = c[:c.shape[0] // 4].mean() return c.max() - cme
def _xcorNonLinear(abyx, threshold, phaseContrast): a, b, y, x = abyx av = imgFilters.cutOutCenter(a, 0.5, interpolate=False) bv = imgFilters.cutOutCenter(b, 0.5, interpolate=False) var = (N.var(av) + N.var(bv)) / 2. # crop to throw away the tip object #regions[1,y,x] = var if var > threshold: yx, c = xcorr.Xcorr(a, b, phaseContrast=phaseContrast) #cs[tslcs[y][x]] = c csd = c[:c.shape[0] // 4].std() cqual = c.max() - csd #regions[2,y,x] = cqual #if cqual >= cthre: # 0.3 is the max #yxs[:,y,x] = yx #regions[0,y,x] = 1 # del c else: c = None cqual = 0 yx = 0 return c, var, cqual, yx, y, x
def iteration(a2d, ref, maxErr=0.01, niter=10, phaseContrast=True, initguess=None, echofunc=None, max_shift_pxl=5, if_failed='simplex'): """ iteratively do quadratic cross correlation a2d: image to be aligned ref: reference image maxErr: iteration is terminated when the calculated shift become less than this value (in pixel) niter: maximum number of iteration max_shift_pxl: number of pixels for you to allow the images to shift if_failed: 'terminate' or else return [ty,tx,r,my,mx] if_failed is 'terminate' and failed, return None """ shape = N.array(a2d.shape) center = shape // 2 ret = N.zeros((5, ), N.float32) ret[3:] = 1 if initguess is None or N.all(initguess[:2] == 0): yx, c = xcorr.Xcorr(ref, a2d, phaseContrast=phaseContrast) ret[:2] = yx else: print 'in iteration, initial geuss is', initguess ret[:] = initguess[:] if if_failed == 'force_simplex': goodImg = False else: goodImg = True rough = True offset = N.zeros((2, ), N.float32) for i in range(niter): if i == 0 and initguess is None: b = a2d c = ref startYX = [0, 0] else: b = applyShift(a2d, [0] + list(ret), offset) # cut out # because irregular size of the quadratic images are not favorable, # the smallest window will be used shiftZYX = cutoutAlign.getShift([0] + list(ret), [0] + list(shape)) maxcutY = max(shiftZYX[2], shape[0] - shiftZYX[3]) maxcutX = max(shiftZYX[4], shape[1] - shiftZYX[5]) slc = [ slice(int(maxcutY), int(shape[0] - maxcutY)), slice(int(maxcutX), int(shape[1] - maxcutX)) ] b = b[slc] c = ref[slc] startYX = [maxcutY, maxcutX] if goodImg: ll, curroff, checks = estimate2D(b, c, center - startYX + offset, phaseContrast=phaseContrast, max_shift_pxl=max_shift_pxl) if len(checks) <= 1: ret[:3] += ll[:3] ret[3:] *= ll[3:] # the quality of quadratic correlation affects resolution. # instead of using low-correlation results, such images are sent to alternative calculation. if len(checks): if if_failed == 'terminate': return elif echofunc: regions = [QUADRATIC_AREA[idx] for idx in checks] echofunc( '%s quadratic regions had too-low correlation, using alternative, slow algorithm' % regions) else: regions = [QUADRATIC_AREA[idx] for idx in checks] print '%s quadratic regions had too-low correlation, using alternative, slow algorithm' % regions goodImg = False checks = [] if initguess is not None: ret[:] = initguess[:] #elif i > 5: #offset += curroff else: ll = simplex(b, c, phaseContrast, rough=rough) ret[:3] += ll[:3] ret[3:] *= ll[3:] rough = False #if echofunc: #echofunc('%i: %s' % (i, ll))#ref)) print i, ret errs = errPxl(ll, center) if N.all(errs < maxErr): break return ret #, offset
def findAlignParamWave(self, t=0, doWave=True, init_t=None): """ do findBestChannel() before calling this function init_t: time frame for the initial guess, None uses the same as t return nw*[tz,ty,tx,r,mz,my,mx] """ if self.refyz is None or self.refyx is None: self.setRefImg() if init_t is None: init_t = t ret = self.alignParms[init_t].copy() if N.any(ret[:,:-3]): doXcorr = False else: doXcorr = True for w in range(self.img.nw): if (doWave and w == self.refwave) or (not doWave and w != self.refwave): continue # vertical alignment if self.img.nz > 1: img = self.img.get3DArr(w=w, t=t) # get initial guess if no initial guess was given if doXcorr: self.echo('makeing an initial guess for channel %i' % w) ref = self.img.get3DArr(w=self.refwave, t=t) prefyx = N.max(ref, 0) pimgyx = N.max(img, 0) searchRad = self.max_shift_pxl * 2 if searchRad > min((self.img.nx, self.img.ny)): searchRad = min((self.img.nx, self.img.ny)) yx, c = xcorr.Xcorr(prefyx, pimgyx, phaseContrast=self.phaseContrast, searchRad=searchRad) ret[w,1:3] = yx del ref, c # create 2D projection image self.echo('calculating shifts for time %i channel %i' % (t, w)) xs = N.round_(self.refxs-ret[w,2]).astype(N.int) if xs.max() >= self.img.nx: xsbool = (xs < self.img.nx) xsinds = N.nonzero(xsbool)[0] xs = xs[xsinds] imgyz = af.prep2D(img.T, zs=xs) # try quadratic cross correlation zdif = max(self.refzs) - min(self.refzs) if (self.zmagSwitch != ZMAG_CHOICE[2]) and ((zdif > 5 and self.img.nz > 30) or self.zmagSwitch == ZMAG_CHOICE[1]): initguess = N.zeros((5,), N.float32) initguess[:2] = ret[w,:2][::-1] initguess[2:] = ret[w,3:6] if zdif > 5 and self.img.nz > 10 and self.zmagSwitch == ZMAG_CHOICE[1]:#'simplex': if_failed = 'force_simplex' else: if_failed = 'terminate' check = af.iteration(imgyz, self.refyz, maxErr=self.maxErrZ, niter=self.niter, phaseContrast=self.phaseContrast, initguess=initguess, echofunc=self.echofunc, max_shift_pxl=self.max_shift_pxl, if_failed=if_failed) if check is not None: ty2,tz,_,_,mz = check ret[w,0] = tz ret[w,4] = mz else: # chage to normal cross correlation initguess = ret[w,:2][::-1] yz = af.iterationXcor(imgyz, self.refyz, maxErr=self.maxErrZ, niter=self.niter, phaseContrast=self.phaseContrast, initguess=initguess, echofunc=self.echofunc) ret[w,0] = yz[1] # since number of section is not enough, do normal cross correlation else: initguess = ret[w,:2][::-1] yz = af.iterationXcor(imgyz, self.refyz, maxErr=self.maxErrZ, niter=self.niter, phaseContrast=self.phaseContrast, initguess=initguess, echofunc=self.echofunc) ret[w,0] = yz[1] zs = N.round_(self.refzs-ret[w,0]).astype(N.int) if zs.max() >= self.img.nz: zsbool = (zs < self.img.nz) zsinds = N.nonzero(zsbool)[0] zs = zs[zsinds] imgyx = af.prep2D(img, zs=zs) del img else: imgyx = self.img.getArr(w=w, t=t, z=0) initguess = N.zeros((5,), N.float32) initguess[:3] = ret[w,1:4] # ty,tx,r initguess[3:] = ret[w,5:7] # my, mx try: ty,tx,r,my,mx = af.iteration(imgyx, self.refyx, maxErr=self.maxErrYX, niter=self.niter, phaseContrast=self.phaseContrast, initguess=initguess, echofunc=self.echofunc, max_shift_pxl=self.max_shift_pxl) except ZeroDivisionError: if self.phaseContrast: ty,tx,r,my,mx = af.iteration(imgyx, self.refyx, maxErr=self.maxErrYX, niter=self.niter, phaseContrast=False, initguess=initguess, echofunc=self.echofunc, max_shift_pxl=self.max_shift_pxl) else: # XY alignment failed raise ret[w,1:4] = ty,tx,r ret[w,5:7] = my,mx if self.img.nz > 1: self.echo('time: %i, wave: %i, tx:%.3f, ty:%.3f, tz:%.3f, r:%.3f, mx:%.3f, my:%.3f, mz:%.3f' % (t,w,tx,ty,ret[w,0],r,mx,my,ret[w,4])) else: self.echo('time: %i, wave: %i, tx:%.3f, ty:%.3f, r:%.3f, mx:%.3f, my:%.3f' % (t,w,tx,ty,r,mx,my)) self.alignParms[t] = ret # final 3D cross correlation searchRad = self.max_shift_pxl * 2 if searchRad > min((self.img.nx, self.img.ny)): searchRad = min((self.img.nx, self.img.ny)) ref = self.get3DArrayAligned(w=self.refwave, t=t) for w in xrange(self.img.nw): if (doWave and w == self.refwave) or (not doWave and w != self.refwave): continue self.echo('3D cross correlation for time %i channel %i' % (t, w)) img = self.get3DArrayAligned(w=w, t=t) zyx, c = xcorr.Xcorr(ref, img, phaseContrast=self.phaseContrast, searchRad=searchRad) if len(zyx) == 2: zyx = N.array([0] + list(zyx)) self.alignParms[t,w,:3] += zyx print 'the result of the last correlation', zyx self.echo('Finding affine parameters done!')
def testNonlinear(arr, ref, npxls=32, phaseContrast=True, centerDot=True): try: if len(npxls) != len(arr.shape): raise ValueError, 'length of the list of npxls must be the same as len(shape)' except TypeError: npxls = [npxls for d in range(len(arr.shape))] arr = arr.astype(N.float32) ref = ref.astype(N.float32) tslcs, arrs = alignfuncs.chopImage2D(arr, npxls) rslcs, refs = alignfuncs.chopImage2D(ref, npxls) nsplit = (len(tslcs), len(tslcs[0])) yxs = N.zeros((2, ) + tuple(nsplit), N.float32) quality = N.zeros((4, ) + nsplit, N.float32) cs = N.zeros_like(arr) variance = (arr.var() + ref.var()) / 2. agrid = arr.copy() bgrid = ref.copy() ame = agrid.max() / 2. bme = bgrid.max() / 2. for y, yslc in enumerate(tslcs): agrid[(yslc[0][0].start - 1):(yslc[0][0].start + 1), :] = ame bgrid[(yslc[0][0].start - 1):(yslc[0][0].start + 1), :] = bme agrid[(yslc[0][0].stop - 1):(yslc[0][0].stop + 1), :] = ame bgrid[(yslc[0][0].stop - 1):(yslc[0][0].stop + 1), :] = bme for x, slc in enumerate(yslc): agrid[:, (slc[1].start - 1):(slc[1].start + 1)] = ame bgrid[:, (slc[1].start - 1):(slc[1].start + 1)] = bme agrid[:, (slc[1].stop - 1):(slc[1].stop + 1)] = ame bgrid[:, (slc[1].stop - 1):(slc[1].stop + 1)] = bme for y, ay in enumerate(arrs): for x, a in enumerate(ay): b = refs[y][x] slc = tslcs[y][x] s, v, yx, c = xcorr.Xcorr(a, b, phaseContrast=phaseContrast, ret=2) yxs[:, y, x] = yx cs[slc] = c quality[0, y, x] = ( (N.var(a[2:-2, 2:-2]) + N.var(b[2:-2, 2:-2])) / 2.) / variance pea = alignfuncs.calcPearson(a, b) quality[1, y, x] = pea #cme = c[:c.shape[0]//4].mean() csd = c[:c.shape[0] // 4].std() quality[2, y, x] = c.max() - csd #me quality[3, y, x] = N.mean(s) #.mean()#c.max() - csd agrid = normalize(agrid) * 0.3 bgrid = normalize(bgrid) * 0.3 #cs = normalize(cs) cme = cs.max() / 2. for y, yslc in enumerate(tslcs): cs[(yslc[0][0].start - 1):(yslc[0][0].start + 1), :] = cme if centerDot: cs[(yslc[0][0].start - 1 + npxls[0] // 2):(yslc[0][0].start + 1 + npxls[0] // 2), ::10] = cme cs[(yslc[0][0].stop - 1):(yslc[0][0].stop + 1), :] = cme for x, slc in enumerate(yslc): cs[:, (slc[1].start - 1):(slc[1].start + 1)] = cme if centerDot: cs[::10, (slc[1].start - 1 + npxls[1] // 2):(slc[1].start + 1 + npxls[1] // 2)] = cme cs[:, (slc[1].stop - 1):(slc[1].stop + 1)] = cme v = N.where(quality[0] > 0.1, 1, 0) q = N.where(quality[2] > 0.065, 1, 0) yxq = yxs * v * q return yxs, N.array((agrid, bgrid, cs)), quality, N.abs(yxq)