Esempio n. 1
0
def runRectRangeOffset(self):
    '''rectify range offset
    '''
    if hasattr(self, 'doInSAR'):
        if not self.doInSAR:
            return

    catalog = isceobj.Catalog.createCatalog(self._insar.procDoc.name)
    self.updateParamemetersFromUser()

    referenceTrack = self._insar.loadTrack(reference=True)
    secondaryTrack = self._insar.loadTrack(reference=False)

    insarDir = 'insar'
    os.makedirs(insarDir, exist_ok=True)
    os.chdir(insarDir)


    #rectify
    rgoff = isceobj.createImage()
    rgoff.load(self._insar.rangeOffset+'.xml')

    if self._insar.radarDemAffineTransform == [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]:
        if not os.path.isfile(self._insar.rectRangeOffset):
            os.symlink(self._insar.rangeOffset, self._insar.rectRangeOffset)
            create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')
    else:
        rect_with_looks(self._insar.rangeOffset,
                        self._insar.rectRangeOffset,
                        rgoff.width, rgoff.length,
                        rgoff.width, rgoff.length,
                        self._insar.radarDemAffineTransform[0], self._insar.radarDemAffineTransform[1],
                        self._insar.radarDemAffineTransform[2], self._insar.radarDemAffineTransform[3],
                        self._insar.radarDemAffineTransform[4], self._insar.radarDemAffineTransform[5],
                        self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1,
                        self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
                        'REAL',
                        'Bilinear')
        create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')

    os.chdir('../')

    catalog.printToLog(logger, "runRectRangeOffset")
    self._insar.procDoc.addAllFromCatalog(catalog)
