if os.path.isdir(RESULT_DIR):
    os.rmdir(RESULT_DIR)
os.mkdir(RESULT_DIR)

if os.path.isdir(ROI_DIR):
    os.rmdir(ROI_DIR)
os.mkdir(ROI_DIR)


from rfData import rfClass

##Get an ROI from the first file in the directory so I know
##its size in pixels
print '\n ROI selection to determine ROI size in pixels'
tmpRf = rfClass(TISSUE_A_DIR + '/' + os.listdir(TISSUE_A_DIR)[0], 'rfd')
tmpRf.SetRoiFixedSize(WINDOWX, WINDOWY)    
region = tmpRf.data[tmpRf.roiY[0]:tmpRf.roiY[1], tmpRf.roiX[0]:tmpRf.roiX[1]]
roiPoints, roiLines = region.shape
psdPoints = roiPoints//2

##Set up CZT parameters for PSD calculation### 
lowCut = 0.0
highCut = 15.0

freqStep = (highCut - lowCut)/psdPoints
spectrumFreq = np.arange(0,psdPoints)*freqStep  + lowCut

fracUnitCircle = (highCut - lowCut)/(tmpRf.fs/10**6)

cztW = np.exp(1j* (-2*np.pi*fracUnitCircle)/psdPoints )
RESULT_DIR = DATA_DIR + '/results'

if os.path.isdir(RESULT_DIR):
    os.rmdir(RESULT_DIR)
os.mkdir(RESULT_DIR)

if os.path.isdir(ROI_DIR):
    os.rmdir(ROI_DIR)
os.mkdir(ROI_DIR)

from rfData import rfClass

##Get an ROI from the first file in the directory so I know
##its size in pixels
print '\n ROI selection to determine ROI size in pixels'
tmpRf = rfClass(TISSUE_A_DIR + '/' + os.listdir(TISSUE_A_DIR)[0], 'rfd')
tmpRf.SetRoiFixedSize(WINDOWX, WINDOWY)
region = tmpRf.data[tmpRf.roiY[0]:tmpRf.roiY[1], tmpRf.roiX[0]:tmpRf.roiX[1]]
roiPoints, roiLines = region.shape
psdPoints = roiPoints // 2

##Set up CZT parameters for PSD calculation###
lowCut = 0.0
highCut = 15.0

freqStep = (highCut - lowCut) / psdPoints
spectrumFreq = np.arange(0, psdPoints) * freqStep + lowCut

fracUnitCircle = (highCut - lowCut) / (tmpRf.fs / 10**6)

cztW = np.exp(1j * (-2 * np.pi * fracUnitCircle) / psdPoints)
    phased = False

DATA_DIR = sys.argv[1]

import os

if not os.path.isdir(DATA_DIR):
    print '\nError ' + DATA_DIR + ' is not a valid path.'
    sys.exit()

from rfData import rfClass

##Get an ROI from the first file in the directory so I know
##its size in pixels
print '\n ROI selection to determine ROI size in pixels'
tmpRf = rfClass(DATA_DIR + '/' + os.listdir(DATA_DIR)[0], 'rfd')

tmpRf.SetRoiFixedSize(WINDOWX, WINDOWY)
region = tmpRf.data[tmpRf.roiY[0]:tmpRf.roiY[1], tmpRf.roiX[0]:tmpRf.roiX[1]]
roiPoints, roiLines = region.shape
psdPoints = roiPoints // 2

##Set up CZT parameters for PSD calculation###
lowCut = 0.0
highCut = 15.0

freqStep = (highCut - lowCut) / psdPoints
spectrumFreq = np.arange(0, psdPoints) * freqStep + lowCut

fracUnitCircle = (highCut - lowCut) / (tmpRf.fs / 10**6)
    phased = False

DATA_DIR = sys.argv[1]

import os

if not os.path.isdir(DATA_DIR):
    print '\nError ' + DATA_DIR + ' is not a valid path.'
    sys.exit()

from rfData import rfClass

##Get an ROI from the first file in the directory so I know
##its size in pixels
print '\n ROI selection to determine ROI size in pixels'
tmpRf = rfClass(DATA_DIR + '/' + os.listdir(DATA_DIR)[0], 'rfd')

