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 runTestShift(img1name, img2name, imgpath, tiltdiff, coord): img1path = os.path.join(imgpath, img1name) img2path = os.path.join(imgpath, img2name) print img1path print img2path img1 = apImage.binImg(apImage.mrcToArray(img1path),4) img2 = apImage.binImg(apImage.mrcToArray(img2path),4) apImage.arrayToMrc(img1,"img1a-raw.mrc") apImage.arrayToMrc(img2,"img2a-raw.mrc") origin, newpart, snr = apTiltShift.getTiltedCoordinates(img1, img2, tiltdiff, coord) apImage.arrayToJpegPlusPeak(img1, "img1a-guess.jpg", (origin[1], origin[0])) apImage.arrayToJpegPlusPeak(img2, "img2a-guess.jpg", (newpart[1], newpart[0]))
def getImage(self, imgdata, binning): imgarray = imgdata['image'] imgarray = apImage.binImg(imgarray, binning) shape = numpy.shape(imgarray) cutoff = 8.0 # remove spikes in the image first imgarray = self.prepImage(imgarray, cutoff) return imgarray
def getImage(self,imgdata,binning): imgarray = imgdata['image'] imgarray = apImage.binImg(imgarray, binning) shape=numpy.shape(imgarray) cutoff=8.0 # remove spikes in the image first imgarray=self.prepImage(imgarray,cutoff) return imgarray
def makeInspectedMask(sessiondata,maskassessname,imgdata): assessruntree = getMaskAssessRunData(sessiondata,maskassessname) maskbins,maxbin = getMaskbins(sessiondata,maskassessname) allmaskarray = None for i,assessrundata in enumerate(assessruntree): maskrundata = assessrundata['maskrun'] maskregiondata = getMaskRegions(maskrundata,imgdata) if len(maskregiondata) == 0: continue keeplist = getRegionKeepList(assessrundata,maskregiondata) if len(keeplist) == 0: continue maskarray = getMaskArray(maskrundata,imgdata) # #### This is for auto msking only # if len(maskarray) == 0: # continue # else: # allmaskarray = maskarray # # return allmaskarray, maxbin # # ### End aoutomasking only code maskarray = apCrud.makeKeepMask(maskarray,keeplist) print maskarray extrabin = maxbin/maskbins[i] if extrabin > 1: maskarray = apImage.binImg(maskarray, extrabin) try: allmaskarray = allmaskarray+maskarray except: allmaskarray = maskarray allmaskarray = numpy.where(allmaskarray==0,0,1) if allmaskarray.shape == (): allmaskarray = None return allmaskarray,maxbin
def averageSubStack(partlist, stackfile, bin=1): if len(partlist) > 300: partlist = partlist[:300] boxsize = apImagicFile.getBoxsize(stackfile) if len(partlist) == 0: binboxsize = boxsize/bin blank = numpy.ones((binboxsize, binboxsize), dtype=numpy.float32) return blank if not os.path.isfile(stackfile): apDisplay.printWarning("could not find stack, "+stackfile) return False partdatalist = apImagicFile.readParticleListFromStack(stackfile, partlist, boxsize, msg=False) partdataarray = numpy.asarray(partdatalist) finaldata = partdataarray.mean(0) if bin > 1: finaldata = apImage.binImg(finaldata, bin) return finaldata
def createMontageInMemory(self, apix): self.cluster_resolution = [] apDisplay.printMsg("Converting files") ### Set binning of images boxsize = apImagicFile.getBoxsize(self.instack) bin = 1 while boxsize/bin > 200: bin+=1 binboxsize = boxsize/bin ### create averages files = glob.glob(self.timestamp+".[0-9]*") files.sort(self.sortFile) montage = [] montagepngs = [] i = 0 for listname in files: i += 1 apDisplay.printMsg("%d of %d classes"%(i,len(files))) pngfile = listname+".png" if not os.path.isfile(listname) or apFile.fileSize(listname) < 1: ### create a ghost particle sys.stderr.write("skipping "+listname+"\n") blank = numpy.ones((binboxsize, binboxsize), dtype=numpy.float32) ### add to montage stack montage.append(blank) self.cluster_resolution.append(None) ### create png apImage.arrayToPng(blank, pngfile) else: ### read particle list partlist = self.readListFile(listname) ### average particles partdatalist = apImagicFile.readParticleListFromStack(self.instack, partlist, boxsize, msg=False) partdataarray = numpy.asarray(partdatalist) finaldata = partdataarray.mean(0) if bin > 1: finaldata = apImage.binImg(finaldata, bin) ### add to montage stack montage.append(finaldata) res = apFourier.spectralSNR(partdatalist, apix) self.cluster_resolution.append(res) ### create png apImage.arrayToPng(finaldata, pngfile) ### check for png file if os.path.isfile(pngfile): montagepngs.append(pngfile) else: apDisplay.printError("failed to create montage") stackname = "kerdenstack"+self.timestamp+".hed" apImagicFile.writeImagic(montage, stackname) ### create montage montagecmd = ("montage -geometry +4+4 -tile %dx%d "%(self.params['xdim'], self.params['ydim'])) for monpng in montagepngs: montagecmd += monpng+" " montagecmd += "montage.png" apEMAN.executeEmanCmd(montagecmd, showcmd=True, verbose=False) time.sleep(1) apFile.removeFilePattern(self.timestamp+".*.png") return bin
def processImage(self, imgdict): from pyami import mrc outimg = apImage.binImg(imgdict['image'], 2) mrc.write(outimg, imgdict['filename']+"_sm.mrc")
def processImage(self, imgdict): from pyami import mrc outimg = apImage.binImg(imgdict['image'], 2) mrc.write(outimg, imgdict['filename'] + "_sm.mrc")
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 getTiltedCoordinates(img1, img2, tiltdiff, picks1=[], angsearch=True, inittiltaxis=-7.2, 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) picks1, list of particles picks for image 1 """ t0 = time.time() #shrink images bin = 2 binned1 = apImage.binImg(img1, bin) binned2 = apImage.binImg(img2, bin) #apImage.arrayToJpeg(binned1, "binned1.jpg") #apImage.arrayToJpeg(binned2, "binned2.jpg") filt1 = apImage.highPassFilter(binned1, apix=1.0, radius=20.0, localbin=4/bin) filt2 = apImage.highPassFilter(binned2, apix=1.0, radius=20.0, localbin=4/bin) #apImage.arrayToJpeg(filt1, "filt1.jpg") #apImage.arrayToJpeg(filt2, "filt2.jpg") if angsearch is True: bestsnr = 0 bestangle = None ### rough refine #for angle in [-6, -4, -2,]: # sys.stderr.write(".") # shift, xfactor, snr = getTiltedRotateShift(filt1, filt2, tiltdiff, angle, bin, msg=False) # if snr > bestsnr: # bestsnr = snr # bestangle = angle bestangle = inittiltaxis if msg is True: apDisplay.printMsg("Best tilt axis angle= %.1f; SNR=%.2f"%(bestangle,bestsnr)) ### finer refine for angle in [bestangle-1, bestangle-0.5, bestangle+0.5, bestangle+1]: if msg is True: sys.stderr.write(".") shift, xfactor, snr = getTiltedRotateShift(filt1, filt2, tiltdiff, angle, bin, msg=False) if snr > bestsnr: bestsnr = snr bestangle = angle if msg is True: apDisplay.printMsg("Best tilt axis angle= %.1f; SNR=%.2f"%(bestangle,bestsnr)) ### really fine refine for angle in [bestangle-0.2, bestangle-0.1, bestangle+0.1, bestangle+0.2]: if msg is True: sys.stderr.write(".") shift, xfactor, snr = getTiltedRotateShift(filt1, filt2, tiltdiff, angle, bin, msg=False) if snr > bestsnr: bestsnr = snr bestangle = angle if msg is True: apDisplay.printMsg("Best tilt axis angle= %.1f; SNR=%.2f"%(bestangle,bestsnr)) shift, xfactor, snr = getTiltedRotateShift(filt1, filt2, tiltdiff, bestangle, bin, msg=msg) if msg is True: apDisplay.printMsg("Best tilt axis angle= %.1f; SNR=%.2f"%(bestangle,bestsnr)) else: bestangle = 0.0 shift, xfactor, snr = getTiltedRotateShift(img1, img2, tiltdiff, bestangle, bin) if msg and min(abs(shift)) < min(img1.shape)/16.0: apDisplay.printWarning("Overlap was too close to the edge and possibly wrong.") ### case 1: find tilted center of first image center = numpy.asarray(img1.shape)/2.0 newpoint = translatePoint(center, center, shift, bestangle, xfactor) #print "newpoint=", newpoint halfsh = (center + newpoint)/2.0 origin = halfsh ### case 2: using a list of picks if len(picks1) > 1: #get center most pick dmin = origin[0]/2.0 for pick in picks1: da = numpy.hypot(pick[0]-halfsh[0], pick[1]-halfsh[1]) if da < dmin: dmin = da origin = pick # origin is pick from image 1 # newpart is pick from image 2 newpart = translatePoint(origin, center, shift, bestangle, xfactor) newpart2 = numpy.array([(origin[0]*xfactor-shift[0])*xfactor, origin[1]-shift[1]]) if msg is True: apDisplay.printMsg("origin=(%d,%d); newpart=(%.1f,%.1f); newpart2=(%.1f,%.1f)" %(origin[0],origin[1], newpart[0],newpart[1], newpart2[0],newpart2[1],)) apDisplay.printMsg("completed in "+apDisplay.timeString(time.time()-t0)) return origin, newpart, snr, bestangle ### check to make sure points are not off the edge while newpart[0] < 10: newpart += numpy.asarray((20,0)) origin += numpy.asarray((20,0)) while newpart[1] < 10: newpart += numpy.asarray((0,20)) origin += numpy.asarray((0,20)) while newpart[0] > img1.shape[0]-10: newpart -= numpy.asarray((20,0)) origin -= numpy.asarray((20,0)) while newpart[1] > img1.shape[1]-10: newpart -= numpy.asarray((0,20)) origin -= numpy.asarray((0,20)) return origin, newpart