Esempio n. 2
0
def swathMosaic(frame,
                inputFiles,
                outputfile,
                rangeOffsets,
                azimuthOffsets,
                numberOfRangeLooks,
                numberOfAzimuthLooks,
                updateFrame=False,
                phaseCompensation=False,
                pcRangeLooks=1,
                pcAzimuthLooks=4,
                filt=False,
                resamplingMethod=0):
    '''
    mosaic swaths
    
    frame:                 frame
    inputFiles:            input file list
    output file:           output mosaic file
    rangeOffsets:          range offsets
    azimuthOffsets:        azimuth offsets
    numberOfRangeLooks:    number of range looks of the input files
    numberOfAzimuthLooks:  number of azimuth looks of the input files
    phaseCompensation:     whether do phase compensation for each swath
    pcRangeLooks:          number of range looks to take when compute swath phase difference
    pcAzimuthLooks:        number of azimuth looks to take when compute swath phase difference
    filt:                  whether do filtering when compute swath phase difference
    resamplingMethod:      0: amp resampling. 1: int resampling.
    '''
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from contrib.alos2proc.alos2proc import mosaicsubswath
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1
    from isceobj.Alos2Proc.Alos2ProcPublic import filterInterferogram

    numberOfSwaths = len(frame.swaths)
    swaths = frame.swaths

    rangeScale = []
    azimuthScale = []
    rectWidth = []
    rectLength = []
    for i in range(numberOfSwaths):
        rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize)
        azimuthScale.append(swaths[0].azimuthLineInterval /
                            swaths[i].azimuthLineInterval)
        if i == 0:
            rectWidth.append(
                int(swaths[i].numberOfSamples / numberOfRangeLooks))
            rectLength.append(
                int(swaths[i].numberOfLines / numberOfAzimuthLooks))
        else:
            rectWidth.append(
                int(1.0 / rangeScale[i] *
                    int(swaths[i].numberOfSamples / numberOfRangeLooks)))
            rectLength.append(
                int(1.0 / azimuthScale[i] *
                    int(swaths[i].numberOfLines / numberOfAzimuthLooks)))

    #convert original offset to offset for images with looks
    #use list instead of np.array to make it consistent with the rest of the code
    rangeOffsets1 = [i / numberOfRangeLooks for i in rangeOffsets]
    azimuthOffsets1 = [i / numberOfAzimuthLooks for i in azimuthOffsets]

    #get offset relative to the first frame
    rangeOffsets2 = [0.0]
    azimuthOffsets2 = [0.0]
    for i in range(1, numberOfSwaths):
        rangeOffsets2.append(0.0)
        azimuthOffsets2.append(0.0)
        for j in range(1, i + 1):
            rangeOffsets2[i] += rangeOffsets1[j]
            azimuthOffsets2[i] += azimuthOffsets1[j]

    #resample each swath
    rinfs = []
    for i, inf in enumerate(inputFiles):
        rinfs.append("{}_{}{}".format(
            os.path.splitext(os.path.basename(inf))[0], i,
            os.path.splitext(os.path.basename(inf))[1]))
        #do not resample first swath
        if i == 0:
            if os.path.isfile(rinfs[i]):
                os.remove(rinfs[i])
            os.symlink(inf, rinfs[i])
        else:
            infImg = isceobj.createImage()
            infImg.load(inf + '.xml')
            rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
            azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])

            if resamplingMethod == 0:
                rect_with_looks(inf, rinfs[i], infImg.width, infImg.length,
                                rectWidth[i], rectLength[i], rangeScale[i],
                                0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'COMPLEX', 'Bilinear')
            elif resamplingMethod == 1:
                #decompose amplitude and phase
                phaseFile = 'phase'
                amplitudeFile = 'amplitude'
                data = np.fromfile(inf, dtype=np.complex64).reshape(
                    infImg.length, infImg.width)
                phase = np.exp(np.complex64(1j) * np.angle(data))
                phase[np.nonzero(data == 0)] = 0
                phase.astype(np.complex64).tofile(phaseFile)
                amplitude = np.absolute(data)
                amplitude.astype(np.float32).tofile(amplitudeFile)

                #resampling
                phaseRectFile = 'phaseRect'
                amplitudeRectFile = 'amplitudeRect'
                rect_with_looks(phaseFile, phaseRectFile, infImg.width,
                                infImg.length, rectWidth[i], rectLength[i],
                                rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'COMPLEX', 'Sinc')
                rect_with_looks(amplitudeFile, amplitudeRectFile, infImg.width,
                                infImg.length, rectWidth[i], rectLength[i],
                                rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                rangeOffsets2Frac * rangeScale[i],
                                azimuthOffsets2Frac * azimuthScale[i], 1, 1, 1,
                                1, 'REAL', 'Bilinear')

                #recombine amplitude and phase
                phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(
                    rectLength[i], rectWidth[i])
                amplitude = np.fromfile(amplitudeRectFile,
                                        dtype=np.float32).reshape(
                                            rectLength[i], rectWidth[i])
                (phase * amplitude).astype(np.complex64).tofile(rinfs[i])

                #tidy up
                os.remove(phaseFile)
                os.remove(amplitudeFile)
                os.remove(phaseRectFile)
                os.remove(amplitudeRectFile)

    #determine output width and length
    #actually no need to calculate in range direction
    xs = []
    xe = []
    ys = []
    ye = []
    for i in range(numberOfSwaths):
        if i == 0:
            xs.append(0)
            xe.append(rectWidth[i] - 1)
            ys.append(0)
            ye.append(rectLength[i] - 1)
        else:
            xs.append(0 - int(rangeOffsets2[i]))
            xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i]))
            ys.append(0 - int(azimuthOffsets2[i]))
            ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i]))

    (xmin, xminIndex) = min((v, i) for i, v in enumerate(xs))
    (xmax, xmaxIndex) = max((v, i) for i, v in enumerate(xe))
    (ymin, yminIndex) = min((v, i) for i, v in enumerate(ys))
    (ymax, ymaxIndex) = max((v, i) for i, v in enumerate(ye))

    outWidth = xmax - xmin + 1
    outLength = ymax - ymin + 1

    #prepare offset for mosaicing
    rangeOffsets3 = []
    azimuthOffsets3 = []
    for i in range(numberOfSwaths):
        azimuthOffsets3.append(
            int(azimuthOffsets2[i]) - int(azimuthOffsets2[yminIndex]))
        if i != 0:
            rangeOffsets3.append(
                int(rangeOffsets2[i]) - int(rangeOffsets2[i - 1]))
        else:
            rangeOffsets3.append(0)

    delta = int(30 / numberOfRangeLooks)

    #compute compensation phase for each swath
    diffMean2 = [0.0 for i in range(numberOfSwaths)]
    if phaseCompensation:
        #compute swath phase offset
        diffMean = [0.0]
        for i in range(1, numberOfSwaths):
            #all indexes start with zero, all the computed start/end sample/line indexes are included.

            #no need to add edge here, as we are going to find first/last nonzero sample/lines later
            #edge = delta
            edge = 0

            #image i-1
            startSample1 = edge + 0 - int(rangeOffsets2[i]) + int(
                rangeOffsets2[i - 1])
            endSample1 = -edge + rectWidth[i - 1] - 1
            startLine1 = edge + max(
                0 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i - 1]), 0)
            endLine1 = -edge + min(
                rectLength[i] - 1 - int(azimuthOffsets2[i]) +
                int(azimuthOffsets2[i - 1]), rectLength[i - 1] - 1)
            data1 = readImage(rinfs[i - 1], rectWidth[i - 1],
                              rectLength[i - 1], startSample1, endSample1,
                              startLine1, endLine1)

            #image i
            startSample2 = edge + 0
            endSample2 = -edge + rectWidth[i - 1] - 1 - int(
                rangeOffsets2[i - 1]) + int(rangeOffsets2[i])
            startLine2 = edge + max(
                0 - int(azimuthOffsets2[i - 1]) + int(azimuthOffsets2[i]), 0)
            endLine2 = -edge + min(
                rectLength[i - 1] - 1 - int(azimuthOffsets2[i - 1]) +
                int(azimuthOffsets2[i]), rectLength[i] - 1)
            data2 = readImage(rinfs[i], rectWidth[i], rectLength[i],
                              startSample2, endSample2, startLine2, endLine2)

            #remove edge due to incomplete covolution in resampling
            edge = 9
            (startLine0, endLine0, startSample0, endSample0) = findNonzero(
                np.logical_and((data1 != 0), (data2 != 0)))
            data1 = data1[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]
            data2 = data2[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]

            #take looks
            data1 = multilook(data1, pcAzimuthLooks, pcRangeLooks)
            data2 = multilook(data2, pcAzimuthLooks, pcRangeLooks)

            #filter
            if filt:
                data1 /= (np.absolute(data1) + (data1 == 0))
                data2 /= (np.absolute(data2) + (data2 == 0))
                data1 = filterInterferogram(data1, 3.0, 64, 1)
                data2 = filterInterferogram(data2, 3.0, 64, 1)

            #get difference
            corth = 0.87
            if filt:
                corth = 0.90
            diffMean0 = 0.0
            for k in range(5):
                dataDiff = data1 * np.conj(data2)
                cor = cal_coherence_1(dataDiff, win=3)
                index = np.nonzero(np.logical_and(cor > corth, dataDiff != 0))
                if index[0].size < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation between swath {} and {}'
                        .format(i - 1, i))
                    print('       : first swath swath number: 0\n\n')
                    break
                angle = np.mean(np.angle(dataDiff[index]), dtype=np.float64)
                diffMean0 += angle
                data2 *= np.exp(np.complex64(1j) * angle)
                print('phase offset: %15.12f rad after loop: %3d' %
                      (diffMean0, k))

                DEBUG = False
                if DEBUG and (k == 0):
                    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                    (lengthxx, widthxx) = dataDiff.shape
                    filtnamePrefix = 'subswath{}_subswath{}_loop{}'.format(
                        frame.swaths[i - 1].swathNumber,
                        frame.swaths[i].swathNumber, k)
                    cor.astype(np.float32).tofile(filtnamePrefix + '.cor')
                    create_xml(filtnamePrefix + '.cor', widthxx, lengthxx,
                               'float')
                    dataDiff.astype(np.complex64).tofile(filtnamePrefix +
                                                         '.int')
                    create_xml(filtnamePrefix + '.int', widthxx, lengthxx,
                               'int')

            diffMean.append(diffMean0)
            print('phase offset: subswath{} - subswath{}: {}'.format(
                frame.swaths[i - 1].swathNumber, frame.swaths[i].swathNumber,
                diffMean0))

        for i in range(1, numberOfSwaths):
            for j in range(1, i + 1):
                diffMean2[i] += diffMean[j]

    #mosaic swaths
    diffflag = 1
    oflag = [0 for i in range(numberOfSwaths)]
    mosaicsubswath(outputfile, outWidth, outLength, delta, diffflag,
                   numberOfSwaths, rinfs, rectWidth, rangeOffsets3,
                   azimuthOffsets3, diffMean2, oflag)
    #remove tmp files
    for x in rinfs:
        os.remove(x)

    #update frame parameters
    if updateFrame:
        #mosaic size
        frame.numberOfSamples = outWidth
        frame.numberOfLines = outLength
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        frame.startingRange = frame.swaths[0].startingRange
        frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
        frame.rangePixelSize = frame.swaths[0].rangePixelSize
        #azimuth parameters
        azimuthTimeOffset = -max([
            int(x) for x in azimuthOffsets2
        ]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval
        frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(
            seconds=azimuthTimeOffset)
        frame.prf = frame.swaths[0].prf
        frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
        frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval
Esempio n. 3
0
def swathMosaic(frame,
                inputFiles,
                outputfile,
                rangeOffsets,
                azimuthOffsets,
                numberOfRangeLooks,
                numberOfAzimuthLooks,
                updateFrame=False,
                phaseCompensation=False,
                phaseDiff=None,
                phaseDiffFixed=None,
                snapThreshold=None,
                snapSwath=None,
                pcRangeLooks=1,
                pcAzimuthLooks=4,
                filt=False,
                resamplingMethod=0):
    '''
    mosaic swaths
    
    #PART 1. REGULAR INPUT PARAMTERS
    frame:                 frame
    inputFiles:            input file list
    outputfile:            output mosaic file
    rangeOffsets:          range offsets
    azimuthOffsets:        azimuth offsets
    numberOfRangeLooks:    number of range looks of the input files
    numberOfAzimuthLooks:  number of azimuth looks of the input files
    updateFrame:           whether update frame parameters

    #PART 2. PARAMETERS FOR COMPUTING PHASE DIFFERENCE BETWEEN SUBSWATHS
    phaseCompensation:     whether do phase compensation for each swath
    phaseDiff:             pre-computed compensation phase for each swath
    phaseDiffFixed:        if provided, the estimated value will snap to one of these values, which is nearest to the estimated one.
    snapThreshold:         this is used with phaseDiffFixed
    snapSwath:             indicate whether snap to fixed values for each swath phase diff, must be specified if phaseDiffFixed!=None
    pcRangeLooks:          number of range looks to take when compute swath phase difference
    pcAzimuthLooks:        number of azimuth looks to take when compute swath phase difference
    filt:                  whether do filtering when compute swath phase difference

    #PART 3. RESAMPLING METHOD
    resamplingMethod:      0: amp resampling. 1: int resampling.
    '''
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from contrib.alos2proc.alos2proc import mosaicsubswath
    from isceobj.Alos2Proc.Alos2ProcPublic import multilook
    from isceobj.Alos2Proc.Alos2ProcPublic import cal_coherence_1
    from isceobj.Alos2Proc.Alos2ProcPublic import filterInterferogram
    from isceobj.Alos2Proc.Alos2ProcPublic import computePhaseDiff
    from isceobj.Alos2Proc.Alos2ProcPublic import snap

    numberOfSwaths = len(frame.swaths)
    swaths = frame.swaths

    rangeScale = []
    azimuthScale = []
    rectWidth = []
    rectLength = []
    for i in range(numberOfSwaths):
        rangeScale.append(swaths[0].rangePixelSize / swaths[i].rangePixelSize)
        azimuthScale.append(swaths[0].azimuthLineInterval /
                            swaths[i].azimuthLineInterval)
        if i == 0:
            rectWidth.append(
                int(swaths[i].numberOfSamples / numberOfRangeLooks))
            rectLength.append(
                int(swaths[i].numberOfLines / numberOfAzimuthLooks))
        else:
            rectWidth.append(
                round(1.0 / rangeScale[i] *
                      int(swaths[i].numberOfSamples / numberOfRangeLooks)))
            rectLength.append(
                round(1.0 / azimuthScale[i] *
                      int(swaths[i].numberOfLines / numberOfAzimuthLooks)))
            #rectWidth.append( int(1.0 / rangeScale[i] * int(swaths[i].numberOfSamples / numberOfRangeLooks)) )
            #rectLength.append( int(1.0 / azimuthScale[i] * int(swaths[i].numberOfLines / numberOfAzimuthLooks)) )

    #convert original offset to offset for images with looks
    #use list instead of np.array to make it consistent with the rest of the code
    rangeOffsets1 = [i / numberOfRangeLooks for i in rangeOffsets]
    azimuthOffsets1 = [i / numberOfAzimuthLooks for i in azimuthOffsets]

    #get offset relative to the first frame
    rangeOffsets2 = [0.0]
    azimuthOffsets2 = [0.0]
    for i in range(1, numberOfSwaths):
        rangeOffsets2.append(0.0)
        azimuthOffsets2.append(0.0)
        for j in range(1, i + 1):
            rangeOffsets2[i] += rangeOffsets1[j]
            azimuthOffsets2[i] += azimuthOffsets1[j]

    #resample each swath
    rinfs = []
    for i, inf in enumerate(inputFiles):
        rinfs.append("{}_{}{}".format(
            os.path.splitext(os.path.basename(inf))[0], i,
            os.path.splitext(os.path.basename(inf))[1]))
        #do not resample first swath
        if i == 0:
            if os.path.isfile(rinfs[i]):
                os.remove(rinfs[i])
            os.symlink(inf, rinfs[i])
        else:
            #no need to resample
            if (abs(rangeOffsets2[i] - round(rangeOffsets2[i])) < 0.0001) and (
                    abs(azimuthOffsets2[i] - round(azimuthOffsets2[i])) <
                    0.0001):
                if os.path.isfile(rinfs[i]):
                    os.remove(rinfs[i])
                os.symlink(inf, rinfs[i])
                #all of the following use of rangeOffsets2/azimuthOffsets2 is inside int(), we do the following in case it is like
                #4.99999999999...
                rangeOffsets2[i] = round(rangeOffsets2[i])
                azimuthOffsets2[i] = round(azimuthOffsets2[i])
            else:
                infImg = isceobj.createImage()
                infImg.load(inf + '.xml')
                rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
                azimuthOffsets2Frac = azimuthOffsets2[i] - int(
                    azimuthOffsets2[i])

                if resamplingMethod == 0:
                    rect_with_looks(inf, rinfs[i], infImg.width, infImg.length,
                                    rectWidth[i], rectLength[i], rangeScale[i],
                                    0.0, 0.0, azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'COMPLEX', 'Bilinear')
                elif resamplingMethod == 1:
                    #decompose amplitude and phase
                    phaseFile = 'phase'
                    amplitudeFile = 'amplitude'
                    data = np.fromfile(inf, dtype=np.complex64).reshape(
                        infImg.length, infImg.width)
                    phase = np.exp(np.complex64(1j) * np.angle(data))
                    phase[np.nonzero(data == 0)] = 0
                    phase.astype(np.complex64).tofile(phaseFile)
                    amplitude = np.absolute(data)
                    amplitude.astype(np.float32).tofile(amplitudeFile)

                    #resampling
                    phaseRectFile = 'phaseRect'
                    amplitudeRectFile = 'amplitudeRect'
                    rect_with_looks(phaseFile, phaseRectFile, infImg.width,
                                    infImg.length, rectWidth[i], rectLength[i],
                                    rangeScale[i], 0.0, 0.0, azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'COMPLEX', 'Sinc')
                    rect_with_looks(amplitudeFile, amplitudeRectFile,
                                    infImg.width, infImg.length, rectWidth[i],
                                    rectLength[i], rangeScale[i], 0.0, 0.0,
                                    azimuthScale[i],
                                    rangeOffsets2Frac * rangeScale[i],
                                    azimuthOffsets2Frac * azimuthScale[i], 1,
                                    1, 1, 1, 'REAL', 'Bilinear')

                    #recombine amplitude and phase
                    phase = np.fromfile(phaseRectFile,
                                        dtype=np.complex64).reshape(
                                            rectLength[i], rectWidth[i])
                    amplitude = np.fromfile(amplitudeRectFile,
                                            dtype=np.float32).reshape(
                                                rectLength[i], rectWidth[i])
                    (phase * amplitude).astype(np.complex64).tofile(rinfs[i])

                    #tidy up
                    os.remove(phaseFile)
                    os.remove(amplitudeFile)
                    os.remove(phaseRectFile)
                    os.remove(amplitudeRectFile)

    #determine output width and length
    #actually no need to calculate in range direction
    xs = []
    xe = []
    ys = []
    ye = []
    for i in range(numberOfSwaths):
        if i == 0:
            xs.append(0)
            xe.append(rectWidth[i] - 1)
            ys.append(0)
            ye.append(rectLength[i] - 1)
        else:
            xs.append(0 - int(rangeOffsets2[i]))
            xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i]))
            ys.append(0 - int(azimuthOffsets2[i]))
            ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i]))

    (xmin, xminIndex) = min((v, i) for i, v in enumerate(xs))
    (xmax, xmaxIndex) = max((v, i) for i, v in enumerate(xe))
    (ymin, yminIndex) = min((v, i) for i, v in enumerate(ys))
    (ymax, ymaxIndex) = max((v, i) for i, v in enumerate(ye))

    outWidth = xmax - xmin + 1
    outLength = ymax - ymin + 1

    #prepare offset for mosaicing
    rangeOffsets3 = []
    azimuthOffsets3 = []
    for i in range(numberOfSwaths):
        azimuthOffsets3.append(
            int(azimuthOffsets2[i]) - int(azimuthOffsets2[yminIndex]))
        if i != 0:
            rangeOffsets3.append(
                int(rangeOffsets2[i]) - int(rangeOffsets2[i - 1]))
        else:
            rangeOffsets3.append(0)

    delta = int(30 / numberOfRangeLooks)

    #compute compensation phase for each swath
    diffMean2 = [0.0 for i in range(numberOfSwaths)]
    phaseDiffEst = [None for i in range(numberOfSwaths)]
    #True if:
    #  (1) used diff phase from input
    #  (2) used estimated diff phase after snapping to a fixed diff phase provided
    #False if:
    #  (1) used purely estimated diff phase
    phaseDiffSource = ['estimated' for i in range(numberOfSwaths)]
    # 1. 'estimated': estimated from subswath overlap
    # 2. 'estimated+snap': estimated from subswath overlap and snap to a fixed value
    # 3. 'input': pre-computed
    # confidence level: 3 > 2 > 1
    numberOfValidSamples = [None for i in range(numberOfSwaths)]
    # only record when (filt == False) and (index[0].size >= 4000)
    if phaseCompensation:
        #compute swath phase offset
        diffMean = [0.0]
        for i in range(1, numberOfSwaths):

            #no need to estimate diff phase if provided from input
            #####################################################################
            if phaseDiff != None:
                if phaseDiff[i] != None:
                    diffMean.append(phaseDiff[i])
                    phaseDiffSource[i] = 'input'
                    print('using pre-computed phase offset given from input')
                    print('phase offset: subswath{} - subswath{}: {}'.format(
                        frame.swaths[i - 1].swathNumber,
                        frame.swaths[i].swathNumber, phaseDiff[i]))
                    continue
            #####################################################################

            #all indexes start with zero, all the computed start/end sample/line indexes are included.

            #no need to add edge here, as we are going to find first/last nonzero sample/lines later
            #edge = delta
            edge = 0

            #image i-1
            startSample1 = edge + 0 - int(rangeOffsets2[i]) + int(
                rangeOffsets2[i - 1])
            endSample1 = -edge + rectWidth[i - 1] - 1
            startLine1 = edge + max(
                0 - int(azimuthOffsets2[i]) + int(azimuthOffsets2[i - 1]), 0)
            endLine1 = -edge + min(
                rectLength[i] - 1 - int(azimuthOffsets2[i]) +
                int(azimuthOffsets2[i - 1]), rectLength[i - 1] - 1)
            data1 = readImage(rinfs[i - 1], rectWidth[i - 1],
                              rectLength[i - 1], startSample1, endSample1,
                              startLine1, endLine1)

            #image i
            startSample2 = edge + 0
            endSample2 = -edge + rectWidth[i - 1] - 1 - int(
                rangeOffsets2[i - 1]) + int(rangeOffsets2[i])
            startLine2 = edge + max(
                0 - int(azimuthOffsets2[i - 1]) + int(azimuthOffsets2[i]), 0)
            endLine2 = -edge + min(
                rectLength[i - 1] - 1 - int(azimuthOffsets2[i - 1]) +
                int(azimuthOffsets2[i]), rectLength[i] - 1)
            data2 = readImage(rinfs[i], rectWidth[i], rectLength[i],
                              startSample2, endSample2, startLine2, endLine2)

            #remove edge due to incomplete covolution in resampling
            edge = 9
            (startLine0, endLine0, startSample0, endSample0) = findNonzero(
                np.logical_and((data1 != 0), (data2 != 0)))
            data1 = data1[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]
            data2 = data2[startLine0 + edge:endLine0 + 1 - edge,
                          startSample0 + edge:endSample0 + 1 - edge]

            #take looks
            data1 = multilook(data1, pcAzimuthLooks, pcRangeLooks)
            data2 = multilook(data2, pcAzimuthLooks, pcRangeLooks)

            #filter
            if filt:
                data1 /= (np.absolute(data1) + (data1 == 0))
                data2 /= (np.absolute(data2) + (data2 == 0))
                data1 = filterInterferogram(data1, 3.0, 64, 1)
                data2 = filterInterferogram(data2, 3.0, 64, 1)

            #get difference
            dataDiff = data1 * np.conj(data2)
            cor = cal_coherence_1(dataDiff, win=5)
            index = np.nonzero(np.logical_and(cor > 0.85, dataDiff != 0))

            DEBUG = False
            if DEBUG:
                from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                (length7, width7) = dataDiff.shape
                filename = 'diff_ori_s{}-s{}.int'.format(
                    frame.swaths[i - 1].swathNumber,
                    frame.swaths[i].swathNumber)
                dataDiff.astype(np.complex64).tofile(filename)
                create_xml(filename, width7, length7, 'int')
                filename = 'cor_ori_s{}-s{}.cor'.format(
                    frame.swaths[i - 1].swathNumber,
                    frame.swaths[i].swathNumber)
                cor.astype(np.float32).tofile(filename)
                create_xml(filename, width7, length7, 'float')

            print('\ncompute phase difference between subswaths {} and {}'.
                  format(frame.swaths[i - 1].swathNumber,
                         frame.swaths[i].swathNumber))
            print('number of pixels with coherence > 0.85: {}'.format(
                index[0].size))

            #if already filtered the subswath overlap interferograms (MAI), do not filtered differential interferograms
            if (filt == False) and (index[0].size < 4000):
                #coherence too low, filter subswath overlap differential interferogram
                diffMean0 = 0.0
                breakFlag = False
                for (filterStrength, filterWinSize) in zip([3.0, 9.0],
                                                           [64, 128]):
                    dataDiff = data1 * np.conj(data2)
                    dataDiff /= (np.absolute(dataDiff) + (dataDiff == 0))
                    dataDiff = filterInterferogram(dataDiff, filterStrength,
                                                   filterWinSize, 1)
                    cor = cal_coherence_1(dataDiff, win=7)

                    DEBUG = False
                    if DEBUG:
                        from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
                        (length7, width7) = dataDiff.shape
                        filename = 'diff_filt_s{}-s{}_strength_{}_winsize_{}.int'.format(
                            frame.swaths[i - 1].swathNumber,
                            frame.swaths[i].swathNumber, filterStrength,
                            filterWinSize)
                        dataDiff.astype(np.complex64).tofile(filename)
                        create_xml(filename, width7, length7, 'int')
                        filename = 'cor_filt_s{}-s{}_strength_{}_winsize_{}.cor'.format(
                            frame.swaths[i - 1].swathNumber,
                            frame.swaths[i].swathNumber, filterStrength,
                            filterWinSize)
                        cor.astype(np.float32).tofile(filename)
                        create_xml(filename, width7, length7, 'float')

                    for corth in [0.99999, 0.9999]:
                        index = np.nonzero(
                            np.logical_and(cor > corth, dataDiff != 0))
                        if index[0].size > 30000:
                            breakFlag = True
                            break
                    if breakFlag:
                        break

                if index[0].size < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation'
                    )
                    print('         number of high coherence pixels: {}\n\n'.
                          format(index[0].size))
                else:
                    print(
                        'filtered coherence threshold used: {}, number of pixels used: {}'
                        .format(corth, index[0].size))
                    angle = np.mean(np.angle(dataDiff[index]),
                                    dtype=np.float64)
                    diffMean0 += angle
                    data2 *= np.exp(np.complex64(1j) * angle)
                    print(
                        'phase offset: %15.12f rad with filter strength: %f, window size: %3d'
                        % (diffMean0, filterStrength, filterWinSize))
            else:
                if filt:
                    (diffMean0, numberOfValidSamples[i]) = computePhaseDiff(
                        data1,
                        data2,
                        coherenceWindowSize=5,
                        coherenceThreshold=0.95)
                else:
                    (diffMean0, numberOfValidSamples[i]) = computePhaseDiff(
                        data1,
                        data2,
                        coherenceWindowSize=5,
                        coherenceThreshold=0.85)
                if numberOfValidSamples[i] < 100:
                    diffMean0 = 0.0
                    print(
                        '\n\nWARNING: too few high coherence pixels for swath phase difference estimation'
                    )
                    print('         number of high coherence pixels: {}\n\n'.
                          format(numberOfValidSamples[i]))

                #do not record when filt
                if filt:
                    numberOfValidSamples[i] = None

            #save purely estimated diff phase
            phaseDiffEst[i] = diffMean0

            #if fixed diff phase provided and the estimated diff phase is close enough to a fixed value, snap to it
            if phaseDiffFixed != None:
                if snapSwath[i - 1] == True:
                    (outputValue, snapped) = snap(diffMean0, phaseDiffFixed,
                                                  snapThreshold)
                    if snapped == True:
                        diffMean0 = outputValue
                        phaseDiffSource[i] = 'estimated+snap'

            diffMean.append(diffMean0)
            print('phase offset: subswath{} - subswath{}: {}'.format(
                frame.swaths[i - 1].swathNumber, frame.swaths[i].swathNumber,
                diffMean0))

        for i in range(1, numberOfSwaths):
            for j in range(1, i + 1):
                diffMean2[i] += diffMean[j]

    #mosaic swaths
    diffflag = 1
    oflag = [0 for i in range(numberOfSwaths)]
    mosaicsubswath(outputfile, outWidth, outLength, delta, diffflag,
                   numberOfSwaths, rinfs, rectWidth, rangeOffsets3,
                   azimuthOffsets3, diffMean2, oflag)
    #remove tmp files
    for x in rinfs:
        os.remove(x)

    #update frame parameters
    if updateFrame:
        #mosaic size
        frame.numberOfSamples = outWidth
        frame.numberOfLines = outLength
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        frame.startingRange = frame.swaths[0].startingRange
        frame.rangeSamplingRate = frame.swaths[0].rangeSamplingRate
        frame.rangePixelSize = frame.swaths[0].rangePixelSize
        #azimuth parameters
        azimuthTimeOffset = -max([
            int(x) for x in azimuthOffsets2
        ]) * numberOfAzimuthLooks * frame.swaths[0].azimuthLineInterval
        frame.sensingStart = frame.swaths[0].sensingStart + datetime.timedelta(
            seconds=azimuthTimeOffset)
        frame.prf = frame.swaths[0].prf
        frame.azimuthPixelSize = frame.swaths[0].azimuthPixelSize
        frame.azimuthLineInterval = frame.swaths[0].azimuthLineInterval

    if phaseCompensation:
        # estimated phase diff, used phase diff, used phase diff source
        return (phaseDiffEst, diffMean, phaseDiffSource, numberOfValidSamples)
