#!/usr/bin/env python3 # author: Minyan Zhong import numpy as np import argparse import os import isce import isceobj import shelve import datetime from isceobj.Location.Offset import OffsetField from iscesys.StdOEL.StdOELPy import create_writer #from mroipac.ampcor.DenseAmpcor import DenseAmpcor from contrib.PyCuAmpcor import PyCuAmpcor from grossOffsets import grossOffsets #from isceobj.Utils.denseoffsets import denseoffsets from isceobj.Util.decorators import use_api from pprint import pprint def createParser(): ''' Command line parser. ''' parser = argparse.ArgumentParser( description='Generate offset field between two Sentinel slc') parser.add_argument('-m','--reference', type=str, dest='reference', required=True, help='Reference image') parser.add_argument('-s', '--secondary',type=str, dest='secondary', required=True, help='Secondary image') parser.add_argument('-l', '--lat',type=str, dest='lat', required=False, help='Latitude') parser.add_argument('-L', '--lon',type=str, dest='lon', required=False, help='Longitude') parser.add_argument('--los',type=str, dest='los', required=False, help='Line of Sight') parser.add_argument('--referencexml',type=str, dest='referencexml', required=False, help='Reference Image Xml File') parser.add_argument('--ww', type=int, dest='winwidth', default=64, help='Window Width') parser.add_argument('--wh', type=int, dest='winhgt', default=64, help='Window height') parser.add_argument('--sw', type=int, dest='srcwidth', default=20, help='Search window width') parser.add_argument('--sh', type=int, dest='srchgt', default=20, help='Search window height') parser.add_argument('--mm', type=int, dest='margin', default=50, help='Margin') parser.add_argument('--kw', type=int, dest='skipwidth', default=64, help='Skip across') parser.add_argument('--kh', type=int, dest='skiphgt', default=64, help='Skip down') parser.add_argument('--nwa', type=int, dest='numWinAcross', default=-1, help='Number of Window Across') parser.add_argument('--nwd', type=int, dest='numWinDown', default=-1, help='Number of Window Down') parser.add_argument('-op','--outprefix', type=str, dest='outprefix', default='dense_ampcor', help='Output prefix') parser.add_argument('-os','--outsuffix', type=str, dest='outsuffix', default='dense_ampcor', help='Output suffix') parser.add_argument('-g','--gross', type=int, dest='gross', default=0, help='Use gross offset or not') parser.add_argument('--aa', type=int, dest='azshift', default=0, help='Gross azimuth offset') parser.add_argument('--rr', type=int, dest='rgshift', default=0, help='Gross range offset') parser.add_argument('--oo', type=int, dest='oversample', default=32, help = 'Oversampling factor') parser.add_argument('-r', '--redo', dest='redo', type=int, default=0 , help='To redo or not') parser.add_argument('-drmp', '--deramp', dest='deramp', type=int, default=0 , help='deramp method (0: mag, 1: complex)') parser.add_argument('-gid', '--gpuid', dest='gpuid', type=int, default=-1 , help='GPU ID') return parser def cmdLineParse(iargs = None): parser = createParser() inps = parser.parse_args(args=iargs) return inps @use_api def estimateOffsetField(reference, secondary, inps=None): ###Loading the secondary image object sim = isceobj.createSlcImage() sim.load(secondary+'.xml') sim.setAccessMode('READ') sim.createImage() ###Loading the reference image object sar = isceobj.createSlcImage() sar.load(reference + '.xml') sar.setAccessMode('READ') sar.createImage() width = sar.getWidth() length = sar.getLength() objOffset = PyCuAmpcor.PyCuAmpcor() objOffset.algorithm = 0 objOffset.deviceID = inps.gpuid # -1:let system find the best GPU objOffset.nStreams = 2 #cudaStreams objOffset.derampMethod = inps.deramp print(objOffset.derampMethod) objOffset.referenceImageName = reference + '.vrt' objOffset.referenceImageHeight = length objOffset.referenceImageWidth = width objOffset.secondaryImageName = secondary + '.vrt' objOffset.secondaryImageHeight = length objOffset.secondaryImageWidth = width print("image length:",length) print("image width:",width) objOffset.numberWindowDown = (length-2*inps.margin-2*inps.srchgt-inps.winhgt)//inps.skiphgt objOffset.numberWindowAcross = (width-2*inps.margin-2*inps.srcwidth-inps.winwidth)//inps.skipwidth if (inps.numWinDown != -1): objOffset.numberWindowDown = inps.numWinDown if (inps.numWinAcross != -1): objOffset.numberWindowAcross = inps.numWinAcross print("nlines: ",objOffset.numberWindowDown) print("ncolumns: ",objOffset.numberWindowAcross) # window size objOffset.windowSizeHeight = inps.winhgt objOffset.windowSizeWidth = inps.winwidth print(objOffset.windowSizeHeight) print(objOffset.windowSizeWidth) # search range objOffset.halfSearchRangeDown = inps.srchgt objOffset.halfSearchRangeAcross = inps.srcwidth print(inps.srchgt,inps.srcwidth) # starting pixel objOffset.referenceStartPixelDownStatic = inps.margin objOffset.referenceStartPixelAcrossStatic = inps.margin # skip size objOffset.skipSampleDown = inps.skiphgt objOffset.skipSampleAcross = inps.skipwidth # oversampling objOffset.corrSufaceOverSamplingMethod = 0 objOffset.corrSurfaceOverSamplingFactor = inps.oversample #objOffset.rawDataOversamplingFactor = 4 # output filenames objOffset.offsetImageName = str(inps.outprefix) + str(inps.outsuffix) + '.bip' objOffset.grossOffsetImageName = str(inps.outprefix) + str(inps.outsuffix) + '_gross.bip' objOffset.snrImageName = str(inps.outprefix) + str(inps.outsuffix) + '_snr.bip' print("offsetfield: ",objOffset.offsetImageName) print("gross offsetfield: ",objOffset.grossOffsetImageName) print("snr: ",objOffset.snrImageName) offsetImageName = objOffset.offsetImageName.decode('utf8') #print(type(offsetImageName)) #print(offsetImageName) #print(type(objOffset.numberWindowAcross)) grossOffsetImageName = objOffset.grossOffsetImageName.decode('utf8') snrImageName = objOffset.snrImageName.decode('utf8') print(offsetImageName) print(inps.redo) if os.path.exists(offsetImageName) and inps.redo==0: print('offsetfield file exists') else: # generic control objOffset.numberWindowDownInChunk = 5 objOffset.numberWindowAcrossInChunk = 5 objOffset.mmapSize = 16 objOffset.setupParams() ## Set Gross Offset ### if inps.gross == 0: objOffset.setConstantGrossOffset(0, 0) else: print("Setting up grossOffset...") objGrossOff = grossOffsets() objGrossOff.setXSize(width) objGrossOff.setYize(length) objGrossOff.setMargin(inps.margin) objGrossOff.setWinSizeHgt(inps.winhgt) objGrossOff.setWinSizeWidth(inps.winwidth) objGrossOff.setSearchSizeHgt(inps.srchgt) objGrossOff.setSearchSizeWidth(inps.srcwidth) objGrossOff.setSkipSizeHgt(inps.skiphgt) objGrossOff.setSkipSizeWidth(inps.skipwidth) objGrossOff.setLatFile(inps.lat) objGrossOff.setLonFile(inps.lon) objGrossOff.setLosFile(inps.los) objGrossOff.setReferenceFile(inps.referencexml) objGrossOff.setbTemp(inps.bTemp) grossDown, grossAcross = objGrossOff.runGrossOffsets() # change nan to 0 grossDown = np.nan_to_num(grossDown) grossAcross = np.nan_to_num(grossAcross) print("Before plotting the gross offsets (min and max): ", np.nanmin(grossDown),np.nanmax(grossDown)) print("Before plotting the gross offsets (min and max): ", np.rint(np.nanmin(grossDown)),np.rint(np.nanmax(grossDown))) grossDown = np.int32(np.rint(grossDown.ravel())) grossAcross = np.int32(np.rint(grossAcross.ravel())) print(np.amin(grossDown), np.amax(grossDown)) print(np.amin(grossAcross), np.amax(grossAcross)) print(grossDown.shape) print(grossDown.shape) objOffset.setVaryingGrossOffset(grossDown, grossAcross) #objOffset.setVaryingGrossOffset(np.zeros(shape=grossDown.shape,dtype=np.int32), np.zeros(shape=grossAcross.shape,dtype=np.int32)) # check objOffset.checkPixelInImageRange() # Run the code print('Running PyCuAmpcor') objOffset.runAmpcor() print('Finished') sar.finalizeImage() sim.finalizeImage() # Finalize the results # offsetfield outImg = isceobj.createImage() outImg.setDataType('FLOAT') outImg.setFilename(offsetImageName) outImg.setBands(2) outImg.scheme = 'BIP' outImg.setWidth(objOffset.numberWindowAcross) outImg.setLength(objOffset.numberWindowDown) outImg.setAccessMode('read') outImg.renderHdr() # gross offsetfield outImg = isceobj.createImage() outImg.setDataType('FLOAT') outImg.setFilename(grossOffsetImageName) outImg.setBands(2) outImg.scheme = 'BIP' outImg.setWidth(objOffset.numberWindowAcross) outImg.setLength(objOffset.numberWindowDown) outImg.setAccessMode('read') outImg.renderHdr() # snr snrImg = isceobj.createImage() snrImg.setFilename(snrImageName) snrImg.setDataType('FLOAT') snrImg.setBands(1) snrImg.setWidth(objOffset.numberWindowAcross) snrImg.setLength(objOffset.numberWindowDown) snrImg.setAccessMode('read') snrImg.renderHdr() return objOffset def main(iargs=None): inps = cmdLineParse(iargs) outDir = os.path.dirname(inps.outprefix) print(inps.outprefix) os.makedirs(outDir, exist_ok=True) objOffset = estimateOffsetField(inps.reference, inps.secondary, inps) if __name__ == '__main__': main()