tmpRf.SetRoiFixedSize(WINDOWX, WINDOWY)    
region = tmpRf.data[tmpRf.roiY[0]:tmpRf.roiY[1], tmpRf.roiX[0]:tmpRf.roiX[1]]
roiPoints, roiLines = region.shape
psdPoints = roiPoints//2

##Set up CZT parameters for PSD calculation### 
lowCut = 0.0
highCut = 15.0

freqStep = (highCut - lowCut)/psdPoints
spectrumFreq = np.arange(0,psdPoints)*freqStep  + lowCut

fracUnitCircle = (highCut - lowCut)/(tmpRf.fs/10**6)
#!/usr/bin/python

from rfData import rfClass
import os,sys


if len(sys.argv) < 2 or len(sys.argv) > 3:
    print "\nError, Usage is: "
    print os.path.basename(sys.argv[0]) + " rfFile <filetype> \n"
    sys.exit()

if len(sys.argv) == 2:
    rf = rfClass(sys.argv[1] , 'rfd')

if len(sys.argv) == 3:
    rf = rfClass(sys.argv[1], sys.argv[2])

rf.DisplayBmodeImage()
Usage:

python singleRfdFile.py RFD_NAME
'''


MAX_STRAIN = .02

import os, sys
START_DIR = os.getcwd()
RFD_NAME = sys.argv[1]
BASE_DIR = RFD_NAME[:-4] + 'dir'

from rfData import rfClass
rf = rfClass(RFD_NAME, 'rfd')

os.mkdir(BASE_DIR)

#B-mode images
os.mkdir(BASE_DIR + '/Bmode')
for frame in range(rf.nFrames):

    rf.SaveBModeImages( BASE_DIR + '/Bmode/f' + str(frame).zfill(3) , frame)    

#use M-player to create a movie
os.chdir(BASE_DIR + '/Bmode')
os.system('mencoder "mf://*.png" -mf fps=4 -o ../bMode.avi -ovc lavc -lavcopts vcodec=msmpeg4v2:vbitrate=1600')
os.chdir(START_DIR)

#Create ITK strain images
Esempio n. 7
0
reader = sitk.ImageFileReader()

if bModeFile:

    if bModeFile == '.mhd':
        #read in B-mode from ITK file
        reader.SetFileName(bModeFile)
        bModeItk = reader.Execute()
        bMode = sitk.GetArrayFromImage(bModeItk).T
        bModeSpacing = bModeItk.GetSpacing()
        bModeOrigin = bModeItk.GetOrigin()

    else:
        #Read in RF data, let the origin be 0,0
        from rfData import rfClass
        rf = rfClass(bModeFile, 'rfd')
        rf.ReadFrame(0)
        temp = rf.data

        from scipy.signal import hilbert
        from numpy import log10
        bMode = log10(abs(hilbert(temp, axis=0)))
        bMode = bMode - bMode.max()
        bModeOrigin = [0., 0.]
        bModeSpacing = [rf.deltaY, rf.deltaX]

    bMode[bMode < -3] = -3

    reader.SetFileName(strainFile)
    paramImItk = reader.Execute()
    paramImage = sitk.GetArrayFromImage(paramImItk).T
    sys.exit()

#Establish paths
BASE_PATH, RFD_NAME = os.path.split(os.path.abspath(sys.argv[1]))
print "\nProcessing file named: " + RFD_NAME + "\non path: " + BASE_PATH + "\n"
RESULT_DIR = BASE_PATH +'/' + RFD_NAME[:-4] + 'Bmode'

if os.path.isdir(RESULT_DIR):
    print "\nError, data set already processed."
    print "Directory: " + RESULT_DIR + " Exists. \n"
    sys.exit()

os.makedirs(RESULT_DIR)
os.makedirs(RESULT_DIR + '/images')

from rfData import rfClass
rf = rfClass(BASE_PATH + '/' + RFD_NAME, 'rfd')


for frames in range(rf.nFrames):
    rf.SaveBModeImage(RESULT_DIR + '/images/frame_' + str(frames).zfill(3), image = frames)

#Create movies
import readrfd
header = readrfd.headerInfo(BASE_PATH + '/' + RFD_NAME)
fps = int( header[3] )
import os
os.system('''mencoder "mf://''' + RESULT_DIR + '''/images/*.png" -mf type=png:fps=5 -ovc lavc -o '''+ RESULT_DIR + '/bMode_fps5.avi')
os.system('''mencoder "mf://''' + RESULT_DIR + '''/images/*.png" -mf type=png:fps=''' + str(fps)+''' -ovc lavc -o '''+ RESULT_DIR + '/bMode_fpsActual'
+ str(fps) +'.avi' )
reader = sitk.ImageFileReader()

if bModeFile:
        
        if bModeFile == '.mhd':
            #read in B-mode from ITK file
            reader.SetFileName(bModeFile)
            bModeItk = reader.Execute()
            bMode = sitk.GetArrayFromImage(bModeItk).T
            bModeSpacing = bModeItk.GetSpacing()
            bModeOrigin = bModeItk.GetOrigin()

        else:
            #Read in RF data, let the origin be 0,0
            from rfData import rfClass
            rf = rfClass(bModeFile, 'rfd')
            rf.ReadFrame(0)
            temp = rf.data

            from scipy.signal import hilbert
            from numpy import log10
            bMode = log10(abs(hilbert(temp, axis = 0)))
            bMode = bMode - bMode.max()
            bModeOrigin = [0., 0.]
            bModeSpacing = [rf.deltaY, rf.deltaX]

        bMode[bMode < -3] = -3

        reader.SetFileName(strainFile)
        paramImItk = reader.Execute()
        paramImage = sitk.GetArrayFromImage(paramImItk).T
Esempio n. 10
0
    def __init__(self,
                 fname,
                 dataType,
                 postFile=None,
                 selectRoi=False,
                 windowYmm=1.0,
                 windowXmm=4.0,
                 rangeYmm=1.0,
                 rangeXmm=.6,
                 overlap=.65,
                 strainKernelmm=6.0):
        '''Input:
        fname: (string)  Either a file containing a sequence of frames with motion, or a pre-compression file.
        dataType: (string)  The filetype of the input files, see rfClass for allowed types
        postFile: (string)  A file of post compression data, the same type and dimensions as the input file
        windowYmm: (float) the axial window size of the block match window in mm
        windowXmm: (float)  The lateral window size of the block match window in mm
        rangeYmm:  (float)  The axial search range for the block match window in mm
        rangeXmm:  (float)  The lateral search range for the block match window in mm
        overlap:  (float)  [0-1].  The axial overlap between block matching windows.
        strainKernelmm:  (float)  The size of the least squares strain estimation kernel in mm.

        '''
        super(blockMatchClass, self).__init__(fname, dataType)

        if postFile:
            self.postRf = rfClass(postFile, dataType)
        else:
            self.postRf = None
        self.windowYmm = windowYmm
        self.windowXmm = windowXmm
        self.rangeYmm = rangeYmm
        self.rangeXmm = rangeXmm

        #axial block size
        self.windowY = int(self.windowYmm / self.deltaY)
        if not self.windowY % 2:
            self.windowY += 1
        self.halfY = self.windowY // 2

        #lateral block size
        if self.imageType == 'la':
            self.windowX = int(self.windowXmm / self.deltaX)
        else:
            self.windowX = 21
        if not self.windowX % 2:
            self.windowX += 1
        self.halfX = self.windowX // 2

        #search range
        if self.imageType == 'la':
            self.rangeX = int(self.rangeXmm / self.deltaX)
        else:
            self.rangeX = 10
        self.rangeY = int(self.rangeYmm / self.deltaY)
        self.smallRangeY = 3
        self.smallRangeX = 2

        #overlap and step
        self.overlap = overlap
        self.stepY = int((1 - self.overlap) * self.windowY)

        ####work out tracking boundaries
        self.startY = 0 + self.rangeY + self.smallRangeY + self.halfY
        self.stopY = self.points - self.halfY - self.smallRangeY - self.rangeY  #last pixel that can fit a window

        self.startX = 0 + self.halfX + self.rangeX + self.smallRangeX
        self.stopX = self.lines - self.halfX - self.smallRangeX - self.rangeX

        ###Allow for selection of an ROI####
        if self.imageType == 'la' and selectRoi:
            self.SetRoiBoxSelect()

            if self.roiX[0] > self.startX:
                self.startX = self.roiX[0]

            if self.roiX[1] < self.stopX:
                self.stopX = self.roiX[1]

            if self.roiY[0] > self.startY:
                self.startY = self.roiY[0]

            if self.roiY[1] < self.stopY:
                self.stopY = self.roiY[1]

        ###Re-adjust roiX, roiY for display
        self.roiY = [self.startY, self.stopY]
        self.roiX = [self.startX, self.stopX]

        if selectRoi and self.imageType == 'la':
            self.ShowRoiImage()

    ###create arrays containing window centers in rf data coordinates
        self.windowCenterY = range(self.startY, self.stopY, self.stepY)
        self.numY = len(self.windowCenterY)

        self.windowCenterX = range(self.startX, self.stopX)
        self.numX = len(self.windowCenterX)

        #work out strainwindow in rf pixels, divide by step to convert to displacement pixels
        #make odd number
        self.strainWindow = int(strainKernelmm / (self.deltaY * self.stepY))
        if not self.strainWindow % 2:
            self.strainWindow += 1
        self.halfLsq = self.strainWindow // 2
        self.strainwindowmm = self.strainWindow * self.deltaY * self.stepY

        if self.numY - 1 < self.strainWindow or self.numX < 1:
            print "ROI is too small"
            import sys
            sys.exit()
Esempio n. 11
0
#!/usr/bin/python

from rfData import rfClass
import os, sys

if len(sys.argv) < 2 or len(sys.argv) > 3:
    print "\nError, Usage is: "
    print os.path.basename(sys.argv[0]) + " rfFile <filetype> \n"
    sys.exit()

if len(sys.argv) == 2:
    rf = rfClass(sys.argv[1], 'rfd')

if len(sys.argv) == 3:
    rf = rfClass(sys.argv[1], sys.argv[2])

rf.DisplayBmodeImage()
    def __init__(self, sampleName, refName, dataType, numRefFrames = 0, refAttenuation = .5, freqLow = 2., freqHigh = 8., attenuationKernelSizeYmm = 12, blockYmm = 8, blockXmm = 8, overlapY = .85, overlapX = .85, bscFitRadius = 1.0, centerFreqSimulation = 5.0, sigmaSimulation = 1.0 ):
        '''Description:
                This class implements the reference phantom method of Yao et al.  It inherits from the RF data class
                defined for working with simulations and Seimens rfd files.

        Input:
                sampleName:  Filename of sample RF data
                refName:  Filename of reference RF data
                dataType:  The file type of the sample and reference RFdata.  Must be the same.
                numRefFrames:  The number of frames to use in the reference data set to calculate
                the reference spectrum.  A value of 0 will use all the frames in the data set.
                refAttenuation:  Assuming a linear dependence of attenuation on frequency,
                                the attenuation slope in dB/(cm MHz)
                freqLow:  The low frequency for the CZT in MHz
                freqHigh: The high frequency for the CZT in MHz
                attenuationKernelSizeMM:  The size of the data segment used to do the least squares fitting
                to find center frequency shift with depth.
                blockSize[Y,X]mm:
                overlap[Y,X]:
                frequencySmoothingKernel: (MHz)

          Throughout the code I'll call the 1-D segment where a single FFT is performed a window

          A block will refer to a 2-D region spanning multiple windows axially and several A-lines
          where a power spectrum is calculated by averaging FFTs
                                '''
        import numpy

        super(attenuation, self).__init__(sampleName, dataType, centerFreqSimulation, sigmaSimulation)

        #For data from clinical scanners the reference and sample data will be the same file
        #type.  For simulations I will be using a different file type
        if dataType == 'sim':
            self.refRf = rfClass(refName, 'multiSim', centerFreqSimulation, sigmaSimulation)
        else:
            self.refRf = rfClass(refName, dataType)

        #Work out which reference frames to use.  First make sure that I haven't selected too many
        #to use
        if numRefFrames >= 1 and numRefFrames < self.refRf.nFrames:
            self.numRefFrames = numRefFrames
        else:
            self.numRefFrames = self.refRf.nFrames

        #Next, instead of picking adjacent reference frames, use reference frames that are evenly spaced
        #throughout the data set, to get beamlines as uncorrelated as possible
        self.refFrameStep = self.refRf.nFrames//numRefFrames
        self.refFrames = numpy.arange(0,numRefFrames)*self.refFrameStep

        #read in frames
        self.refRf.ReadFrame()
        self.ReadFrame()
        #Check to see that reference data and sample data contain
        #the same number of points
        if self.points != self.refRf.points or self.lines != self.refRf.lines:
            print "Error.  Sample and reference images must be the same size. \n\ "
            return

        #Attenuation estimation parameters
        self.betaRef = refAttenuation
        #get window sizes and overlap
        self.blockYmm = blockYmm
        self.blockXmm = blockXmm
        self.overlapY = overlapY
        self.overlapX = overlapX
        self.blockX =int( self.blockXmm/self.deltaX)
        self.blockY =int( self.blockYmm/self.deltaY)


        #make the block sizes in pixels odd numbers for the sake of calculating their centers
        if not self.blockY%2:
            self.blockY +=1

        if not self.blockX%2:
            self.blockX +=1

        self.halfY = self.blockY//2
        self.halfX = self.blockX//2

        #overlap the blocks axially by self.overlapY%
        stepY = int(  (1-self.overlapY)*self.blockY )
        startY = self.halfY
        stopY = self.points - self.halfY - 1
        self.blockCenterY = range(startY, stopY, stepY)

        #Set the attenuation kernel size in mm
        #Work it out in points
        #Make kernel size an odd number of poitns
        #Work out kernel size in mm
        self.attenuationKernelSizeYmm = attenuationKernelSizeYmm #attenuation estimation size used in least squares fit
        self.lsqFitPoints = int(self.attenuationKernelSizeYmm/(stepY*self.deltaY) ) #make this number odd
        if not self.lsqFitPoints%2:
            self.lsqFitPoints += 1
        self.halfLsq = self.lsqFitPoints//2
        self.attenuationKernelSizeYmm = self.lsqFitPoints*stepY*self.deltaY


        #cutoff some more points because of least squares fitting, cross correlation
        self.attenCenterY= self.blockCenterY[self.halfLsq + 1:-(self.halfLsq + 1)]

        stepX = int( (1-self.overlapX)*self.blockX )
        if stepX < 1:
            stepX = 1
        startX =self.halfX
        stopX = self.lines - self.halfX
        self.blockCenterX = range(startX, stopX, stepX)

        ##Within each block a Welch-Bartlett style spectrum will be estimated
        ##Figure out the number of points used in an individual FFT based on
        ##a 50% overlap and rounding the block size to be divisible by 4
        self.blockY -= self.blockY%4
        self.bartlettY = self.blockY//2
        self.spectrumFreqStep = (freqHigh - freqLow)/self.bartlettY
        self.radiusInPoints = int( bscFitRadius/self.spectrumFreqStep)
        self.spectrumFreq = numpy.arange(0, self.bartlettY)*self.spectrumFreqStep + freqLow



        #set-up parameters for the chirpZ transform
        fracUnitCircle = (freqHigh - freqLow)/(self.fs/10**6)
        self.cztW = numpy.exp(1j* (-2*numpy.pi*fracUnitCircle)/self.bartlettY )
        self.cztA = numpy.exp(1j* (2*numpy.pi*freqLow/(self.fs/10**6) ) )
    def __init__(self, fname, dataType, postFile = None,  selectRoi = False,windowYmm = 1.0, windowXmm = 4.0, rangeYmm = 1.0, rangeXmm = .6, overlap = .65,
    strainKernelmm = 6.0):
        '''Input:
        fname: (string)  Either a file containing a sequence of frames with motion, or a pre-compression file.
        dataType: (string)  The filetype of the input files, see rfClass for allowed types
        postFile: (string)  A file of post compression data, the same type and dimensions as the input file
        windowYmm: (float) the axial window size of the block match window in mm
        windowXmm: (float)  The lateral window size of the block match window in mm
        rangeYmm:  (float)  The axial search range for the block match window in mm
        rangeXmm:  (float)  The lateral search range for the block match window in mm
        overlap:  (float)  [0-1].  The axial overlap between block matching windows.
        strainKernelmm:  (float)  The size of the least squares strain estimation kernel in mm.

        '''
        super(blockMatchClass, self).__init__(fname, dataType)

        if postFile:
            self.postRf = rfClass(postFile, dataType)
        else:
            self.postRf = None
        self.windowYmm = windowYmm
        self.windowXmm = windowXmm
        self.rangeYmm =  rangeYmm
        self.rangeXmm = rangeXmm

        #axial block size
        self.windowY = int(self.windowYmm/self.deltaY)
        if not self.windowY%2:
            self.windowY += 1
        self.halfY = self.windowY//2

        #lateral block size
        if self.imageType == 'la':
            self.windowX = int(self.windowXmm/self.deltaX)
        else:
            self.windowX = 21
        if not self.windowX%2:
            self.windowX +=1
        self.halfX = self.windowX//2


        #search range
        if self.imageType == 'la':
            self.rangeX = int(self.rangeXmm/self.deltaX)
        else:
            self.rangeX = 10
        self.rangeY = int(self.rangeYmm/self.deltaY)
        self.smallRangeY = 3
        self.smallRangeX = 2

        #overlap and step
        self.overlap = overlap
        self.stepY =int( (1 - self.overlap)*self.windowY )


        ####work out tracking boundaries
        self.startY = 0 + self.rangeY + self.smallRangeY + self.halfY
        self.stopY = self.points - self.halfY - self.smallRangeY - self.rangeY #last pixel that can fit a window

        self.startX = 0 + self.halfX + self.rangeX + self.smallRangeX
        self.stopX = self.lines - self.halfX - self.smallRangeX - self.rangeX
        
        ###Allow for selection of an ROI####
        if self.imageType == 'la' and selectRoi:
            self.SetRoiBoxSelect()
                
            if self.roiX[0] > self.startX:
                self.startX = self.roiX[0]

            if self.roiX[1] < self.stopX:
                self.stopX = self.roiX[1]
            
            if self.roiY[0] > self.startY:
                self.startY = self.roiY[0]

            if self.roiY[1] < self.stopY:
                self.stopY = self.roiY[1]

        
        ###Re-adjust roiX, roiY for display
        self.roiY = [self.startY, self.stopY]
        self.roiX = [self.startX, self.stopX]

        if selectRoi and self.imageType == 'la':
            self.ShowRoiImage()

    ###create arrays containing window centers in rf data coordinates
        self.windowCenterY = range(self.startY,self.stopY, self.stepY)
        self.numY = len(self.windowCenterY)

        self.windowCenterX = range(self.startX,self.stopX)
        self.numX = len(self.windowCenterX)


    #work out strainwindow in rf pixels, divide by step to convert to displacement pixels
    #make odd number
        self.strainWindow = int(strainKernelmm/(self.deltaY*self.stepY) )
        if not self.strainWindow%2:
            self.strainWindow += 1
        self.halfLsq = self.strainWindow//2
        self.strainwindowmm = self.strainWindow*self.deltaY*self.stepY
       
        if self.numY - 1 < self.strainWindow or self.numX < 1:
            print "ROI is too small"
            import sys
            sys.exit()
    phased = False

DATA_DIR = sys.argv[1]
REFPHANFILE = sys.argv[2]

import os

if not os.path.isdir(DATA_DIR):
    print '\nError ' + DATA_DIR + ' is not a valid path.'
    sys.exit()

from rfData import rfClass

##Get an ROI from the first file in the directory so I know
##its size in pixels
tmpRf = rfClass(DATA_DIR + '/' + os.listdir(DATA_DIR)[0], 'rfd')

counter = 0
allFiles = os.listdir(DATA_DIR )
allFiles = [f for f in allFiles if 'rfd' in f]

refPhanRf = rfClass(REFPHANFILE, 'rfd')

for fName in allFiles:

    tmpRf = rfClass(DATA_DIR + '/' + fName, 'rfd')
    if not phased:
        tmpRf.SetRoiFixedSize(WINDOWX, WINDOWY)    
    else:
        tmpRf.SetRoiFixedSize(WINDOWX_PA, WINDOWY)
        refPhanRf.SetRoiFixedSize(WINDOWX_PA, WINDOWY)