Esempio n. 4
0
def estimateSwathOffset(swath1,
                        swath2,
                        image1,
                        image2,
                        rangeScale1=1,
                        azimuthScale1=1,
                        rangeScale2=1,
                        azimuthScale2=1,
                        numberOfAzimuthLooks=10):
    '''
    estimate offset of two adjacent swaths using matching
    '''
    from osgeo import gdal
    import isceobj
    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from isceobj.Alos2Proc.Alos2ProcPublic import cullOffsets
    from isceobj.Alos2Proc.Alos2ProcPublic import meanOffset
    from mroipac.ampcor.Ampcor import Ampcor

    #processing image 1
    rangeOff1 = int(
        (swath2.startingRange - swath1.startingRange) / swath1.rangePixelSize)
    if rangeOff1 < 0:
        rangeOff1 = 0
    numberOfSamples1 = swath1.numberOfSamples - rangeOff1

    numberOfSamplesRect1 = int(numberOfSamples1 / rangeScale1)
    numberOfLinesRect1 = int(swath1.numberOfLines / azimuthScale1)

    numberOfSamplesLook1 = int(numberOfSamplesRect1 / 1)
    numberOfLinesLook1 = int(numberOfLinesRect1 / numberOfAzimuthLooks)

    #get magnitude image whether complex or not
    #ReadAsArray: https://pcjericks.github.io/py-gdalogr-cookbook/raster_layers.html
    ds = gdal.Open(image1 + '.vrt', gdal.GA_ReadOnly)
    data = ds.ReadAsArray(rangeOff1, 0, numberOfSamples1, swath1.numberOfLines)
    ds = None
    (np.absolute(data)).astype(np.float32).tofile('image1.float')

    #rectify
    if rangeScale1 == 1 and azimuthScale1 == 1:
        os.rename('image1.float', 'image1_rect.float')
    else:
        rect_with_looks('image1.float', 'image1_rect.float', numberOfSamples1,
                        swath1.numberOfLines, numberOfSamplesRect1,
                        numberOfLinesRect1, rangeScale1, 0.0, 0.0,
                        azimuthScale1, 0.0, 0.0, 1, 1, 1, 1, 'REAL',
                        'Bilinear')
        os.remove('image1.float')

    #take looks
    if numberOfAzimuthLooks == 1:
        os.rename('image1_rect.float', 'image1_look.float')
    else:
        data1 = np.fromfile('image1_rect.float',
                            dtype=np.float32).reshape(numberOfLinesRect1,
                                                      numberOfSamplesRect1)
        data1 = np.sqrt(multilook(data1**2, numberOfAzimuthLooks, 1))
        data1.astype(np.float32).tofile('image1_look.float')
        os.remove('image1_rect.float')
    create_xml('image1_look.float', numberOfSamplesLook1, numberOfLinesLook1,
               'float')

    #processing image 2
    rangeOff2 = 0
    numberOfSamples2 = int(
        (swath1.startingRange + swath1.rangePixelSize *
         (swath1.numberOfSamples - 1) - swath2.startingRange) /
        swath2.rangePixelSize) + 1
    if numberOfSamples2 > swath2.numberOfSamples:
        numberOfSamples2 = swath2.numberOfSamples

    numberOfSamplesRect2 = int(numberOfSamples2 / rangeScale2)
    numberOfLinesRect2 = int(swath2.numberOfLines / azimuthScale2)

    numberOfSamplesLook2 = int(numberOfSamplesRect2 / 1)
    numberOfLinesLook2 = int(numberOfLinesRect2 / numberOfAzimuthLooks)

    #get magnitude image whether complex or not
    ds = gdal.Open(image2 + '.vrt', gdal.GA_ReadOnly)
    data = ds.ReadAsArray(rangeOff2, 0, numberOfSamples2, swath2.numberOfLines)
    ds = None
    (np.absolute(data)).astype(np.float32).tofile('image2.float')

    #rectify
    if rangeScale2 == 1 and azimuthScale2 == 1:
        os.rename('image2.float', 'image2_rect.float')
    else:
        rect_with_looks('image2.float', 'image2_rect.float', numberOfSamples2,
                        swath2.numberOfLines, numberOfSamplesRect2,
                        numberOfLinesRect2, rangeScale2, 0.0, 0.0,
                        azimuthScale2, 0.0, 0.0, 1, 1, 1, 1, 'REAL',
                        'Bilinear')
        os.remove('image2.float')

    #take looks
    if numberOfAzimuthLooks == 1:
        os.rename('image2_rect.float', 'image2_look.float')
    else:
        data2 = np.fromfile('image2_rect.float',
                            dtype=np.float32).reshape(numberOfLinesRect2,
                                                      numberOfSamplesRect2)
        data2 = np.sqrt(multilook(data2**2, numberOfAzimuthLooks, 1))
        data2.astype(np.float32).tofile('image2_look.float')
        os.remove('image2_rect.float')
    create_xml('image2_look.float', numberOfSamplesLook2, numberOfLinesLook2,
               'float')

    #matching
    ampcor = Ampcor(name='insarapp_slcs_ampcor')
    ampcor.configure()

    mMag = isceobj.createImage()
    mMag.load('image1_look.float.xml')
    mMag.setAccessMode('read')
    mMag.createImage()

    sMag = isceobj.createImage()
    sMag.load('image2_look.float.xml')
    sMag.setAccessMode('read')
    sMag.createImage()

    ampcor.setImageDataType1('real')
    ampcor.setImageDataType2('real')

    ampcor.setReferenceSlcImage(mMag)
    ampcor.setSecondarySlcImage(sMag)

    #MATCH REGION
    rgoff = 0
    azoff = int(
        (swath1.sensingStart - swath2.sensingStart).total_seconds() /
        swath1.azimuthLineInterval / azimuthScale1 / numberOfAzimuthLooks)
    #it seems that we cannot use 0, haven't look into the problem
    if rgoff == 0:
        rgoff = 1
    if azoff == 0:
        azoff = 1
    firstSample = 1
    if rgoff < 0:
        firstSample = int(35 - rgoff)
    firstLine = 1
    if azoff < 0:
        firstLine = int(35 - azoff)
    ampcor.setAcrossGrossOffset(rgoff)
    ampcor.setDownGrossOffset(azoff)
    ampcor.setFirstSampleAcross(firstSample)
    ampcor.setLastSampleAcross(numberOfSamplesLook1)
    ampcor.setNumberLocationAcross(20)
    ampcor.setFirstSampleDown(firstLine)
    ampcor.setLastSampleDown(numberOfLinesLook1)
    ampcor.setNumberLocationDown(100)

    #MATCH PARAMETERS
    ampcor.setWindowSizeWidth(32)
    ampcor.setWindowSizeHeight(32)
    #note this is the half width/length of search area, so number of resulting correlation samples: 8*2+1
    ampcor.setSearchWindowSizeWidth(8)
    ampcor.setSearchWindowSizeHeight(8)

    #REST OF THE STUFF
    ampcor.setAcrossLooks(1)
    ampcor.setDownLooks(1)
    ampcor.setOversamplingFactor(64)
    ampcor.setZoomWindowSize(16)
    #1. The following not set
    #Matching Scale for Sample/Line Directions                       (-)    = 1. 1.
    #should add the following in Ampcor.py?
    #if not set, in this case, Ampcor.py'value is also 1. 1.
    #ampcor.setScaleFactorX(1.)
    #ampcor.setScaleFactorY(1.)

    #MATCH THRESHOLDS AND DEBUG DATA
    #2. The following not set
    #in roi_pac the value is set to 0 1
    #in isce the value is set to 0.001 1000.0
    #SNR and Covariance Thresholds                                   (-)    =  {s1} {s2}
    #should add the following in Ampcor?
    #THIS SHOULD BE THE ONLY THING THAT IS DIFFERENT FROM THAT OF ROI_PAC
    #ampcor.setThresholdSNR(0)
    #ampcor.setThresholdCov(1)
    ampcor.setDebugFlag(False)
    ampcor.setDisplayFlag(False)

    #in summary, only two things not set which are indicated by 'The following not set' above.

    #run ampcor
    ampcor.ampcor()
    offsets = ampcor.getOffsetField()
    refinedOffsets = cullOffsets(offsets)

    #finalize image, and re-create it
    #otherwise the file pointer is still at the end of the image
    mMag.finalizeImage()
    sMag.finalizeImage()

    os.remove('image1_look.float')
    os.remove('image1_look.float.vrt')
    os.remove('image1_look.float.xml')
    os.remove('image2_look.float')
    os.remove('image2_look.float.vrt')
    os.remove('image2_look.float.xml')

    if refinedOffsets != None:
        rangeOffset, azimuthOffset = meanOffset(refinedOffsets)
        rangeOffset -= rangeOff1 / rangeScale1
        azimuthOffset *= numberOfAzimuthLooks
        return (rangeOffset, azimuthOffset)
    else:
        return None
