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
Example #3
0
    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
Example #5
0
	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
Example #7
0
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
Example #8
0
    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
Example #12
0
    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']
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']