Hi all,
I am experiencing an issue when preprocessing Sentinel-1 SLC products for interferometric coherence estimation. My current processing workflow is as follows:
- S-1 TOPS Split
- Apply Orbit File
- Calibration to complex numbers
- S-1 Back Geocoding
- S-1 TOPS Deburst
- Multilooking (4:1 ratio)
Before estimating coherence, I intended to apply a Boxcar filter (3x3 window size) for additional smoothing. I tried applying the filter using:
- The Filter Band option (from Raster menu in SNAP)
- A Python script (code attached below)
import os
import sys
import numpy as np
import scipy.ndimage
sys.path.append(r'C:\Users\user\.snap\snap-python\esa_snappy')
from esa_snappy import ProductIO, ProductUtils, ProductData, Product, HashMap, GPF
dirfiles = r'...\SLCimgs'
kernel_size = (3,3)
# Load the Sentinel-1 product
file = 'S1B_IW_SLC__1SDV_20170529_split_Orb_Cal_Stack_Deb_ML.dim'
rimg = os.path.join(dirfiles,file)
product = ProductIO.readProduct(rimg)
# Get image dimensions
width = product.getSceneRasterWidth()
height = product.getSceneRasterHeight()
#Initialize the filtered product
filtered_product = Product('Filtered_Product', 'Filtered_Type', width, height)
# Copy metadata from original product
ProductUtils.copyMetadata(product, filtered_product)
ProductUtils.copyVectorData(product, filtered_product)
ProductUtils.copyTiePointGrids(product, filtered_product)
ProductUtils.copyGeoCoding(product, filtered_product)
# Define a 3x3 Boxcar filter (uniform weights)
boxcar_kernel = np.ones((kernel_size[1], kernel_size[0]), dtype=np.float32) / (kernel_size[0] * kernel_size[1])
# Attach a product writer
output_path = os.path.join(dirfiles,file.replace('.dim',f'_spkl{kernel_size[0]}x{kernel_size[1]}.dim'))
data_format = 'BEAM-DIMAP'
writer = ProductIO.getProductWriter(data_format)
filtered_product.setProductWriter(writer)
# Select the band to filter
for band_name in list(product.getBandNames()):
if 'Intensity' in band_name: continue
print(band_name)
band = product.getBand(band_name)
print('Creating new band...')
# Create a new band
filtered_band = filtered_product.addBand(band_name, band.getDataType()) #Importante mantener el nombre
#copy important data
filtered_band.setNoDataValueUsed(band.isNoDataValueUsed())
filtered_band.setNoDataValue(band.getNoDataValue())
filtered_band.setUnit(band.getUnit())
filtered_band.setDescription(band.getDescription())
# Read band data into a NumPy array
band_data = np.zeros((height, width), dtype=np.float32)
band.readPixels(0, 0, width, height, band_data)
print('Applying filter...')
# Apply the filter using 2D convolution
filtered_data = scipy.ndimage.convolve(band_data, boxcar_kernel, mode='nearest')
# filtered_band.setModified(True)
print('Writing pixels...\n')
# '''
# Convert NumPy array to SNAP-compatible raster data buffer
filtered_band_data = np.ravel(filtered_data) # Flatten array
filtered_band.setRasterData(ProductData.createInstance(filtered_band_data))
# '''
# del filtered_band, filtered_band_data, band_data
# Save the new product
ProductIO.writeProduct(filtered_product, output_path, data_format)
print(f"Filtered product saved at: {output_path}")
The issue arises after applying the filter—I observe horizontal patterns in the output. I checked the original images and noticed a slight horizontal pattern when zooming into specific locations (these horizontal patterns appear in the phase images but not in the amplitude images). However, when I skip the Boxcar filter, no such patterns appear in the final coherence result.
Has anyone encountered a similar issue? Any insights or recommendations would be greatly appreciated!
Thank you!
PS: I have also noticed that these patterns appear even when I do not apply multilooking and when using an irregular window size Boxcar filter.