def centerParticles(self, oldstack, centerstack, badstack): maxshift = self.params['maxshift'] centerparts = [] badparts = [] keeplist = [] i = 0 while partnum < numparts: ### if need more particles ### read 4000 parts from oldstack ### write centerparts to centerstack ### write badparts to badstack ### set current image oldpart = oldparts[i] ### mirror about x xmirror = numpy.flipud(oldpart) ### cross-correlate xcc = correlator.cross_correlate(oldpart, xmirror) ### find peak peakdict = peakfinder.findSubpixelPeak(xcc) xpeak = correlator.wrap_coord(peakdict['pixel peak'], xcc.shape) ### mirror about y ymirror = numpy.fliplr(oldpart) ### cross-correlate ycc = correlator.cross_correlate(oldpart, ymirror) ### find peak peakdict = peakfinder.findSubpixelPeak(ycc) ypeak = correlator.wrap_coord(peakdict['pixel peak'], ycc.shape) ### mirror about y then x xymirror = numpy.flipud(ymirror) ### cross-correlate xycc = correlator.cross_correlate(oldpart, xymirror) ### find peak peakdict = peakfinder.findSubpixelPeak(xycc) xypeak = correlator.wrap_coord(peakdict['pixel peak'], xycc.shape) ### do some math to get shift xshift = (ypeak[0] + xypeak[0]) / 4.0 yshift = (xpeak[0] + xypeak[0]) / 4.0 ### shift particle, by integers only if xshift < maxshift and yshift < maxshift: xyshift = (xshift, yshift) centerpart = ndimage.shift(oldpart, shift=xyshift, mode='wrap', order=0) centerparts.append(centerpart) keeplist.append(partnum) else: badparts.append(oldpart) return keeplist
def centerParticles(self, oldstack, centerstack, badstack): maxshift = self.params['maxshift'] centerparts = [] badparts = [] keeplist = [] i = 0 while partnum < numparts: ### if need more particles ### read 4000 parts from oldstack ### write centerparts to centerstack ### write badparts to badstack ### set current image oldpart = oldparts[i] ### mirror about x xmirror = numpy.flipud(oldpart) ### cross-correlate xcc = correlator.cross_correlate(oldpart, xmirror) ### find peak peakdict = peakfinder.findSubpixelPeak(xcc) xpeak = correlator.wrap_coord(peakdict['pixel peak'], xcc.shape) ### mirror about y ymirror = numpy.fliplr(oldpart) ### cross-correlate ycc = correlator.cross_correlate(oldpart, ymirror) ### find peak peakdict = peakfinder.findSubpixelPeak(ycc) ypeak = correlator.wrap_coord(peakdict['pixel peak'], ycc.shape) ### mirror about y then x xymirror = numpy.flipud(ymirror) ### cross-correlate xycc = correlator.cross_correlate(oldpart, xymirror) ### find peak peakdict = peakfinder.findSubpixelPeak(xycc) xypeak = correlator.wrap_coord(peakdict['pixel peak'], xycc.shape) ### do some math to get shift xshift = (ypeak[0] + xypeak[0])/4.0 yshift = (xpeak[0] + xypeak[0])/4.0 ### shift particle, by integers only if xshift < maxshift and yshift < maxshift: xyshift = (xshift, yshift) centerpart = ndimage.shift(oldpart, shift=xyshift, mode='wrap', order=0) centerparts.append(centerpart) keeplist.append(partnum) else: badparts.append(oldpart) return keeplist
def correlateTemplate(self): ## correlate self.correlator.setImage(0, self.images['templateB']) if self.settings['correlation type'] == 'phase': cor = self.correlator.phaseCorrelate(zero=False) else: cor = self.correlator.crossCorrelate() self.images['correlation'] = cor # low pass filter if self.settings['correlation lpf']: cor = scipy.ndimage.gaussian_filter( cor, self.settings['correlation lpf']) # display correlation self.setImage(cor, 'correlation') # find peak peakinfo = peakfinder.findSubpixelPeak(cor) peakinfo['correlation'] = cor peakinfo['templateB-unshifted'] = self.images['templateB-unshifted'] #self.printPeakInfo(peakinfo) corpeak = peakinfo['subpixel peak'] ivtargets = [(corpeak[1], corpeak[0])] self.setTargets(ivtargets, 'peak', block=True) return peakinfo
def correlateTemplate(self): ## correlate self.correlator.setImage(0, self.images["templateB"]) if self.settings["correlation type"] == "phase": cor = self.correlator.phaseCorrelate(zero=False) else: cor = self.correlator.crossCorrelate() self.images["correlation"] = cor # low pass filter if self.settings["correlation lpf"]: cor = scipy.ndimage.gaussian_filter(cor, self.settings["correlation lpf"]) # display correlation self.setImage(cor, "correlation") # find peak peakinfo = peakfinder.findSubpixelPeak(cor) peakinfo["correlation"] = cor peakinfo["templateB-unshifted"] = self.images["templateB-unshifted"] # self.printPeakInfo(peakinfo) corpeak = peakinfo["subpixel peak"] ivtargets = [(corpeak[1], corpeak[0])] self.setTargets(ivtargets, "peak", block=True) return peakinfo
def correlateTemplate(self): ## correlate self.correlator.setImage(0, self.images['templateB']) if self.settings['correlation type'] == 'phase': cor = self.correlator.phaseCorrelate(zero=False) else: cor = self.correlator.crossCorrelate() self.images['correlation'] = cor # low pass filter if self.settings['correlation lpf']: cor = scipy.ndimage.gaussian_filter(cor, self.settings['correlation lpf']) # display correlation self.setImage(cor, 'correlation') # find peak peakinfo = peakfinder.findSubpixelPeak(cor) peakinfo['correlation'] = cor peakinfo['templateB-unshifted'] = self.images['templateB-unshifted'] #self.printPeakInfo(peakinfo) corpeak = peakinfo['subpixel peak'] ivtargets = [(corpeak[1], corpeak[0])] self.setTargets(ivtargets, 'peak', block=True) return peakinfo
def getShift(imgdata1, imgdata2): # assumes images are square print "Finding shift between", apDisplay.short(imgdata1["filename"]), "and", apDisplay.short(imgdata2["filename"]) dimension1 = imgdata1["camera"]["dimension"]["x"] binning1 = imgdata1["camera"]["binning"]["x"] dimension2 = imgdata2["camera"]["dimension"]["x"] binning2 = imgdata2["camera"]["binning"]["x"] finalsize = 512 # test to make sure images are at same mag if imgdata1["scope"]["magnification"] != imgdata2["scope"]["magnification"]: apDisplay.printWarning("Defocus pairs are at different magnifications, so shift can't be calculated.") return None # test to see if images capture the same area if (dimension1 * binning1) != (dimension2 * binning2): apDisplay.printWarning("Defocus pairs do not capture the same imaging area, so shift can't be calculated.") return None # images must not be less than finalsize (currently 512) pixels. This is arbitrary but for good reason if dimension1 < finalsize or dimension2 < finalsize: apDisplay.printWarning("Images must be greater than " + finalsize + " pixels to calculate shift.") return None # low pass filter 2 images to twice the final pixelsize BEFORE binning shrinkfactor1 = dimension1 / finalsize shrinkfactor2 = dimension2 / finalsize binned1 = apImage.filterImg(imgdata1["image"], 1.0, shrinkfactor1 * 2) binned2 = apImage.filterImg(imgdata2["image"], 1.0, shrinkfactor2 * 2) # now bin 2 images binned1 = apImage.binImg(binned1, shrinkfactor1) binned2 = apImage.binImg(binned2, shrinkfactor2) ### fix for non-square images, correlation fails on non-square images mindim = min(binned1.shape) binned1 = binned1[:mindim, :mindim] binned2 = binned2[:mindim, :mindim] ### use phase correlation, performs better than cross pc = correlator.phase_correlate(binned1, binned2) apImage.arrayToMrc(pc, "phaseCorrelate.mrc") ### find peak, filtering to 10.0 helps peak = peakfinder.findSubpixelPeak(pc, lpf=10.0) subpixpeak = peak["subpixel peak"] shift = correlator.wrap_coord(subpixpeak, pc.shape) peak["scalefactor"] = dimension2 / float(dimension1) # print shift[0]*shrinkfactor1, shift[1]*shrinkfactor1 xshift = int(round(shift[0] * shrinkfactor1)) yshift = int(round(shift[1] * shrinkfactor1)) peak["shift"] = numpy.array((xshift, yshift)) apDisplay.printMsg("Determined shifts: %f %f" % (peak["shift"][0], peak["shift"][1])) # print peak['shift'] # sys.exit(1) return peak
def register2(image1, image2, angles): im2filt = scipy.ndimage.spline_filter(image2) peaks = [] for angle in angles: image2 = scipy.ndimage.rotate(im2filt, angle, reshape=False) #mrc.write(image2, 'rot.mrc') pc = correlator.phase_correlate(image1, image2, zero=False) mrc.write(pc, 'pc.mrc') peak = peakfinder.findSubpixelPeak(pc) result = (angle, peak['pixel peak value'], peak['subpixel peak value'], peak['snr']) print result peaks.append(result) return peaks
def correlateOriginal(self, index, imagedata): if index == 0: self.originalimage = imagedata['image'] unbinned = {'row': 0.0, 'col': 0.0} else: ## correlate self.startTimer('scope change correlation') try: correlation_type = self.settings['correlation type'] except KeyError: correlation_type = 'phase' if correlation_type == 'cross': cor = correlator.cross_correlate(self.originalimage, imagedata['image']) elif correlation_type == 'phase': cor = correlator.phase_correlate(self.originalimage, imagedata['image'], False, wiener=True) else: raise RuntimeError('invalid correlation type') self.stopTimer('scope change correlation') self.displayCorrelation(cor) ## find peak self.startTimer('shift peak') peak = peakfinder.findSubpixelPeak(cor) self.stopTimer('shift peak') self.logger.debug('Peak %s' % (peak, )) pixelpeak = peak['subpixel peak'] self.startTimer('shift display') self.displayPeak(pixelpeak) self.stopTimer('shift display') peakvalue = peak['subpixel peak value'] shift = correlator.wrap_coord(peak['subpixel peak'], cor.shape) self.logger.debug('pixel shift (row,col): %s' % (shift, )) ## need unbinned result binx = imagedata['camera']['binning']['x'] biny = imagedata['camera']['binning']['y'] unbinned = {'row': shift[0] * biny, 'col': shift[1] * binx} shiftinfo = { 'previous': self.originalimage, 'next': imagedata, 'pixel shift': unbinned } return shiftinfo
def simpleCorrelation(array1,array2): c = correlator.Correlator() p = peakfinder.PeakFinder() c.setImage(0,array1) c.setImage(1,array2) shape = array1.shape corrimage = c.phaseCorrelate() p.setImage(corrimage) peak = peakfinder.findSubpixelPeak(corrimage,lpf=1.5) shift = [0.0,0.0] for i in (0,1): if peak['subpixel peak'][i] > shape[i]/2: shift[i] = peak['subpixel peak'][i] - shape[i] else: shift[i] = peak['subpixel peak'][i] return shift
def simpleCorrelation(array1, array2): c = correlator.Correlator() p = peakfinder.PeakFinder() c.setImage(0, array1) c.setImage(1, array2) shape = array1.shape corrimage = c.phaseCorrelate() p.setImage(corrimage) peak = peakfinder.findSubpixelPeak(corrimage, lpf=1.5) shift = [0.0, 0.0] for i in (0, 1): if peak['subpixel peak'][i] > shape[i] / 2: shift[i] = peak['subpixel peak'][i] - shape[i] else: shift[i] = peak['subpixel peak'][i] return shift
def correlateOriginal(self,index,imagedata): if index == 0: self.originalimage = imagedata['image'] unbinned = {'row':0.0, 'col': 0.0} else: ## correlate self.startTimer('scope change correlation') try: correlation_type = self.settings['correlation type'] except KeyError: correlation_type = 'phase' if correlation_type == 'cross': cor = correlator.cross_correlate(self.originalimage,imagedata['image']) elif correlation_type == 'phase': cor = correlator.phase_correlate(self.originalimage,imagedata['image'],False,wiener=True) else: raise RuntimeError('invalid correlation type') self.stopTimer('scope change correlation') self.displayCorrelation(cor) ## find peak self.startTimer('shift peak') peak = peakfinder.findSubpixelPeak(cor) self.stopTimer('shift peak') self.logger.debug('Peak %s' % (peak,)) pixelpeak = peak['subpixel peak'] self.startTimer('shift display') self.displayPeak(pixelpeak) self.stopTimer('shift display') peakvalue = peak['subpixel peak value'] shift = correlator.wrap_coord(peak['subpixel peak'], cor.shape) self.logger.debug('pixel shift (row,col): %s' % (shift,)) ## need unbinned result binx = imagedata['camera']['binning']['x'] biny = imagedata['camera']['binning']['y'] unbinned = {'row':shift[0] * biny, 'col': shift[1] * binx} shiftinfo = {'previous': self.originalimage, 'next': imagedata, 'pixel shift': unbinned} return shiftinfo
def removeStageAlphaBacklash(self, tilts, preset_name, target, emtarget): if len(tilts) < 2: raise ValueError ## change to parent preset try: parentname = target['image']['preset']['name'] except: adjust = False else: adjust = True ## acquire parent preset image, initial image if adjust: isoffset = self.getImageShiftOffset() self.presetsclient.toScope(parentname) self.setImageShiftOffset(isoffset) imagedata0 = self.acquireCorrectedCameraImageData(0) ## tilt then return in slow increments delta = math.radians(5.0) n = 5 increment = delta / n if tilts[1] - tilts[0] > 0: sign = -1 else: sign = 1 alpha = tilts[0] + sign * delta self.instrument.tem.StagePosition = {'a': alpha} time.sleep(1.0) for i in range(n): alpha -= sign * increment self.instrument.tem.StagePosition = {'a': alpha} time.sleep(1.0) if adjust: ## acquire parent preset image, final image imagedata1 = self.acquireCorrectedCameraImageData(1) self.presetsclient.toScope(preset_name) ## return to tomography preset if emtarget['movetype'] == 'image shift': presetdata = self.presetsclient.getPresetFromDB(preset_name) self.moveAndPreset(presetdata, emtarget) else: self.presetsclient.toScope(preset_name) self.setImageShiftOffset(isoffset) ## find shift between image0, image1 pc = correlator.phase_correlate(imagedata0['image'], imagedata1['image'], False) peakinfo = peakfinder.findSubpixelPeak(pc, lpf=1.5) subpixelpeak = peakinfo['subpixel peak'] shift = correlator.wrap_coord(subpixelpeak, imagedata0['image'].shape) shift = {'row': shift[0], 'col': shift[1]} ## transform pixel to image shift oldscope = imagedata0['scope'] newscope = self.calclients['image shift'].transform( shift, oldscope, imagedata0['camera']) ishiftx = newscope['image shift']['x'] - oldscope['image shift'][ 'x'] ishifty = newscope['image shift']['y'] - oldscope['image shift'][ 'y'] oldishift = self.instrument.tem.ImageShift newishift = { 'x': oldishift['x'] + ishiftx, 'y': oldishift['y'] + ishifty } self.logger.info( 'adjusting imageshift after backlash: dx,dy = %s,%s' % (ishiftx, ishifty)) self.instrument.tem.ImageShift = newishift
def removeStageAlphaBacklash(self, tilts, preset_name, target, emtarget): if len(tilts) < 2: raise ValueError ## change to parent preset try: parentname = target['image']['preset']['name'] except: adjust = False else: adjust = True ## acquire parent preset image, initial image if adjust: isoffset = self.getImageShiftOffset() self.presetsclient.toScope(parentname) self.setImageShiftOffset(isoffset) imagedata0 = self.acquireCorrectedCameraImageData(0) ## tilt then return in slow increments delta = math.radians(5.0) n = 5 increment = delta/n if tilts[1] - tilts[0] > 0: sign = -1 else: sign = 1 alpha = tilts[0] + sign*delta self.instrument.tem.StagePosition = {'a': alpha} time.sleep(1.0) for i in range(n): alpha -= sign*increment self.instrument.tem.StagePosition = {'a': alpha} time.sleep(1.0) if adjust: ## acquire parent preset image, final image imagedata1 = self.acquireCorrectedCameraImageData(1) self.presetsclient.toScope(preset_name) ## return to tomography preset if emtarget['movetype'] == 'image shift': presetdata = self.presetsclient.getPresetFromDB(preset_name) self.moveAndPreset(presetdata, emtarget) else: self.presetsclient.toScope(preset_name) self.setImageShiftOffset(isoffset) ## find shift between image0, image1 pc = correlator.phase_correlate(imagedata0['image'], imagedata1['image'], False) peakinfo = peakfinder.findSubpixelPeak(pc, lpf=1.5) subpixelpeak = peakinfo['subpixel peak'] shift = correlator.wrap_coord(subpixelpeak, imagedata0['image'].shape) shift = {'row': shift[0], 'col': shift[1]} ## transform pixel to image shift oldscope = imagedata0['scope'] newscope = self.calclients['image shift'].transform(shift, oldscope, imagedata0['camera']) ishiftx = newscope['image shift']['x'] - oldscope['image shift']['x'] ishifty = newscope['image shift']['y'] - oldscope['image shift']['y'] oldishift = self.instrument.tem.ImageShift newishift = {'x': oldishift['x'] + ishiftx, 'y': oldishift['y'] + ishifty} self.logger.info('adjusting imageshift after backlash: dx,dy = %s,%s' % (ishiftx,ishifty)) self.instrument.tem.ImageShift = newishift
def getShift(imgdata1, imgdata2): #assumes images are square print "Finding shift between", apDisplay.short( imgdata1['filename']), "and", apDisplay.short(imgdata2['filename']) dimension1 = imgdata1['camera']['dimension']['x'] binning1 = imgdata1['camera']['binning']['x'] dimension2 = imgdata2['camera']['dimension']['x'] binning2 = imgdata2['camera']['binning']['x'] finalsize = 512 #test to make sure images are at same mag if imgdata1['scope']['magnification'] != imgdata2['scope']['magnification']: apDisplay.printWarning( "Defocus pairs are at different magnifications, so shift can't be calculated." ) return None #test to see if images capture the same area if (dimension1 * binning1) != (dimension2 * binning2): apDisplay.printWarning( "Defocus pairs do not capture the same imaging area, so shift can't be calculated." ) return None #images must not be less than finalsize (currently 512) pixels. This is arbitrary but for good reason if dimension1 < finalsize or dimension2 < finalsize: apDisplay.printWarning("Images must be greater than " + finalsize + " pixels to calculate shift.") return None #low pass filter 2 images to twice the final pixelsize BEFORE binning shrinkfactor1 = dimension1 / finalsize shrinkfactor2 = dimension2 / finalsize binned1 = apImage.filterImg(imgdata1['image'], 1.0, shrinkfactor1 * 2) binned2 = apImage.filterImg(imgdata2['image'], 1.0, shrinkfactor2 * 2) #now bin 2 images binned1 = apImage.binImg(binned1, shrinkfactor1) binned2 = apImage.binImg(binned2, shrinkfactor2) ### fix for non-square images, correlation fails on non-square images mindim = min(binned1.shape) binned1 = binned1[:mindim, :mindim] binned2 = binned2[:mindim, :mindim] ### use phase correlation, performs better than cross pc = correlator.phase_correlate(binned1, binned2) apImage.arrayToMrc(pc, "phaseCorrelate.mrc") ### find peak, filtering to 10.0 helps peak = peakfinder.findSubpixelPeak(pc, lpf=10.0) subpixpeak = peak['subpixel peak'] shift = correlator.wrap_coord(subpixpeak, pc.shape) peak['scalefactor'] = dimension2 / float(dimension1) #print shift[0]*shrinkfactor1, shift[1]*shrinkfactor1 xshift = int(round(shift[0] * shrinkfactor1)) yshift = int(round(shift[1] * shrinkfactor1)) peak['shift'] = numpy.array((xshift, yshift)) apDisplay.printMsg("Determined shifts: %f %f" % (peak['shift'][0], peak['shift'][1])) #print peak['shift'] #sys.exit(1) return peak
def getTiltedRotateShift(img1, img2, tiltdiff, angle=0, bin=1, msg=True): """ takes two images tilted with respect to one another and tries to find overlap img1 (as numpy array) img2 (as numpy array) tiltdiff (in degrees) negative, img1 is more compressed (tilted) positive, img2 is more compressed (tilted) """ ### untilt images by stretching and compressing # choose angle s/t compressFactor = 1/stretchFactor # this only works if one image is untilted (RCT) of both images are opposite tilt (OTR) #halftilt = abs(tiltdiff)/2.0 halftiltrad = math.acos(math.sqrt(math.cos(abs(tiltdiff)/180.0*math.pi))) # go from zero tilt to half tilt compressFactor = math.cos(halftiltrad) # go from max tilt to half tilt stretchFactor = math.cos(halftiltrad) / math.cos(abs(tiltdiff)/180.0*math.pi) if tiltdiff > 0: if msg is True: apDisplay.printMsg("compress image 1") untilt1 = transformImage(img1, compressFactor, angle) untilt2 = transformImage(img2, stretchFactor, angle) xfactor = compressFactor else: if msg is True: apDisplay.printMsg("stretch image 1") untilt1 = transformImage(img1, stretchFactor, angle) untilt2 = transformImage(img2, compressFactor, angle) xfactor = stretchFactor ### filtering was done earlier filt1 = untilt1 filt2 = untilt2 if filt1.shape != filt2.shape: newshape = ( max(filt1.shape[0],filt2.shape[0]), max(filt1.shape[1],filt2.shape[1]) ) apDisplay.printMsg("Resizing images to: "+str(newshape)) filt1 = apImage.frame_constant(filt1, newshape, filt1.mean()) filt2 = apImage.frame_constant(filt2, newshape, filt2.mean()) ### cross-correlate cc = correlator.cross_correlate(filt1, filt2, pad=True) rad = min(cc.shape)/20.0 cc = apImage.highPassFilter(cc, radius=rad) cc = apImage.normRange(cc) cc = blackEdges(cc) cc = apImage.normRange(cc) cc = blackEdges(cc) cc = apImage.normRange(cc) cc = apImage.lowPassFilter(cc, radius=10.0) #find peak peakdict = peakfinder.findSubpixelPeak(cc, lpf=0) #import pprint #pprint.pprint(peak) pixpeak = peakdict['subpixel peak'] if msg is True: apDisplay.printMsg("Pixel peak: "+str(pixpeak)) apImage.arrayToJpegPlusPeak(cc, "guess-cross-ang"+str(abs(angle))+".jpg", pixpeak) rawpeak = numpy.array([pixpeak[1], pixpeak[0]]) #swap coord shift = numpy.asarray(correlator.wrap_coord(rawpeak, cc.shape))*bin if msg is True: apDisplay.printMsg("Found xy-shift btw two images" +";\n\t SNR= "+str(round(peakdict['snr'],2)) +";\n\t halftilt= "+str(round(halftiltrad*180/math.pi, 3)) +";\n\t compressFactor= "+str(round(compressFactor, 3)) +";\n\t stretchFactor= "+str(round(stretchFactor, 3)) +";\n\t xFactor= "+str(round(xfactor, 3)) +";\n\t rawpeak= "+str(numpy.around(rawpeak*bin, 1)) +";\n\t shift= "+str(numpy.around(shift, 1)) ) return shift, xfactor, peakdict['snr']