def recalcHist(self, i, postponeToIdle): if postponeToIdle: self.recalcHist_todo_Set.add(i) return img = self.data[ tuple(self.zsec) ][i] from . import useful as U mmms = U.mmms( img ) self.mmms[i] = mmms #time import time #time x = time.clock() # print mmms from . import useful as U if self.hist_arr[i] is not None: #glSeb import time #glSeb x = time.clock() # print U.mmms(self.hist_arr[i]), U.histogram(img, amin=self.hist_min[i], amax=self.hist_max[i], histArr=self.hist_arr[i]) # print U.mmms(self.hist_arr[i]) self.hist[i].setHist(self.hist_arr[i], self.hist_min[i], self.hist_max[i]) #glSeb print "ms: %.2f"% ((time.clock()-x)*1000.0) ## FIXME setHist needs to NOT alloc xArray every time !!! else: resolution = 10000 a_h = U.histogram(img, resolution, mmms[0], mmms[1]) self.hist[i].setHist(a_h, mmms[0], mmms[1])
def recalcHist(self, i, postponeToIdle): if postponeToIdle: self.recalcHist_todo_Set.add(i) return img = self.data[tuple(self.zsec)][i] from . import useful as U mmms = U.mmms(img) self.mmms[i] = mmms #time import time #time x = time.clock() # print mmms from . import useful as U if self.hist_arr[i] is not None: #glSeb import time #glSeb x = time.clock() # print U.mmms(self.hist_arr[i]), U.histogram(img, amin=self.hist_min[i], amax=self.hist_max[i], histArr=self.hist_arr[i]) # print U.mmms(self.hist_arr[i]) self.hist[i].setHist(self.hist_arr[i], self.hist_min[i], self.hist_max[i]) #glSeb print "ms: %.2f"% ((time.clock()-x)*1000.0) ## FIXME setHist needs to NOT alloc xArray every time !!! else: resolution = 10000 a_h = U.histogram(img, resolution, mmms[0], mmms[1]) self.hist[i].setHist(a_h, mmms[0], mmms[1])
def save(self, baseFn=None): """save Mosaic size/pos/scale info in baseFn.txt save all images into baseFn_xx.mrc """ from Priithon.all import Mrc, U if baseFn is None: from .usefulX import FN baseFn = FN(1) if not baseFn: return a = N.concatenate((self.m_imgPosArr, self.m_imgSizeArr, N.array(self.m_imgRotArr,)[:,N.newaxis], self.m_imgScaleMM), 1) U.writeArray(a, baseFn + '.txt') n = len(self.m_imgSizeArr) for i in range( n ): # Mrc.save(self.m_imgArrL[i], "%s_%02d.mrc" % (baseFn, i)) #20070126 m = Mrc.Mrc("%s_%02d.mrc" % (baseFn, i), "w+", self.m_imgArrL[i] ) #20070126 m.calcMMM() #20070126 m.hdr('d')[:] = tuple(self.m_imgSizeArr[i] / N.array((self.m_imgArrL[i].shape))[::1]) + (1,) #20070126 m.hdr('zxy0')[:] = (0,) + tuple(self.m_imgPosArr[i]) #20070126 m.hdr('mmm1')[:] = tuple(self.m_imgScaleMM[i]) + (1,) #20070126 m.flush() #20070126 m.close() d = tuple(self.m_imgSizeArr[i] / N.array((self.m_imgArrL[i].shape), dtype=N.float32)[::1]) + (1,) zxy0 = (0,) + tuple(self.m_imgPosArr[i]) Mrc.save(self.m_imgArrL[i], "%s_%02d.mrc" % (baseFn, i), hdrEval='''hdr.d = d; hdr.zxy0 = zxy0''' )
def findBestRefZs(ref, sigma=1): """ PSF spread along the Z axis is often tilted in the Y or X axis. Thus simple maximum intensity projection may lead to the wrong answer to estimate rotation and magnification. On the other hands, taking a single section may also contain out of focus flare from neighboring sections that are tilted. Therefore, here sections with high complexity are selected and projected. ref: 3D array return z idx at the focus """ nz = ref.shape[0] if ref.ndim == 2: return [0] elif nz <= 3: return range(nz) # Due to the roll up after FFT, the edge sections in Z may contain different information among the channels. Thus these sections are left unused. ms = N.zeros((nz - 2, ), N.float32) for z in range(1, nz - 1): arr = ref[z] ms[z - 1] = N.prod(U.mmms(arr)[-2:]) # mean * std mi, ma, me, st = U.mmms(ms) thr = me + st * sigma ids = [idx for idx in range(1, nz - 1) if ms[idx - 1] > thr] if not ids: ids = range(1, nz - 1) return ids
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 yCos(parm, r=0): """ parm: (amp,freq,phase,mean) amp * N.sin(freq*r + phase(deg)) + mean r: degree (not radian!!) """ a, b, c, d = parm r = U.deg2rad(r) c = U.deg2rad(c) return a * N.cos(b * r + c) + d
def yCos(parm, r=0): """ parm: (amp,freq,phase,mean) amp * N.sin(freq*r + phase(deg)) + mean r: degree (not radian!!) """ a, b, c, d = parm r = U.deg2rad(r) c = U.deg2rad(c) return a * N.cos(b*r + c) + d
def fitSkew1D(img, ts=None, sigma=0.5, exp=0): """ img: 1D array containg one skewd gaussian peak """ mi, ma, me, sd = U.mmms(img) ma, _1, _2, t = U.findMax(img) if ts is not None: t = ts[t] img = list(zip(ts, img)) return U.fitAny(ySkew, (mi, ma - mi, t, sigma, exp), img, warning=None)
def fitSkew1D(img, ts=None, sigma=0.5, exp=0): """ img: 1D array containg one skewd gaussian peak """ mi, ma, me, sd = U.mmms(img) ma, _1, _2, t = U.findMax(img) if ts is not None: t = ts[t] img = list(zip(ts, img)) return U.fitAny(ySkew, (mi, ma-mi, t, sigma, exp), img, warning=None)
def onMove(self, xEff, yEff, ev): #self.oldOnMouse(xEff, yEff, xyEffVal) # show label info self.yx1 = y1,x1 = int(round(yEff)), int(round(xEff)) y0,x0 = self.yx0 dy = y1-y0 dx = x1-x0 from Priithon.all import U # even size if ev.AltDown(): dy2 = int(dy / 2) * 2 dx2 = int(dx / 2) * 2 y1 = y0 + dy2 x1 = x0 + dx2 self.yx1 = (y1,x1) dy = y1-y0 dx = x1-x0 #power of two if ev.ShiftDown() and ev.ControlDown(): ddy = N.log(abs(dy)) / log2 dy2 = 2 ** int(ddy+.5) ddx = N.log(abs(dx)) / log2 dx2 = 2 ** int(ddx+.5) y1 = y0 + dy2 * U.sgn(dy) x1 = x0 + dx2 * U.sgn(dx) self.yx1 = (y1,x1) dy = y1-y0 dx = x1-x0 #square elif ev.ShiftDown() or ev.ControlDown(): if abs(dx) < abs(dy): x1 = x0 + abs(dy) * U.sgn(dx) self.yx1 = (y1,x1) elif abs(dy) < abs(dx): y1 = y0 + abs(dx) * U.sgn(dy) self.yx1 = (y1,x1) dx = x1-x0 dy = y1-y0 if self.splitND is not None: self.splitND.label.SetLabel("h,w: %3d %3d" % (abs(dy),abs(dx))) self.gfxUpdate() #self.viewer.updateGlList( self.my_defGlList ) self.doThisAlsoOnMove()
def OnSaveScreenShort(self, event=None): '''always flipY''' from Priithon.all import U, FN fn = FN(1, verbose=0) if not fn: return flipY=1 if flipY: U.saveImg(self.readGLviewport(copy=1)[:, ::-1], fn) else: U.saveImg(self.readGLviewport(copy=1), fn)
def OnSaveScreenShort(self, event=None): '''always flipY''' from Priithon.all import U, FN fn = FN(1, verbose=0) if not fn: return flipY = 1 if flipY: U.saveImg(self.readGLviewport(copy=1)[:, ::-1], fn) else: U.saveImg(self.readGLviewport(copy=1), fn)
def onMove(self, xEff, yEff, ev): #self.oldOnMouse(xEff, yEff, xyEffVal) # show label info self.yx1 = y1, x1 = int(round(yEff)), int(round(xEff)) y0, x0 = self.yx0 dy = y1 - y0 dx = x1 - x0 from Priithon.all import U # even size if ev.AltDown(): dy2 = int(dy / 2) * 2 dx2 = int(dx / 2) * 2 y1 = y0 + dy2 x1 = x0 + dx2 self.yx1 = (y1, x1) dy = y1 - y0 dx = x1 - x0 #power of two if ev.ShiftDown() and ev.ControlDown(): ddy = N.log(abs(dy)) / log2 dy2 = 2**int(ddy + .5) ddx = N.log(abs(dx)) / log2 dx2 = 2**int(ddx + .5) y1 = y0 + dy2 * U.sgn(dy) x1 = x0 + dx2 * U.sgn(dx) self.yx1 = (y1, x1) dy = y1 - y0 dx = x1 - x0 #square elif ev.ShiftDown() or ev.ControlDown(): if abs(dx) < abs(dy): x1 = x0 + abs(dy) * U.sgn(dx) self.yx1 = (y1, x1) elif abs(dy) < abs(dx): y1 = y0 + abs(dx) * U.sgn(dy) self.yx1 = (y1, x1) dx = x1 - x0 dy = y1 - y0 if self.splitND is not None: self.splitND.label.SetLabel("h,w: %3d %3d" % (abs(dy), abs(dx))) self.gfxUpdate() #self.viewer.updateGlList( self.my_defGlList ) self.doThisAlsoOnMove()
def recalcHist(self, triggeredFromIdle): if not triggeredFromIdle: self.recalcHist_todo_Set.add(0) return #CHECK img = self.viewer.m_imgArr img = self.img from . import useful as U mmms = U.mmms( img ) self.mmms = mmms #time import time #time x = time.clock() # print mmms if self.hist_arr is not None: #glSeb import time #glSeb x = time.clock() if sys.platform.startswith('linux'): # 20180712 win SIM error wx.Yield() # 20180406 dileptus linux U.histogram(img, amin=self.hist_min, amax=self.hist_max, histArr=self.hist_arr) self.hist.setHist(self.hist_arr, self.hist_min, self.hist_max) #glSeb print "ms: %.2f"% ((time.clock()-x)*1000.0) ## FIXME setHist needs to NOT alloc xArray every time !!! else: # self.viewer.m_imgChanged = True # self.viewer.Refresh(False) #20040915(OverflowError: float too large to convert) resolution = int(mmms[1]-mmms[0]+2) #20040915if resolution > 10000: #20040915 resolution = 10000 #20040915elif resolution < 1000: #CHECK #20040915 resolution = 10000 # CHECK resolution = 10000 a_h = U.histogram(img, resolution, mmms[0], mmms[1]) # self.hist.setHist(a_h, mmms[0], mmms[1]) self.recalcHist__a_h = a_h self.recalcHist__Done = 1 #time print "recalcHist ms: %.2f"% ((time.clock()-x)*1000.0) #20171225 py2to3 if wx.VERSION[0] <= 3: mainthread = wx.Thread_IsMain() elif wx.VERSION[0] >= 4: mainthread = wx.IsMainThread() if mainthread:#wx.IsMainThread():#Thread_IsMain(): self.hist.setHist(self.recalcHist__a_h, self.mmms[0], self.mmms[1]) else: wx.PostEvent(self.frame, self.__class__.ResultEvent(None))
def OnSave(self, event=None): from Priithon.all import Mrc, U, Y fn = Y.FN(1) #, verbose=0) if not fn: return if fn[-4:] in [".mrc", ".dat"]: Mrc.save(self.m_imgArr, fn) elif fn[-5:] in [".fits"]: U.saveFits(self.m_imgArr, fn) else: U.saveImg8(self.m_imgArr, fn) Y.shellMessage("### section saved to '%s'\n" % fn)
def OnSave(self, event=None): from Priithon.all import Mrc, U, Y fn = Y.FN(1)#, verbose=0) if not fn: return if fn[-4:] in [ ".mrc", ".dat" ]: Mrc.save(self.m_imgArr, fn) elif fn[-5:] in [ ".fits" ]: U.saveFits(self.m_imgArr, fn) else: U.saveImg8(self.m_imgArr, fn) Y.shellMessage("### section saved to '%s'\n"%fn)
def OnSaveScreenShort(self, event=None): """always flipY""" from Priithon.all import U, FN, Y fn = FN(1)#, verbose=0) if not fn: return flipY=1 if flipY: U.saveImg(self.readGLviewport(copy=1)[:, ::-1], fn) else: U.saveImg(self.readGLviewport(copy=1), fn) Y.shellMessage("### screenshot saved to '%s'\n"%fn)
def OnSaveScreenShort(self, event=None): """always flipY""" from Priithon.all import U, FN, Y fn = FN(1) #, verbose=0) if not fn: return flipY = 1 if flipY: U.saveImg(self.readGLviewport(copy=1)[:, ::-1], fn) else: U.saveImg(self.readGLviewport(copy=1), fn) Y.shellMessage("### screenshot saved to '%s'\n" % fn)
def recalcHist(self, triggeredFromIdle): if not triggeredFromIdle: self.recalcHist_todo_Set.add(0) return #CHECK img = self.viewer.m_imgArr img = self.img from . import useful as U mmms = U.mmms(img) self.mmms = mmms #time import time #time x = time.clock() # print mmms if self.hist_arr is not None: #glSeb import time #glSeb x = time.clock() wx.Yield() # 20180406 dileptus U.histogram(img, amin=self.hist_min, amax=self.hist_max, histArr=self.hist_arr) self.hist.setHist(self.hist_arr, self.hist_min, self.hist_max) #glSeb print "ms: %.2f"% ((time.clock()-x)*1000.0) ## FIXME setHist needs to NOT alloc xArray every time !!! else: # self.viewer.m_imgChanged = True # self.viewer.Refresh(False) #20040915(OverflowError: float too large to convert) resolution = int(mmms[1]-mmms[0]+2) #20040915if resolution > 10000: #20040915 resolution = 10000 #20040915elif resolution < 1000: #CHECK #20040915 resolution = 10000 # CHECK resolution = 10000 a_h = U.histogram(img, resolution, mmms[0], mmms[1]) # self.hist.setHist(a_h, mmms[0], mmms[1]) self.recalcHist__a_h = a_h self.recalcHist__Done = 1 #time print "recalcHist ms: %.2f"% ((time.clock()-x)*1000.0) #20171225 py2to3 if wx.IsMainThread(): #Thread_IsMain(): self.hist.setHist(self.recalcHist__a_h, self.mmms[0], self.mmms[1]) else: wx.PostEvent(self.frame, self.__class__.ResultEvent(None))
def findBestChannel(self, t=0): """ the reference wavelength is determined from the wavelength and intensity set self.refwave (in index) """ if self.refwave is not None: self.refwave = self.img.getWaveIdx(self.refwave) else: # if time laplse if self.img.nt > 1: # how large the object is... arrs = [self.img.get3DArr(w=w, t=t).ravel() for w in range(self.img.nw)] modes = [imgFilters.mode(a[::50]) for a in arrs] fpxls = [N.where(a > modes[i])[0].size/float(a.size) for i, a in enumerate(arrs)] # bleach half time halfs = [] for w in range(self.nw): mes = [self.img.get3DArr(w=w, t=t).mean() for t in range(self.nt)] parm, check = U.fitDecay(mes) halfs.append(parm[-1] / float(self.nt)) channels = N.add(fpxls, halfs) refwave = N.argmax(channels) print('The channel to align is %i' % refwave) # if wavelengths are only 2, then use the channel 0 elif self.img.nw <= 2: refwave = 0 # take into account for the PSF distortion due to chromatic aberration elif self.img.nw > 2: pwrs = N.array([self.img.get3DArr(w=w, t=t).mean() for w in range(self.img.nw)]) # the middle channel should have the intermediate PSF shape waves = [self.img.getWaveFromIdx(w) for w in range(self.img.nw)] waves.sort() candidates = [self.img.getWaveIdx(wave) for wave in waves[1:-1]] # remove channels with lots of saturation candidates = [w for w in candidates if not self.getSaturation(w=w,t=t)] # find out channels with enough signal thr = N.mean(pwrs) / 1.25 bol = N.where(pwrs[candidates] > thr, 1, 0) if N.any(bol): ids = N.nonzero(bol)[0] if len(ids) == 1: idx = ids[0] else: candidates = N.array(candidates)[ids] idx = N.argmax(pwrs[candidates]) refwave = candidates[idx] else: refwave = N.argmax(pwrs) self.refwave = refwave self.fixAlignParmWithCurrRefWave() self.progress()
def _fitGaussian2DR(img, LD, y, x, sigma=[2.,2.], mean_max=None, window=5, rot=0, searchRot=None): """ img: already cut out with indy, indx """ if mean_max is None: mi, ma, me, sd = U.mmms(img) #ma = img[y,x] else: me, ma = mean_max if searchRot: param0 = (me, float(ma-me), y, x, float(sigma[0]), float(sigma[1]), rot) else: param0 = (me, float(ma-me), y, x, float(sigma[0]), float(sigma[1])) img = img.flatten() def func(p, shape, LD, rot): return yGaussian2DR(p, shape, LD, rot).flatten() - img from scipy import optimize ret, check = optimize.leastsq(func, param0, args=((window,window), LD, rot), warning=None) if searchRot and ret[-1] < 0: ret[-1] += 90 ret[4:] = N.abs(ret[4:]) return ret, check
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 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] ''' imgFit.fitFailedClear() vzyx = 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 list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma)] if check == 5: imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) sigma = imgFit._scalerToSeq(sigma, ndim) return list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma] else: v = ret[1] zyx = ret[2:2+ndim] sigma = ret[2+ndim:2+ndim*2] return [v,zyx,sigma]
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] ''' imgFit.fitFailedClear() vzyx = 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 list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma)] if check == 5: imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) sigma = imgFit._scalerToSeq(sigma, ndim) return list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma] else: v = ret[1] zyx = ret[2:2 + ndim] sigma = ret[2 + ndim:2 + ndim * 2] return [v, zyx, sigma]
def zoomToAll(self): if self.m_nImgs < 1: return posA=N.array(self.m_imgPosArr) sizA=N.array(self.m_imgSizeArr) a=N.array([N.minimum.reduce(posA), N.maximum.reduce(posA+sizA), ]) from Priithon.all import U MC = N.array([0.5, 0.5]) # mosaic viewer's center (0.5, 0.5) a -= MC hypot = N.array((N.hypot(a[0][0], a[0][1]), N.hypot(a[1][0], a[1][1]))) theta = N.array((N.arctan2(a[0][1], a[0][0]), N.arctan2(a[1][1], a[1][0]))) # radians phi = theta + U.deg2rad(self.m_rot) mimXY = N.array((hypot[0]*N.cos(phi[0]), hypot[0]*N.sin(phi[0]))) maxXY = N.array((hypot[1]*N.cos(phi[1]), hypot[1]*N.sin(phi[1]))) a = N.array((mimXY, maxXY)) a.sort(0) if self.m_aspectRatio == -1: a = N.array(([a[0][0],-a[1][1]],[a[1][0],-a[0][1]])) self.zoomToRect(x0=a[0][0], y0=a[0][1], x1=a[-1][0],y1=a[-1][1])
def _fitGaussian2D(img, indy, indx, y, x, sigma=[2.,2.], mean_max=None): """ img: already cut out with indy, indx """ if mean_max is None: mi, ma, me, sd = U.mmms(img) #ma = img[y,x] else: me, ma = mean_max try: sigma, sigma2 = sigma param0 = (me, float(ma-me), y, x, float(sigma), float(sigma2)) # func = _gaussian2D_ellipse except (ValueError, TypeError): try: len(sigma) sigma = [0] except TypeError: pass param0 = (me, float(ma-me), y, x, float(sigma)) #func = _gaussian2D img = img.flatten() def func(p, indy, indx): return yGaussian2D(p, indy, indx) - img from scipy import optimize ret, check = optimize.leastsq(func, param0, args=(indy.flatten(), indx.flatten()), warning=None) ret[2:4] += 0.5 # use pixel center ret[4:] = N.abs(ret[4:]) return ret, check
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 findMaxWithGFitAll(img, thre=0, sigma_peak=0.5, win=11, mask_npxls=3): """ find peaks until either 1. any pxls becomes below thre 2. the same peak was found as the maximum mask_npxls: number of pixels to mask when Gaussian fitting failed return poslist """ img = img.copy() imgFit.fitFailedClear() ndim = img.ndim sigma_peak = imgFit._scalerToSeq(sigma_peak, ndim) poses = [] vzyx = U.findMax(img) while vzyx[0] > thre: prev = vzyx try: ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma_peak, win) except IndexError: # too close to the edge imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:])) mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min()) poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma_peak)]) if check == 5: imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min()) poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak]) else: v = ret[1] zyx = ret[2:2+ndim] if N.any(N.abs(zyx - vzyx[1:]) > win/2.):#zyx < 0 or zyx > img.shape or ): mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min()) poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak]) else: sigma = ret[2+ndim:2+ndim*2] mask_gaussianND(img, zyx, v, sigma) poses.append([v,zyx,sigma]) vzyx = U.findMax(img) if N.all(vzyx == prev): break return poses#, img
def findBestChannel(self, t=0): """ the reference wavelength is determined from the wavelength and intensity set self.refwave (in index) """ # if time laplse if self.img.nt > 1: # how large the object is... arrs = [self.img.get3DArr(w=w, t=t).ravel() for w in range(self.img.nw)] modes = [imgFilters.mode(a[::50]) for a in arrs] fpxls = [N.where(a > modes[i])[0].size/float(a.size) for i, a in enumerate(arrs)] # bleach half time halfs = [] for w in range(self.nw): mes = [self.img.get3DArr(w=w, t=t).mean() for t in range(self.nt)] parm, check = U.fitDecay(mes) halfs.append(parm[-1] / float(self.nt)) channels = N.add(fpxls, halfs) refwave = N.argmax(channels) print('The channel to align is %i' % refwave) # if wavelengths are only 2, then use the channel 0 elif self.img.nw <= 2: refwave = 0 # take into account for the PSF distortion due to chromatic aberration elif self.img.nw > 2: pwrs = N.array([self.img.get3DArr(w=w, t=t).mean() for w in range(self.img.nw)]) # the middle channel should have the intermediate PSF shape waves = [self.img.getWaveFromIdx(w) for w in range(self.img.nw)] waves.sort() candidates = [self.img.getWaveIdx(wave) for wave in waves[1:-1]] # remove channels with lots of saturation candidates = [w for w in candidates if not self.getSaturation(w=w,t=t)] # find out channels with enough signal thr = N.mean(pwrs) / 1.25 bol = N.where(pwrs[candidates] > thr, 1, 0) if N.any(bol): ids = N.nonzero(bol)[0] if len(ids) == 1: idx = ids[0] else: candidates = N.array(candidates)[ids] idx = N.argmax(pwrs[candidates]) refwave = candidates[idx] else: refwave = N.argmax(pwrs) self.refwave = refwave self.fixAlignParmWithCurrRefWave() self.progress()
def findMaxWithGFitAll(img, thre=0, sigma_peak=0.5, win=11, mask_npxls=3): """ find peaks until either 1. any pxls becomes below thre 2. the same peak was found as the maximum mask_npxls: number of pixels to mask when Gaussian fitting failed return poslist """ img = img.copy() imgFit.fitFailedClear() ndim = img.ndim sigma_peak = imgFit._scalerToSeq(sigma_peak, ndim) poses = [] vzyx = U.findMax(img) while vzyx[0] > thre: prev = vzyx try: ret, check = imgFit.fitGaussianND(img, vzyx[-ndim:], sigma_peak, win) except IndexError: # too close to the edge imgFit.fitFailedAppend("at %s" % str(vzyx[-ndim:])) mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min()) poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [list(sigma_peak)]) if check == 5: imgFit.fitFailedAppend("at %s, %s, check=%i" % (str(vzyx[-ndim:]), str(ret), check)) mask_value(img, vzyx[-ndim:], r=mask_npxls, value=img.min()) poses.append(list(vzyx)[0:1] + [vzyx[-ndim:]] + [sigma_peak]) else: v = ret[1] zyx = ret[2:2 + ndim] sigma = ret[2 + ndim:2 + ndim * 2] mask_gaussianND(img, zyx, v, sigma) poses.append([v, zyx, sigma]) vzyx = U.findMax(img) if N.all(vzyx == prev): break return poses #, img
def paddingMed(img, shape, shift=None, smooth=10): """ pad with median see doc for paddingValue """ try: med = N.median(img, axis=None) except TypeError: # numpy version < 1.1 med = U.median(img) return paddingValue(img, shape, med, shift, smooth)
def maskEdgeWithValue2D(arr, val=None): """ overwrite 2D image edge (s[:-2,2:]) with value **in place** if val is None, use median """ if not val: val = U.median(arr[:-2, 2:]) arr[-2:] = val arr[:, :2] = val return arr
def maskEdgeWithValue2D(arr, val=None): """ overwrite 2D image edge (s[:-2,2:]) with value **in place** if val is None, use median """ if not val: val = U.median(arr[:-2,2:]) arr[-2:] = val arr[:,:2] = val return arr
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 _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 roughRotMag(a, b, yxrm, idx, step=0.02, nstep=20): guess = yxrm[idx] Range = (guess - (step * nstep), guess + (step * nstep), step) xs = N.arange(*Range) yxrms = N.empty((len(xs), ) + yxrm.shape, yxrm.dtype.type) yxrms[:] = yxrm yxrms[:, idx] = xs #for r in Range: # yxrm2 = N.copy(yxrm) # yxrm2[idx] = r # yxrms.append(yxrm2) pp = ppro.pmap(_compCost, yxrms, ppro.NCPU, a, b) #pp = [_compCost(yx, a, b) for yx in yxrms] xi = N.argmin(pp) pmin = pp[xi] base = max(pp) if pmin == base: # failed to get the curve for some reason # usually this happens if one used ndimage.zoom() in scipy # ndimage.zoom only interpolate pixel-wise. # no subpixel interpolation is done... x = int(idx >= 3) check = 5 else: # go ahead and fit poly x = xs[xi] data = zip(xs, pp) fit, check = U.fitPoly(data, p=(1, 1, 1, 1, 1, 1, 1)) if check == 5: answer = x else: xx = U.nd.zoom(xs, 100) yy = U.yPoly(fit, xx) ii = N.argmin(yy) answer = xx[ii] return answer
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 arr_normalize(a, normalize_with='intens'): """ normalize_with: intens or std """ choices = ('intens', 'std') mi, ma, me, sd = U.mmms(a) if normalize_with == choices[0]: a = (a - mi) / (ma - mi) elif normalize_with == choices[1]: a = (a - me) / sd else: raise ValueError('normalize only with %s' % choices) return a
def chopYX(shapeYX, ncpu=8): """ return axis, YXmmlist """ n, _1, _2, axis = U.findMax(shapeYX) n0 = n // ncpu mms = [] pixel = 0 for cpu in range(ncpu): mms += [[pixel, pixel + n0]] pixel += n0 mms[-1][-1] = n return axis, mms
def arr_normalize(a, normalize_with='intens'): """ normalize_with: intens or std """ choices = ('intens', 'std') mi, ma, me, sd = U.mmms(a) if normalize_with == choices[0]: a = (a-mi) / (ma-mi) elif normalize_with == choices[1]: a = (a - me) / sd else: raise ValueError('normalize only with %s' % choices) return a
def writeSec(self, arr, i=0, singleOutFn=None): if self._rescaleTo8bit: if self._rescaleTo8bit is True: self.rescaleTo8bit(arr) arr = (arr-self._rescaleTo8bit[0])*255./self._rescaleTo8bit[1] # astype changes byteorder as well arr = arr.astype(self.dtype) img = U.array2image(arr, rgbOrder=self.rgbOrder) if not singleOutFn: singleOutFn = self.outfn img.save(singleOutFn, **self.saveOptions)
def OnMenuSaveND(self, ev=None): if self.data.dtype.type in (N.complex64, N.complex128): dat = self.dataCplx datX = abs(self.data) #CHECK else: dat = datX = self.data from Priithon.all import Mrc, U, FN, Y fn = FN(1, 0) if not fn: return if fn[-4:] in [".mrc", ".dat"]: Mrc.save(dat, fn) elif fn[-5:] in [".fits"]: U.saveFits(dat, fn) else: # save as sequence of image files # if fn does contain something like '%0d' auto-insert '_%0NNd' # with NN to just fit the needed number of digits datX = datX.view() datX.shape = (-1, ) + datX.shape[-2:] U.saveImg8_seq(datX, fn) Y.shellMessage("### Y.vd(%d) saved to '%s'\n" % (self.id, fn))
def OnMenuSaveND(self, ev=None): if self.data.dtype.type in (N.complex64, N.complex128): dat = self.dataCplx datX = abs(self.data) #CHECK else: dat = datX = self.data from Priithon.all import Mrc, U, FN, Y fn = FN(1,0) if not fn: return if fn[-4:] in [ ".mrc", ".dat" ]: Mrc.save(dat, fn) elif fn[-5:] in [ ".fits" ]: U.saveFits(dat, fn) else: # save as sequence of image files # if fn does contain something like '%0d' auto-insert '_%0NNd' # with NN to just fit the needed number of digits datX = datX.view() datX.shape = (-1,)+datX.shape[-2:] U.saveImg8_seq(datX, fn) Y.shellMessage("### Y.vd(%d) saved to '%s'\n"%(self.id, fn))
def rot2D(img2D, yx, sigma, rlist, mean_max=None, win=11): y, x = yx yi, xi, LD = _indLD(win, y, x) imgP = img2D[yi, xi] if mean_max is None: mi, ma, me, sd = U.mmms(imgP) else: me, ma = mean_max yy = [] for r in rlist: ret, check = _fitGaussian2DR(imgP, LD, y, x, sigma, [me, ma], win, r) syx = ret[4] / ret[5] # width y / x yy.append(syx) return yy
def writeSec(self, arr, i=0, singleOutFn=None): if self._rescaleTo8bit: if self._rescaleTo8bit is True: self.rescaleTo8bit(arr) arr = (arr - self._rescaleTo8bit[0]) * 255. / self._rescaleTo8bit[1] # astype changes byteorder as well arr = arr.astype(self.dtype) img = U.array2image(arr, rgbOrder=self.rgbOrder) if not singleOutFn: singleOutFn = self.outfn img.save(singleOutFn, **self.saveOptions)
def rot2D(img2D, yx, sigma, rlist, mean_max=None, win=11): y, x = yx yi, xi, LD = _indLD(win, y, x) imgP = img2D[yi,xi] if mean_max is None: mi, ma, me, sd = U.mmms(imgP) else: me, ma = mean_max yy = [] for r in rlist: ret, check = _fitGaussian2DR(imgP, LD, y, x, sigma, [me,ma], win, r) syx = ret[4] / ret[5] # width y / x yy.append(syx) return yy
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 setupHistArr(self, i): self.hist_arr[i] = None img = self.data[tuple(self.zsec)][i] if img.dtype.type == N.uint8: self.hist_min[i], self.hist_max[i] = 0, (1 << 8) - 1 elif img.dtype.type == N.uint16: self.hist_min[i], self.hist_max[i] = 0, (1 << 16) - 1 elif img.dtype.type == N.int16: self.hist_min[i], self.hist_max[i] = 0 - (1 << 15), (1 << 15) - 1 from Priithon.all import U self.hist[i].hist_min, self.hist[i].hist_max = U.mm(img) #self.img) if img.dtype.type in (N.uint8, N.int16, N.uint16): self.hist_range[i] = self.hist_max[i] - self.hist_min[i] + 1 self.hist_arr[i] = N.zeros(shape=self.hist_range[i], dtype=N.int32)
def onViewSeq(self, ev): from Priithon.all import Y,U try: Y.view( U.loadImg_seq( self.fn_or_fns ) ) except: if NO_SPECIAL_GUI_EXCEPT: raise import sys e = sys.exc_info() wx.MessageBox("Error when loading image sequence: %s - %s" %\ (str(e[0]), str(e[1]) ), "Non consistent image shapes !?", style=wx.ICON_ERROR) else: s = "Y.view( U.loadImg_seq(<fileslist>) )" Y.shellMessage("### %s\n"% s)
def rotND(img, zyx, sigma, rlist, mean_max=None, win=10): # y, x = yx # yi, xi, LD = _indLD(win, y, x) slices = imgGeo.nearbyRegion(img.shape, zyx, win) imgP = img[slices] if mean_max is None: mi, ma, me, sd = U.mmms(imgP) else: me, ma = mean_max yy = [] for r in rlist: ret, check = fitGaussianND(img, zyx, sigma, win, [me, ma], r)#_fitGaussian2DR(imgP, LD, y, x, sigma, [me,ma], win, r) syx = ret[4] / ret[5] # width y / x yy.append(syx) return yy
def setupHistArr(self,i): self.hist_arr[i] = None img = self.data[ tuple(self.zsec) ][i] if img.dtype.type == N.uint8: self.hist_min[i], self.hist_max[i] = 0, (1<<8)-1 elif img.dtype.type == N.uint16: self.hist_min[i], self.hist_max[i] = 0, (1<<16)-1 elif img.dtype.type == N.int16: self.hist_min[i], self.hist_max[i] = 0-(1<<15), (1<<15)-1 from Priithon.all import U self.hist[i].hist_min,self.hist[i].hist_max = U.mm(img)#self.img) if img.dtype.type in (N.uint8, N.int16, N.uint16): self.hist_range[i] = self.hist_max[i] - self.hist_min[i] + 1 self.hist_arr[i] = N.zeros(shape=self.hist_range[i], dtype=N.int32)
def setupHistArr(self): self.hist_arr = None if self.img.dtype.type == N.uint8: self.hist_min, self.hist_max = 0, (1<<8)-1 elif self.img.dtype.type == N.uint16: self.hist_min, self.hist_max = 0, (1<<16)-1 elif self.img.dtype.type == N.int16: self.hist_min, self.hist_max = 0-(1<<15), (1<<15)-1 from Priithon.all import U self.hist.hist_min,self.hist.hist_max = U.mm(self.img)#self.hist_min #if self.hist.m_histPlotArray is not None: # self.hist.m_histPlotArray[0,0],self.hist.m_histPlotArray[-1,0] = U.mm(self.img) # print self.hist.m_histPlotArray[0,0],self.hist.m_histPlotArray[-1,0] if self.img.dtype.type in (N.uint8, N.int16, N.uint16): self.hist_range = self.hist_max - self.hist_min + 1 self.hist_arr = N.zeros(shape=self.hist_range, dtype=N.int32)