Esempio n. 5
0
def frameMosaic(track,
                inputFiles,
                outputfile,
                rangeOffsets,
                azimuthOffsets,
                numberOfRangeLooks,
                numberOfAzimuthLooks,
                updateTrack=False,
                phaseCompensation=False,
                resamplingMethod=0):
    '''
    mosaic frames
    
    track:                 track
    inputFiles:            input file list
    output file:           output mosaic file
    rangeOffsets:          range offsets
    azimuthOffsets:        azimuth offsets
    numberOfRangeLooks:    number of range looks of the input files
    numberOfAzimuthLooks:  number of azimuth looks of the input files
    updateTrack:           whether update track parameters
    phaseCompensation:     whether do phase compensation for each frame
    resamplingMethod:      0: amp resampling. 1: int resampling. 2: slc resampling
    '''
    import numpy as np

    from contrib.alos2proc_f.alos2proc_f import rect_with_looks
    from contrib.alos2proc.alos2proc import resamp
    from isceobj.Alos2Proc.runSwathMosaic import readImage
    from isceobj.Alos2Proc.runSwathMosaic import findNonzero
    from isceobj.Alos2Proc.Alos2ProcPublic import create_xml
    from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_file
    from isceobj.Alos2Proc.Alos2ProcPublic import find_vrt_keyword

    numberOfFrames = len(track.frames)
    frames = track.frames

    rectWidth = []
    rectLength = []
    for i in range(numberOfFrames):
        infImg = isceobj.createImage()
        infImg.load(inputFiles[i] + '.xml')
        rectWidth.append(infImg.width)
        rectLength.append(infImg.length)

    #convert original offset to offset for images with looks
    #use list instead of np.array to make it consistent with the rest of the code
    rangeOffsets1 = [i / numberOfRangeLooks for i in rangeOffsets]
    azimuthOffsets1 = [i / numberOfAzimuthLooks for i in azimuthOffsets]

    #get offset relative to the first frame
    rangeOffsets2 = [0.0]
    azimuthOffsets2 = [0.0]
    for i in range(1, numberOfFrames):
        rangeOffsets2.append(0.0)
        azimuthOffsets2.append(0.0)
        for j in range(1, i + 1):
            rangeOffsets2[i] += rangeOffsets1[j]
            azimuthOffsets2[i] += azimuthOffsets1[j]

    #resample each frame
    rinfs = []
    for i, inf in enumerate(inputFiles):
        rinfs.append("{}_{}{}".format(
            os.path.splitext(os.path.basename(inf))[0], i,
            os.path.splitext(os.path.basename(inf))[1]))
        #do not resample first frame
        if i == 0:
            rinfs[i] = inf
        else:
            infImg = isceobj.createImage()
            infImg.load(inf + '.xml')
            rangeOffsets2Frac = rangeOffsets2[i] - int(rangeOffsets2[i])
            azimuthOffsets2Frac = azimuthOffsets2[i] - int(azimuthOffsets2[i])

            if resamplingMethod == 0:
                rect_with_looks(inf, rinfs[i], infImg.width, infImg.length,
                                infImg.width, infImg.length, 1.0, 0.0, 0.0,
                                1.0, rangeOffsets2Frac, azimuthOffsets2Frac, 1,
                                1, 1, 1, 'COMPLEX', 'Bilinear')
                if infImg.getImageType() == 'amp':
                    create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
                else:
                    create_xml(rinfs[i], infImg.width, infImg.length, 'int')

            elif resamplingMethod == 1:
                #decompose amplitude and phase
                phaseFile = 'phase'
                amplitudeFile = 'amplitude'
                data = np.fromfile(inf, dtype=np.complex64).reshape(
                    infImg.length, infImg.width)
                phase = np.exp(np.complex64(1j) * np.angle(data))
                phase[np.nonzero(data == 0)] = 0
                phase.astype(np.complex64).tofile(phaseFile)
                amplitude = np.absolute(data)
                amplitude.astype(np.float32).tofile(amplitudeFile)

                #resampling
                phaseRectFile = 'phaseRect'
                amplitudeRectFile = 'amplitudeRect'
                rect_with_looks(phaseFile, phaseRectFile, infImg.width,
                                infImg.length, infImg.width, infImg.length,
                                1.0, 0.0, 0.0, 1.0, rangeOffsets2Frac,
                                azimuthOffsets2Frac, 1, 1, 1, 1, 'COMPLEX',
                                'Sinc')
                rect_with_looks(amplitudeFile, amplitudeRectFile, infImg.width,
                                infImg.length, infImg.width, infImg.length,
                                1.0, 0.0, 0.0, 1.0, rangeOffsets2Frac,
                                azimuthOffsets2Frac, 1, 1, 1, 1, 'REAL',
                                'Bilinear')

                #recombine amplitude and phase
                phase = np.fromfile(phaseRectFile, dtype=np.complex64).reshape(
                    infImg.length, infImg.width)
                amplitude = np.fromfile(amplitudeRectFile,
                                        dtype=np.float32).reshape(
                                            infImg.length, infImg.width)
                (phase * amplitude).astype(np.complex64).tofile(rinfs[i])

                #tidy up
                os.remove(phaseFile)
                os.remove(amplitudeFile)
                os.remove(phaseRectFile)
                os.remove(amplitudeRectFile)
                if infImg.getImageType() == 'amp':
                    create_xml(rinfs[i], infImg.width, infImg.length, 'amp')
                else:
                    create_xml(rinfs[i], infImg.width, infImg.length, 'int')
            else:
                resamp(inf, rinfs[i], 'fake', 'fake', infImg.width,
                       infImg.length, frames[i].swaths[0].prf,
                       frames[i].swaths[0].dopplerVsPixel, [
                           rangeOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                           0.0, 0.0, 0.0
                       ], [
                           azimuthOffsets2Frac, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                           0.0, 0.0, 0.0
                       ])
                create_xml(rinfs[i], infImg.width, infImg.length, 'slc')

    #determine output width and length
    #actually no need to calculate in azimuth direction
    xs = []
    xe = []
    ys = []
    ye = []
    for i in range(numberOfFrames):
        if i == 0:
            xs.append(0)
            xe.append(rectWidth[i] - 1)
            ys.append(0)
            ye.append(rectLength[i] - 1)
        else:
            xs.append(0 - int(rangeOffsets2[i]))
            xe.append(rectWidth[i] - 1 - int(rangeOffsets2[i]))
            ys.append(0 - int(azimuthOffsets2[i]))
            ye.append(rectLength[i] - 1 - int(azimuthOffsets2[i]))

    (xmin, xminIndex) = min((v, i) for i, v in enumerate(xs))
    (xmax, xmaxIndex) = max((v, i) for i, v in enumerate(xe))
    (ymin, yminIndex) = min((v, i) for i, v in enumerate(ys))
    (ymax, ymaxIndex) = max((v, i) for i, v in enumerate(ye))

    outWidth = xmax - xmin + 1
    outLength = ymax - ymin + 1

    #prepare for mosaicing using numpy
    xs = [x - xmin for x in xs]
    xe = [x - xmin for x in xe]
    ys = [y - ymin for y in ys]
    ye = [y - ymin for y in ye]

    #compute phase offset
    if phaseCompensation:
        phaseOffsetPolynomials = [np.array([0.0])]
        for i in range(1, numberOfFrames):
            upperframe = np.zeros((ye[i - 1] - ys[i] + 1, outWidth),
                                  dtype=np.complex128)
            lowerframe = np.zeros((ye[i - 1] - ys[i] + 1, outWidth),
                                  dtype=np.complex128)
            #upper frame
            if os.path.isfile(rinfs[i - 1]):
                upperframe[:, xs[i - 1]:xe[i - 1] + 1] = readImage(
                    rinfs[i - 1], rectWidth[i - 1], rectLength[i - 1], 0,
                    rectWidth[i - 1] - 1, ys[i] - ys[i - 1],
                    ye[i - 1] - ys[i - 1])
            else:
                upperframe[:, xs[i - 1]:xe[i - 1] + 1] = readImageFromVrt(
                    rinfs[i - 1], 0, rectWidth[i - 1] - 1, ys[i] - ys[i - 1],
                    ye[i - 1] - ys[i - 1])
            #lower frame
            if os.path.isfile(rinfs[i]):
                lowerframe[:, xs[i]:xe[i] + 1] = readImage(
                    rinfs[i], rectWidth[i], rectLength[i], 0, rectWidth[i] - 1,
                    0, ye[i - 1] - ys[i])
            else:
                lowerframe[:, xs[i]:xe[i] + 1] = readImageFromVrt(
                    rinfs[i], 0, rectWidth[i] - 1, 0, ye[i - 1] - ys[i])
            #get a polynomial
            diff = np.sum(upperframe * np.conj(lowerframe), axis=0)
            (firstLine, lastLine, firstSample,
             lastSample) = findNonzero(np.reshape(diff, (1, outWidth)))
            #here i use mean value(deg=0) in case difference is around -pi or pi.
            deg = 0
            p = np.polyfit(np.arange(firstSample, lastSample + 1),
                           np.angle(diff[firstSample:lastSample + 1]), deg)
            phaseOffsetPolynomials.append(p)

            #check fit result
            DEBUG = False
            if DEBUG:
                #create a dir and work in this dir
                diffDir = 'frame_mosaic'
                os.makedirs(diffDir, exist_ok=True)
                os.chdir(diffDir)

                #dump phase difference
                diffFilename = 'phase_difference_frame{}-frame{}.int'.format(
                    i, i + 1)
                (upperframe * np.conj(lowerframe)).astype(
                    np.complex64).tofile(diffFilename)
                create_xml(diffFilename, outWidth, ye[i - 1] - ys[i] + 1,
                           'int')

                #plot phase difference vs range
                import matplotlib.pyplot as plt
                x = np.arange(firstSample, lastSample + 1)
                y = np.angle(diff[firstSample:lastSample + 1])
                plt.plot(x, y, label='original phase difference')
                plt.plot(x, np.polyval(p, x), label='fitted phase difference')
                plt.legend()

                plt.minorticks_on()
                plt.tick_params('both', length=10, which='major')
                plt.tick_params('both', length=5, which='minor')

                plt.xlabel('Range Sample Number [Samples]')
                plt.ylabel('Phase Difference [Rad]')
                plt.savefig('phase_difference_frame{}-frame{}.pdf'.format(
                    i, i + 1))

                os.chdir('../')

    #mosaic file
    outFp = open(outputfile, 'wb')
    for i in range(numberOfFrames):
        print('adding frame: {}'.format(i + 1))

        #phase offset in the polynomials
        if phaseCompensation:
            cJ = np.complex64(1j)
            phaseOffset = np.ones(outWidth, dtype=np.complex64)
            for j in range(i + 1):
                phaseOffset *= np.exp(
                    cJ *
                    np.polyval(phaseOffsetPolynomials[j], np.arange(outWidth)))

        #get start line number (starts with zero)
        if i == 0:
            ys1 = 0
        else:
            ys1 = int((ye[i - 1] + ys[i]) / 2.0) + 1 - ys[i]
        #get end line number (start with zero)
        if i == numberOfFrames - 1:
            ye1 = rectLength[i] - 1
        else:
            ye1 = int((ye[i] + ys[i + 1]) / 2.0) - ys[i]

        #get image format
        inputimage = find_vrt_file(rinfs[i] + '.vrt',
                                   'SourceFilename',
                                   relative_path=True)
        byteorder = find_vrt_keyword(rinfs[i] + '.vrt', 'ByteOrder')
        if byteorder == 'LSB':
            swapByte = False
        else:
            swapByte = True
        imageoffset = int(find_vrt_keyword(rinfs[i] + '.vrt', 'ImageOffset'))
        lineoffset = int(find_vrt_keyword(rinfs[i] + '.vrt', 'LineOffset'))

        #read image
        with open(inputimage, 'rb') as fp:
            for j in range(ys1, ye1 + 1):
                fp.seek(imageoffset + j * lineoffset, 0)
                data = np.zeros(outWidth, dtype=np.complex64)
                if swapByte:
                    tmp = np.fromfile(fp, dtype='>f', count=2 * rectWidth[i])
                    cJ = np.complex64(1j)
                    data[xs[i]:xe[i] + 1] = tmp[0::2] + cJ * tmp[1::2]
                else:
                    data[xs[i]:xe[i] + 1] = np.fromfile(fp,
                                                        dtype=np.complex64,
                                                        count=rectWidth[i])
                if phaseCompensation:
                    data *= phaseOffset
                data.astype(np.complex64).tofile(outFp)
    outFp.close()

    #delete files. DO NOT DELETE THE FIRST ONE!!!
    for i in range(numberOfFrames):
        if i == 0:
            continue
        os.remove(rinfs[i])
        os.remove(rinfs[i] + '.vrt')
        os.remove(rinfs[i] + '.xml')

    #update frame parameters
    if updateTrack:
        #mosaic size
        track.numberOfSamples = outWidth
        track.numberOfLines = outLength
        #NOTE THAT WE ARE STILL USING SINGLE LOOK PARAMETERS HERE
        #range parameters
        track.startingRange = frames[0].startingRange + (
            int(rangeOffsets2[0]) - int(rangeOffsets2[xminIndex])
        ) * numberOfRangeLooks * frames[0].rangePixelSize
        track.rangeSamplingRate = frames[0].rangeSamplingRate
        track.rangePixelSize = frames[0].rangePixelSize
        #azimuth parameters
        track.sensingStart = frames[0].sensingStart
        track.prf = frames[0].prf
        track.azimuthPixelSize = frames[0].azimuthPixelSize
        track.azimuthLineInterval = frames[0].azimuthLineInterval
