# # Author: Heresh Fattahi # Copyright 2017 # # Modified by V. Brancato (10.12.2019) # Including offset filtering with no SNR masking # import isce import isceobj from osgeo import gdal from scipy import ndimage from astropy.convolution import convolve import numpy as np import os def mask_filterNoSNR(denseOffsetFile,filterSize,outName): # Masking the offsets with a data-based approach # 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 off_az_copy = np.copy(off_az) off_rg_copy = np.copy(off_rg) # Compute MAD off_azm = ndimage.median_filter(off_az,filterSize) off_rgm = ndimage.median_filter(off_rg,filterSize) metric_rg = np.abs(off_rgm-off_rg) metric_az = np.abs(off_azm-off_az) idx = np.where((metric_rg > 3) | (metric_az > 3)) # Remove missing data in the offset map off_rg_copy[np.where(off_rg_copy<-9999)]=np.nan off_rg_copy[idx]=np.nan # Fill the offsets with smoothed values off_rg_filled = fill_with_smoothed(off_rg_copy,filterSize) # Median filter the offsets off_rg_filled = ndimage.median_filter(off_rg_filled,filterSize) # Save the filtered offsets length, width = off_rg_filled.shape # writing the masked and filtered offsets to a file print ('writing masked and filtered offsets to: ', outName) ##Write array to offsetfile off_rg_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 None 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. """ 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 fill_with_smoothed(off,filterSize): off_2filt=np.copy(off) kernel = np.ones((filterSize,filterSize),np.float32)/(filterSize*filterSize) loop = 0 cnt2=1 while (loop<100): loop += 1 idx2= np.isnan(off_2filt) cnt2 = np.sum(np.count_nonzero(np.isnan(off_2filt))) if cnt2 != 0: off_filt= convolve(off_2filt,kernel,boundary='extend',nan_treatment='interpolate') off_2filt[idx2]=off_filt[idx2] idx3 = np.where(off_filt == 0) off_2filt[idx3]=np.nan off_filt=None return off_2filt def mask_filter(denseOffsetFile, snrFile, band, snrThreshold, filterSize, outName): #masking and Filtering ##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