Merge pull request #399 from yunjunz/ampcor

cuDenseOffsets: bugfix in prepGeometry()
LT1AB
Ryan Burns 2021-12-07 11:34:34 -08:00 committed by GitHub
commit 31803ef7fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 43 additions and 23 deletions

View File

@ -22,6 +22,7 @@ EXAMPLE = '''example
cuDenseOffsets.py -r ./SLC/20151120/20151120.slc.full -s ./SLC/20151214/20151214.slc.full --outprefix ./offsets/20151120_20151214/offset --ww 256 --wh 256 --sw 8 --sh 8 --oo 32 --kw 300 --kh 100 --nwac 100 --nwdc 1 --gpuid 2 cuDenseOffsets.py -r ./SLC/20151120/20151120.slc.full -s ./SLC/20151214/20151214.slc.full --outprefix ./offsets/20151120_20151214/offset --ww 256 --wh 256 --sw 8 --sh 8 --oo 32 --kw 300 --kh 100 --nwac 100 --nwdc 1 --gpuid 2
# offset and its geometry # offset and its geometry
# tip: re-run with --full/out-geom and without --redo to generate geometry only
cuDenseOffsets.py -r ./SLC/20151120/20151120.slc.full -s ./SLC/20151214/20151214.slc.full --outprefix ./offsets/20151120_20151214/offset --ww 256 --wh 256 --sw 8 --sh 8 --oo 32 --kw 300 --kh 100 --nwac 100 --nwdc 1 --gpuid 2 --full-geom ./geom_reference --out-geom ./offset/geom_reference cuDenseOffsets.py -r ./SLC/20151120/20151120.slc.full -s ./SLC/20151214/20151214.slc.full --outprefix ./offsets/20151120_20151214/offset --ww 256 --wh 256 --sw 8 --sh 8 --oo 32 --kw 300 --kh 100 --nwac 100 --nwdc 1 --gpuid 2 --full-geom ./geom_reference --out-geom ./offset/geom_reference
''' '''
@ -148,14 +149,13 @@ def cmdLineParse(iargs = None):
@use_api @use_api
def estimateOffsetField(reference, secondary, inps=None): def estimateOffsetField(reference, secondary, inps=None):
"""Estimte offset field using PyCuAmpcor.
# check redo Parameters: reference - str, path of the reference SLC file
print('redo: ', inps.redo) secondary - str, path of the secondary SLC file
if not inps.redo: inps - Namespace, input configuration
offsetImageName = '{}{}.bip'.format(inps.outprefix, inps.outsuffix) Returns: objOffset - PyCuAmpcor object
if os.path.exists(offsetImageName): geomDict - dict, geometry location info of the offset field
print('offset field file: {} exists and w/o redo, skip re-estimation.'.format(offsetImageName)) """
return 0
# update file path in xml file # update file path in xml file
if inps.fixImageXml: if inps.fixImageXml:
@ -295,8 +295,10 @@ def estimateOffsetField(reference, secondary, inps=None):
numberWindows = objOffset.numberWindowDown*objOffset.numberWindowAcross numberWindows = objOffset.numberWindowDown*objOffset.numberWindowAcross
if grossOffset.size != 2*numberWindows : if grossOffset.size != 2*numberWindows :
print(('WARNING: The input gross offsets do not match the number of windows:' print(('WARNING: The input gross offsets do not match the number of windows:'
' {} by {} in int32 type').format(objOffset.numberWindowDown, objOffset.numberWindowAcross)) ' {} by {} in int32 type').format(objOffset.numberWindowDown,
return 0; objOffset.numberWindowAcross))
return 0
grossOffset = grossOffset.reshape(numberWindows, 2) grossOffset = grossOffset.reshape(numberWindows, 2)
grossAzimuthOffset = grossOffset[:, 0] grossAzimuthOffset = grossOffset[:, 0]
grossRangeOffset = grossOffset[:, 1] grossRangeOffset = grossOffset[:, 1]
@ -309,6 +311,24 @@ def estimateOffsetField(reference, secondary, inps=None):
# check # check
objOffset.checkPixelInImageRange() 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 # Run the code
print('Running PyCuAmpcor') print('Running PyCuAmpcor')
@ -362,10 +382,10 @@ def estimateOffsetField(reference, secondary, inps=None):
covImg.setAccessMode('read') covImg.setAccessMode('read')
covImg.renderHdr() covImg.renderHdr()
return objOffset return objOffset, geomDict
def prepareGeometry(full_dir, out_dir, x_start, y_start, x_step, y_step, num_win_x, num_win_y, def prepareGeometry(full_dir, out_dir, x_start, y_start, x_step, y_step, x_win_num, y_win_num,
fbases=['hgt','lat','lon','los','shadowMask','waterMask']): fbases=['hgt','lat','lon','los','shadowMask','waterMask']):
"""Generate multilooked geometry datasets in the same grid as the estimated offset field """Generate multilooked geometry datasets in the same grid as the estimated offset field
from the full resolution geometry datasets. from the full resolution geometry datasets.
@ -373,7 +393,7 @@ def prepareGeometry(full_dir, out_dir, x_start, y_start, x_step, y_step, num_win
out_dir - str, path of output geometry directory out_dir - str, path of output geometry directory
x/y_start - int, starting column/row number x/y_start - int, starting column/row number
x/y_step - int, output pixel step in column/row direction x/y_step - int, output pixel step in column/row direction
num_win_x/y - int, number of columns/rows x/y_win_num - int, number of columns/rows
""" """
full_dir = os.path.abspath(full_dir) full_dir = os.path.abspath(full_dir)
out_dir = os.path.abspath(out_dir) out_dir = os.path.abspath(out_dir)
@ -406,14 +426,14 @@ def prepareGeometry(full_dir, out_dir, x_start, y_start, x_step, y_step, num_win
in_len = ds.RasterYSize in_len = ds.RasterYSize
# starting column/row and column/row number # starting column/row and column/row number
src_win = [x_start, y_start, num_win_x * x_step, num_win_y * y_step] src_win = [x_start, y_start, x_win_num * x_step, y_win_num * y_step]
print('read {} from file: {}'.format(src_win, in_file)) print('read {} from file: {}'.format(src_win, in_file))
# write binary data file # write binary data file
print('write file: {}'.format(out_file)) print('write file: {}'.format(out_file))
opts = gdal.TranslateOptions(format='ENVI', opts = gdal.TranslateOptions(format='ENVI',
width=num_win_x, width=x_win_num,
height=num_win_y, height=y_win_num,
srcWin=src_win, srcWin=src_win,
noData=0) noData=0)
gdal.Translate(out_file, ds, options=opts) gdal.Translate(out_file, ds, options=opts)
@ -437,17 +457,17 @@ def main(iargs=None):
os.makedirs(outDir, exist_ok=True) os.makedirs(outDir, exist_ok=True)
# estimate offset # estimate offset
objOffset = estimateOffsetField(inps.reference, inps.secondary, inps) geomDict = estimateOffsetField(inps.reference, inps.secondary, inps)[1]
# generate geometry # generate geometry
if inps.full_geometry_dir and inps.out_geometry_dir: if inps.full_geometry_dir and inps.out_geometry_dir:
prepareGeometry(inps.full_geometry_dir, inps.out_geometry_dir, prepareGeometry(inps.full_geometry_dir, inps.out_geometry_dir,
x_start=objOffset.referenceStartPixelAcrossStatic, x_start=geomDict['x_start'],
y_start=objOffset.referenceStartPixelDownStatic, y_start=geomDict['y_start'],
x_step=objOffset.skipSampleAcross, x_step=geomDict['x_step'],
y_step=objOffset.skipSampleDown, y_step=geomDict['y_step'],
num_win_x=objOffset.numberWindowAcross, x_win_num=geomDict['x_win_num'],
num_win_y=objOffset.numberWindowDown) y_win_num=geomDict['y_win_num'])
m, s = divmod(time.time() - start_time, 60) m, s = divmod(time.time() - start_time, 60)
print('time used: {:02.0f} mins {:02.1f} secs.\n'.format(m, s)) print('time used: {:02.0f} mins {:02.1f} secs.\n'.format(m, s))