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
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']