# # Author: Heresh Fattahi # Copyright 2017 # # Modified by V. Brancato # Included offset filtering with no SNR # import isce import isceobj from osgeo import gdal import numpy as np import os def mask_filterNoSNR(denseOffsetFile,filterSize,outName): # Masking the offsets with a data-based approach from scipy import ndimage # Open the offsets ds = gdal.Open(denseOffsetFile+'.vrt',gdal.GA_ReadOnly) off_az = ds.GetRasterBand(1).ReadAsArray() off_rg = ds.GetRasterBand(2).ReadAsArray() ds = None # Remove missing values from ampcor off_rg[np.where(off_rg < -9999)]=0 off_az[np.where(off_az < -9999)]=0 # Store the offsets in a complex variable off = off_rg + 1j*off_az # Mask the azimuth offsets based on the MAD mask = off_masking(off,filterSize,thre=3) xoff_masked = np.ma.array(off.real,mask=mask) yoff_masked = np.ma.array(off.imag,mask=mask) # Delete unused variables mask = None off = None # Remove residual noisy spots with a median filter on the azimuth offmap yoff_masked.mask = yoff_masked.mask | \ (ndimage.median_filter(xoff_masked.filled(fill_value=0),3) == 0) | \ (ndimage.median_filter(yoff_masked.filled(fill_value=0),3) == 0) # Fill the data by iteratively using smoothed values data = yoff_masked.data data[yoff_masked.mask]=np.nan off_az_filled = fill_with_smoothed(data,filterSize) # Apply median filter to smooth the azimuth offset map off_az_filled = ndimage.median_filter(off_az_filled,filterSize) # Save the filtered offsets length, width = off_az_filled.shape # writing the masked and filtered offsets to a file print ('writing masked and filtered offsets to: ', outName) ##Write array to offsetfile off_az_filled.tofile(outName) # write the xml file img = isceobj.createImage() img.setFilename(outName) img.setWidth(width) img.setAccessMode('READ') img.bands = 1 img.dataType = 'FLOAT' img.scheme = 'BIP' img.renderHdr() return def off_masking(off,filterSize,thre=2): from scipy import ndimage # Define the mask to fill the offsets vram = ndimage.median_filter(off.real, filterSize) vazm = ndimage.median_filter(off.imag, filterSize) mask = (np.abs(off.real-vram) > thre) | (np.abs(off.imag-vazm) > thre) | (off.imag == 0) | (off.real == 0) return mask def fill(data, invalid=None): """ Replace the value of invalid 'data' cells (indicated by 'invalid') by the value of the nearest valid data cell Input: data: numpy array of any dimension invalid: a binary array of same shape as 'data'. data value are replaced where invalid is True If None (default), use: invalid = np.isnan(data) Output: Return a filled array. """ from scipy import ndimage if invalid is None: invalid = np.isnan(data) ind = ndimage.distance_transform_edt(invalid, return_distances=False, return_indices=True) return data[tuple(ind)] def mask_filter(denseOffsetFile, snrFile, band, snrThreshold, filterSize, outName): #masking and Filtering from scipy import ndimage ##Read in the offset file ds = gdal.Open(denseOffsetFile + '.vrt', gdal.GA_ReadOnly) Offset = ds.GetRasterBand(band).ReadAsArray() ds = None ##Read in the SNR file ds = gdal.Open(snrFile + '.vrt', gdal.GA_ReadOnly) snr = ds.GetRasterBand(1).ReadAsArray() ds = None # Masking the dense offsets based on SNR print ('masking the dense offsets with SNR threshold: ', snrThreshold) Offset[snr