import numpy as np
import zarr
from matplotlib import pyplot as plt
import colorcet
from moraine.utils_ import is_cuda_available
if is_cuda_available():
import cupy as cp
from cupyx.scipy.ndimage import uniform_filter
import moraine as mr
DS Processing
In this tutorial, we demostrate how to do standard DS processing with the Moraine package.
Load rslc stack
if is_cuda_available():
= cp.asarray(zarr.open('../../data/rslc.zarr','r')[:])
rslc print(rslc.shape)
(2500, 1834, 17)
Apply ks test
if is_cuda_available():
= cp.abs(rslc)**2 rmli
= 5
az_half_win = 5
r_half_win = 2*az_half_win+1
az_win = 2*r_half_win+1 r_win
if is_cuda_available():
= mr.ks_test(rmli,az_half_win=az_half_win,r_half_win=r_half_win) p
Select SHPs
if is_cuda_available():
= (p < 0.05) & (p >= 0.0)
is_shp del p
if is_cuda_available():
= cp.count_nonzero(is_shp,axis=(-2,-1)) shp_num
if is_cuda_available():
= plt.subplots(1,1,figsize=(10,10))
fig, ax = ax.imshow(cp.asnumpy(shp_num),cmap=colorcet.cm.fire)
pcm set(title='Number of SHPs',xlabel='Range Index',ylabel='Azimuth Index')
ax.
fig.colorbar(pcm) fig.show()
Select DSs
Here we select DSs candidate as pixels have more than 50 brothers.
if is_cuda_available():
= shp_num >= 50
is_ds_can del shp_num
The number of DSs:
if is_cuda_available():
cp.count_nonzero(is_ds_can)
The DSs distribution:
if is_cuda_available():
= plt.subplots(1,1,figsize=(10,10))
fig, ax = ax.imshow(cp.asnumpy(is_ds_can),cmap=colorcet.cm.fire)
pcm set(title='DS Candidate distribution',xlabel='Range Index',ylabel='Azimuth Index')
ax.
fig.colorbar(pcm) fig.show()
Estimate coherence matrix
In order to save memory, here we only estimate coherence matrix on selected DSs:
if is_cuda_available():
= is_shp[is_ds_can]
ds_can_is_shp = cp.stack(cp.where(is_ds_can),axis=-1)
ds_can_idx = mr.emperical_co_pc(rslc,ds_can_idx,ds_can_is_shp)
ds_can_coh del is_shp
Plot the average coherence matrix:
if is_cuda_available():
= abs(ds_can_coh).mean(axis=0)
ds_can_ave_coh = mr.uncompress_coh(ds_can_ave_coh)
ds_can_ave_coh_uncompressed print(ds_can_ave_coh.shape,ds_can_ave_coh_uncompressed.shape)
(136,) (17, 17)
= plt.subplots(1,1,figsize=(15,10))
fig, ax = ax.imshow(ds_can_ave_coh_uncompressed.get(),cmap=colorcet.cm.fire)
pcm set(title='Average Coherence Matrix',xlabel='Image Index',ylabel='Image Index')
ax.
fig.colorbar(pcm) fig.show()
The coherence between the 5-th SLC and other SLC are bad. We may consider removing this image.
Phase linking
Here we apply the EMI method:
if is_cuda_available():
= mr.emi(ds_can_coh)
ds_can_ph, ds_can_emi_quality print(ds_can_ph.shape, ds_can_emi_quality.shape)
(740397, 17) (740397,)
if is_cuda_available():
= cp.empty_like(is_ds_can,dtype=ds_can_emi_quality.dtype)
ds_can_emi_quality_2d = cp.nan
ds_can_emi_quality_2d[:] = ds_can_emi_quality ds_can_emi_quality_2d[is_ds_can]
if is_cuda_available():
= plt.subplots(1,1,figsize=(10,10))
fig, ax = ax.imshow(cp.asnumpy(ds_can_emi_quality_2d),interpolation='nearest',vmin=1,vmax=1.3)
pcm set(title='DS EMI quality factor',xlabel='Range Index',ylabel='Azimuth Index')
ax.
fig.colorbar(pcm) fig.show()
if is_cuda_available():
= mr.ds_temp_coh(ds_can_coh,ds_can_ph)
ds_can_temp_coh print(ds_can_temp_coh.shape)
(740397,)
if is_cuda_available():
= cp.empty_like(is_ds_can,dtype=ds_can_temp_coh.dtype)
ds_can_temp_coh_2d = cp.nan
ds_can_temp_coh_2d[:] = ds_can_temp_coh
ds_can_temp_coh_2d[is_ds_can] = plt.subplots(1,1,figsize=(10,10))
fig, ax = ax.imshow(cp.asnumpy(ds_can_temp_coh_2d),interpolation='nearest')
pcm set(title='DS Temporal Coherence',xlabel='Range Index',ylabel='Azimuth Index')
ax.
fig.colorbar(pcm) fig.show()
Refine DS candidate
Here we select DS candidate based on EMI quality factor and temporal coherence:
if is_cuda_available():
= (ds_can_emi_quality>=1.0) & (ds_can_emi_quality <1.2) & (ds_can_temp_coh > 0.7) & (ds_can_temp_coh <= 1.0) _is_ds_can_refined
if is_cuda_available():
= ds_can_idx[_is_ds_can_refined]
ds_can_refined_idx = cp.zeros_like(is_ds_can,dtype=bool)
is_ds_can_refined 0],ds_can_refined_idx[:,1]] = True is_ds_can_refined[ds_can_refined_idx[:,
if is_cuda_available():
= ds_can_coh[_is_ds_can_refined]
ds_can_refined_coh = ds_can_ph[_is_ds_can_refined]
ds_can_refined_ph ds_can_refined_coh.shape
Plot the average coherence matrix and refined DS candiate distribution:
if is_cuda_available():
= abs(ds_can_refined_coh).mean(axis=0)
ds_can_refined_ave_coh = mr.uncompress_coh(ds_can_refined_ave_coh)
ds_can_refined_ave_coh_uncompressed = plt.subplots(1,1,figsize=(15,10))
fig, ax = ax.imshow(cp.asnumpy(ds_can_refined_ave_coh_uncompressed),cmap=colorcet.cm.fire)
pcm set(title='Average Coherence Matrix',xlabel='Image Index',ylabel='Image Index')
ax.
fig.colorbar(pcm) fig.show()
if is_cuda_available():
= plt.subplots(1,1,figsize=(10,10))
fig, ax = ax.imshow(cp.asnumpy(is_ds_can_refined),cmap=colorcet.cm.fire)
pcm set(title='DS Candidate Refined distribution',xlabel='Range Index',ylabel='Azimuth Index')
ax.
fig.colorbar(pcm) fig.show()
We find the coherence matrix gets better and noisy pixels are moved.
Show the interferogram improvement
Here we select one interferogram to show the improvement:
= 1
ref_image = 10 sec_image
1 look interferogram:
if is_cuda_available():
= rslc[:,:,ref_image]*rslc[:,:,sec_image].conj() diff_2d
Multilook interferogram:
if is_cuda_available():
= uniform_filter(diff_2d,size=(az_win,r_win)) ml_diff_2d
Adaptive multilook interferogram on DS candidates:
= mr.TempNet.from_bandwidth(rslc.shape[2])
tnet = tnet.image_pairs_idx(ref=ref_image,sec=sec_image) image_pair_idx
if is_cuda_available():
= cp.empty_like(diff_2d)
ds_can_diff_2d = cp.nan
ds_can_diff_2d[:] = ds_can_coh[:,image_pair_idx]
ds_can_diff = ds_can_diff ds_can_diff_2d[is_ds_can]
Adaptive multilook interferogram after phase linking on DS candidates:
if is_cuda_available():
= cp.empty_like(diff_2d)
ds_can_diff2_2d = cp.nan
ds_can_diff2_2d[:] = ds_can_ph[:,ref_image]*ds_can_ph[:,sec_image].conj()
ds_can_diff2 = ds_can_diff2 ds_can_diff2_2d[is_ds_can]
Adaptive multilook interferogram after phase linking on refined DS candidates:
if is_cuda_available():
= cp.empty_like(diff_2d)
ds_can_refined_diff_2d = cp.nan
ds_can_refined_diff_2d[:] = ds_can_refined_ph[:,ref_image]*ds_can_refined_ph[:,sec_image].conj()
ds_can_refined_diff = ds_can_refined_diff ds_can_refined_diff_2d[is_ds_can_refined]
The plot background:
if is_cuda_available():
= rmli[:,:,0]
plot_bg = cp.asnumpy(plot_bg)
plot_bg = mr.bg_alpha(plot_bg) alpha
Plot:
if is_cuda_available():
= plt.subplots(2,3,figsize=(11,10))
f,axes #axes[-1,-1].remove()
= axes.flatten()
axes = 'Range Index'
xlabel = 'Azimuth Index'
ylabel = axes[0].imshow(cp.asnumpy(cp.angle(diff_2d)),alpha=alpha,interpolation='nearest',cmap='hsv')
pcm 1].imshow(cp.asnumpy(cp.angle(ml_diff_2d)),alpha=alpha,interpolation='nearest',cmap='hsv')
axes[2].imshow(cp.asnumpy(cp.angle(ds_can_diff_2d)),alpha=1,interpolation='nearest',cmap='hsv')
axes[3].imshow(cp.asnumpy(cp.angle(ds_can_diff2_2d)),alpha=1,interpolation='nearest',cmap='hsv')
axes[4].imshow(cp.asnumpy(cp.angle(ds_can_refined_diff_2d)),alpha=1,interpolation='nearest',cmap='hsv')
axes[for ax in axes:
set(facecolor = "black")
ax.0].set(title='Orignal Interferogram')
axes[1].set(title=f'Multilook {az_win} by {r_win}')
axes[2].set(title=f'Adaptively multilook \n Interferogram on DS candidate')
axes[3].set(title=f'Adaptively multilook \n Interferogram after phase \n linking on DS candidate')
axes[4].set(title=f'Adaptively multilook \n Interferogram after phase \n linking on DS candidate refined')
axes[
=axes[5],orientation='horizontal')
f.colorbar(pcm,cax5].set_aspect(2) axes[