def estimateOffsetField(reference, secondary, inps=None): """Estimte offset field using PyCuAmpcor. Parameters: reference - str, path of the reference SLC file secondary - str, path of the secondary SLC file inps - Namespace, input configuration Returns: objOffset - PyCuAmpcor object geomDict - dict, geometry location info of the offset field """ # update file path in xml file if inps.fixImageXml: for fname in [reference, secondary]: fname = os.path.abspath(fname) img = IML.loadImage(fname)[0] img.filename = fname img.setAccessMode('READ') img.renderHdr() ###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() # create a PyCuAmpcor instance objOffset = PyCuAmpcor() objOffset.algorithm = inps.algorithm objOffset.deviceID = inps.gpuid objOffset.nStreams = inps.nstreams #cudaStreams objOffset.derampMethod = inps.deramp print('deramp method (0 for magnitude, 1 for complex): ', 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) # if using gross offset, adjust the margin margin = max(inps.margin, abs(inps.azshift), abs(inps.rgshift)) # determine the number of windows down and across # that's also the size of the output offset field objOffset.numberWindowDown = inps.numWinDown if inps.numWinDown > 0 \ else (length-2*margin-2*inps.srchgt-inps.winhgt)//inps.skiphgt objOffset.numberWindowAcross = inps.numWinAcross if inps.numWinAcross > 0 \ else (width-2*margin-2*inps.srcwidth-inps.winwidth)//inps.skipwidth print('the number of windows: {} by {}'.format( objOffset.numberWindowDown, objOffset.numberWindowAcross)) # window size objOffset.windowSizeHeight = inps.winhgt objOffset.windowSizeWidth = inps.winwidth print('window size for cross-correlation: {} by {}'.format( objOffset.windowSizeHeight, objOffset.windowSizeWidth)) # search range objOffset.halfSearchRangeDown = inps.srchgt objOffset.halfSearchRangeAcross = inps.srcwidth print('initial search range: {} by {}'.format(inps.srchgt, inps.srcwidth)) # starting pixel objOffset.referenceStartPixelDownStatic = inps.startpixeldw if inps.startpixeldw != -1 \ else margin + objOffset.halfSearchRangeDown # use margin + halfSearchRange instead objOffset.referenceStartPixelAcrossStatic = inps.startpixelac if inps.startpixelac != -1 \ else margin + objOffset.halfSearchRangeAcross print('the first pixel in reference image is: ({}, {})'.format( objOffset.referenceStartPixelDownStatic, objOffset.referenceStartPixelAcrossStatic)) # skip size objOffset.skipSampleDown = inps.skiphgt objOffset.skipSampleAcross = inps.skipwidth print('search step: {} by {}'.format(inps.skiphgt, inps.skipwidth)) # oversample raw data (SLC) objOffset.rawDataOversamplingFactor = inps.raw_oversample # correlation surface objOffset.corrStatWindowSize = inps.corr_stat_win_size corr_win_size = 2 * inps.corr_srch_size * inps.raw_oversample objOffset.corrSurfaceZoomInWindow = corr_win_size print('correlation surface zoom-in window size:', corr_win_size) objOffset.corrSurfaceOverSamplingMethod = inps.corr_oversamplemethod objOffset.corrSurfaceOverSamplingFactor = inps.corr_oversample print('correlation surface oversampling factor:', inps.corr_oversample) # output filenames fbase = '{}{}'.format(inps.outprefix, inps.outsuffix) objOffset.offsetImageName = fbase + '.bip' objOffset.grossOffsetImageName = fbase + '_gross.bip' objOffset.snrImageName = fbase + '_snr.bip' objOffset.covImageName = fbase + '_cov.bip' print("offsetfield: ", objOffset.offsetImageName) print("gross offsetfield: ", objOffset.grossOffsetImageName) print("snr: ", objOffset.snrImageName) print("cov: ", objOffset.covImageName) # whether to include the gross offset in offsetImage objOffset.mergeGrossOffset = inps.merge_gross_offset try: offsetImageName = objOffset.offsetImageName.decode('utf8') grossOffsetImageName = objOffset.grossOffsetImageName.decode('utf8') snrImageName = objOffset.snrImageName.decode('utf8') covImageName = objOffset.covImageName.decode('utf8') except: offsetImageName = objOffset.offsetImageName grossOffsetImageName = objOffset.grossOffsetImageName snrImageName = objOffset.snrImageName covImageName = objOffset.covImageName # generic control objOffset.numberWindowDownInChunk = inps.numWinDownInChunk objOffset.numberWindowAcrossInChunk = inps.numWinAcrossInChunk objOffset.useMmap = inps.usemmap objOffset.mmapSize = inps.mmapsize # setup and check parameters objOffset.setupParams() ## Set Gross Offset ### if inps.gross == 0: # use static grossOffset print('Set constant grossOffset ({}, {})'.format( inps.azshift, inps.rgshift)) objOffset.setConstantGrossOffset(inps.azshift, inps.rgshift) else: # use varying offset print("Set varying grossOffset from file {}".format( inps.gross_offset_file)) grossOffset = np.fromfile(inps.gross_offset_file, dtype=np.int32) numberWindows = objOffset.numberWindowDown * objOffset.numberWindowAcross if grossOffset.size != 2 * numberWindows: print(( 'WARNING: The input gross offsets do not match the number of windows:' ' {} by {} in int32 type').format( objOffset.numberWindowDown, objOffset.numberWindowAcross)) return 0 grossOffset = grossOffset.reshape(numberWindows, 2) grossAzimuthOffset = grossOffset[:, 0] grossRangeOffset = grossOffset[:, 1] # enforce C-contiguous flag grossAzimuthOffset = grossAzimuthOffset.copy(order='C') grossRangeOffset = grossRangeOffset.copy(order='C') # set varying gross offset objOffset.setVaryingGrossOffset(grossAzimuthOffset, grossRangeOffset) # check objOffset.checkPixelInImageRange() # save output geometry location info geomDict = { 'x_start': objOffset.referenceStartPixelAcrossStatic + int(objOffset.windowSizeWidth / 2.), 'y_start': objOffset.referenceStartPixelDownStatic + int(objOffset.windowSizeHeight / 2.), 'x_step': objOffset.skipSampleAcross, 'y_step': objOffset.skipSampleDown, 'x_win_num': objOffset.numberWindowAcross, 'y_win_num': objOffset.numberWindowDown, } # check redo print('redo: ', inps.redo) if not inps.redo: offsetImageName = '{}{}.bip'.format(inps.outprefix, inps.outsuffix) if os.path.exists(offsetImageName): print( 'offset field file: {} exists and w/o redo, skip re-estimation.' .format(offsetImageName)) return objOffset, geomDict # 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() # cov covImg = isceobj.createImage() covImg.setFilename(covImageName) covImg.setDataType('FLOAT') covImg.setBands(3) covImg.scheme = 'BIP' covImg.setWidth(objOffset.numberWindowAcross) covImg.setLength(objOffset.numberWindowDown) covImg.setAccessMode('read') covImg.renderHdr() return objOffset, geomDict
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() objOffset.algorithm = 0 objOffset.deviceID = inps.gpuid # -1:let system find the best GPU objOffset.nStreams = 2 #cudaStreams objOffset.derampMethod = inps.deramp print('deramp method (0 for magnitude, 1 for complex): ', 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("offset field length: ", objOffset.numberWindowDown) print("offset field width: ", objOffset.numberWindowAcross) # window size objOffset.windowSizeHeight = inps.winhgt objOffset.windowSizeWidth = inps.winwidth print('cross correlation window size: {} by {}'.format( objOffset.windowSizeHeight, objOffset.windowSizeWidth)) # search range objOffset.halfSearchRangeDown = inps.srchgt objOffset.halfSearchRangeAcross = inps.srcwidth print('half search range: {} by {}'.format(inps.srchgt, inps.srcwidth)) # starting pixel objOffset.referenceStartPixelDownStatic = inps.margin objOffset.referenceStartPixelAcrossStatic = inps.margin # skip size objOffset.skipSampleDown = inps.skiphgt objOffset.skipSampleAcross = inps.skipwidth print('search step: {} by {}'.format(inps.skiphgt, inps.skipwidth)) # oversample raw data (SLC) objOffset.rawDataOversamplingFactor = inps.raw_oversample print('raw data oversampling factor:', inps.raw_oversample) # correlation surface if inps.corr_win_size == -1: corr_win_size_orig = min(inps.srchgt, inps.srcwidth) * inps.raw_oversample + 1 inps.corr_win_size = np.power(2, int(np.log2(corr_win_size_orig))) objOffset.corrSurfaceZoomInWindow = inps.corr_win_size print('correlation surface zoom-in window size:', inps.corr_win_size) objOffset.corrSufaceOverSamplingMethod = 0 objOffset.corrSurfaceOverSamplingFactor = inps.corr_oversample print('correlation surface oversampling factor:', inps.corr_oversample) # 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' objOffset.covImageName = str(inps.outprefix) + str( inps.outsuffix) + '_cov.bip' print("offsetfield: ", objOffset.offsetImageName) print("gross offsetfield: ", objOffset.grossOffsetImageName) print("snr: ", objOffset.snrImageName) print("cov: ", objOffset.covImageName) offsetImageName = objOffset.offsetImageName.decode('utf8') grossOffsetImageName = objOffset.grossOffsetImageName.decode('utf8') snrImageName = objOffset.snrImageName.decode('utf8') covImageName = objOffset.covImageName.decode('utf8') print(offsetImageName) print(inps.redo) if os.path.exists(offsetImageName) and not inps.redo: print('offsetfield file exists') return 0 # generic control objOffset.numberWindowDownInChunk = inps.numWinDownInChunk objOffset.numberWindowAcrossInChunk = inps.numWinAcrossInChunk objOffset.useMmap = 0 objOffset.mmapSize = 8 objOffset.setupParams() ## Set Gross Offset ### if inps.gross == 0: print("Set constant grossOffset") print("By default, the gross offsets are zero") print("You can override the default values here") objOffset.setConstantGrossOffset(0, 0) else: print("Set varying grossOffset") print("By default, the gross offsets are zero") print( "You can override the default grossDown and grossAcross arrays here" ) 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() # cov covImg = isceobj.createImage() covImg.setFilename(covImageName) covImg.setDataType('FLOAT') covImg.setBands(3) covImg.scheme = 'BIP' covImg.setWidth(objOffset.numberWindowAcross) covImg.setLength(objOffset.numberWindowDown) covImg.setAccessMode('read') covImg.renderHdr() return