Esempio n. 6
0
    self._insar.numberRangeLooksSim = int(lines[0].split()[0])
    self._insar.numberAzimuthLooksSim = int(lines[0].split()[1])
    self._insar.radarDemAffineTransform = [float(x) for x in lines[1].strip('[').strip(']').split(',')]
    if DEBUG:
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')
        print('{} {}\n{}'.format(self._insar.numberRangeLooksSim, self._insar.numberAzimuthLooksSim, self._insar.radarDemAffineTransform))
        print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')

    #rectify
    rgoff = isceobj.createImage()
    rgoff.load(self._insar.rangeOffset+'.xml')

    if self._insar.radarDemAffineTransform == [1.0, 0.0, 0.0, 1.0, 0.0, 0.0]:
        if not os.path.isfile(self._insar.rectRangeOffset):
            os.symlink(self._insar.rangeOffset, self._insar.rectRangeOffset)
            create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')
    else:
        rect_with_looks(self._insar.rangeOffset,
                        self._insar.rectRangeOffset,
                        rgoff.width, rgoff.length,
                        rgoff.width, rgoff.length,
                        self._insar.radarDemAffineTransform[0], self._insar.radarDemAffineTransform[1],
                        self._insar.radarDemAffineTransform[2], self._insar.radarDemAffineTransform[3],
                        self._insar.radarDemAffineTransform[4], self._insar.radarDemAffineTransform[5],
                        self._insar.numberRangeLooksSim*self._insar.numberRangeLooks1, self._insar.numberAzimuthLooksSim*self._insar.numberAzimuthLooks1,
                        self._insar.numberRangeLooks1, self._insar.numberAzimuthLooks1,
                        'REAL',
                        'Bilinear')
        create_xml(self._insar.rectRangeOffset, rgoff.width, rgoff.length, 'float')