Esta división fue probado por expertos para que tengas la garantía de la veracidad de este ensayo.
Solución:
Este es un pequeño problema divertido. En lugar de intentar encontrar una biblioteca para él, ¿por qué no escribirlo a partir de la definición?
from scipy.ndimage.filters import uniform_filter
from scipy.ndimage.measurements import variance
def lee_filter(img, size):
img_mean = uniform_filter(img, (size, size))
img_sqr_mean = uniform_filter(img**2, (size, size))
img_variance = img_sqr_mean - img_mean**2
overall_variance = variance(img)
img_weights = img_variance / (img_variance + overall_variance)
img_output = img_mean + img_weights * (img - img_mean)
return img_output
Si no desea que la ventana sea un cuadrado de tamaño x tamaño, simplemente reemplace uniform_filter
con otra cosa (convolución con un disco, filtro gaussiano, etc.). Cualquier tipo de filtro de promedio (ponderado) servirá, siempre que sea el mismo para calcular ambos img_mean
y img_square_mean
.
El filtro Lee parece bastante anticuado como filtro. No se comportará bien en los bordes porque para cualquier ventana que tenga un borde, la variación será mucho mayor que la variación general de la imagen y, por lo tanto, los pesos (de la imagen sin filtrar en relación con la imagen filtrada) van estar cerca de 1.
Un ejemplo:
from pylab import *
import numpy as np
img = np.random.normal(0.5, 0.1, (100,100))
img[:,:50] += 0.25
imshow(img, vmin=0, vmax=1, cmap='gray')
imshow(lee_filter(img, 20), vmin=0, vmax=1, cmap='gray')
Como puede ver, la reducción de ruido es muy buena en general, pero mucho más débil en el borde.
No estoy familiarizado con el SAR, por lo que no sé si el filtro Lee tiene algunas características que lo hacen particularmente bueno para el moteado en el SAR, pero es posible que desee buscar en los eliminadores de ruido modernos con reconocimiento de bordes, como el filtro guiado o el filtro bilateral.
En general, es muy difícil ver el efecto de un filtro de ruido a simple vista en un gráfico 2D. Déjame demostrarte esto con un ejemplo. Supongamos que tenemos esta imagen ruidosa:
Permítanme convertir esta imagen en un diagrama de malla 3D. Entonces se verá así. El ruido se vuelve muy claro pero también las diferencias de profundidad entre el lado izquierdo y derecho de la imagen.
La biblioteca findpeaks
contiene muchos filtros que se utilizan de varias bibliotecas (antiguas de python 2) y se reescriben y se convierten a python 3. La aplicación de los filtros es muy fácil, como se muestra a continuación. Este ejemplo no parece muy representativo para una imagen de SAR. Un filtro de media o mediana parece funcionar muy bien en este ejemplo. En imágenes de ruido de moteado donde las alturas locales son importantes, dichos filtros de media / mediana pueden eliminar fácilmente los picos.
Instalar por:
pip install findpeaks
Contener:
from findpeaks import findpeaks
# Read image
img = cv2.imread('noise.png')
filters = [None, 'lee','lee_enhanced','kuan', 'fastnl','bilateral','frost','median','mean']
for getfilter in filters:
fp = findpeaks(method='topology', scale=False, denoise=getfilter, togray=True, imsize=False, window=15)
fp.fit(img)
fp.plot_mesh(wireframe=False, title=str(getfilter), view=(30,30))
Si desea utilizar directamente los filtros de eliminación de ruido, puede hacerlo de la siguiente manera:
import findpeaks
import matplotlib.pyplot as plt
# Read image
img = cv2.imread('noise.png')
# filters parameters
# window size
winsize = 15
# damping factor for frost
k_value1 = 2.0
# damping factor for lee enhanced
k_value2 = 1.0
# coefficient of variation of noise
cu_value = 0.25
# coefficient of variation for lee enhanced of noise
cu_lee_enhanced = 0.523
# max coefficient of variation for lee enhanced
cmax_value = 1.73
# Some pre-processing
# Make grey image
img = findpeaks.stats.togray(img)
# Scale between [0-255]
img = findpeaks.stats.scale(img)
# Denoising
# fastnl
img_fastnl = findpeaks.stats.denoise(img, method='fastnl', window=winsize)
# bilateral
img_bilateral = findpeaks.stats.denoise(img, method='bilateral', window=winsize)
# frost filter
image_frost = findpeaks.frost_filter(img, damping_factor=k_value1, win_size=winsize)
# kuan filter
image_kuan = findpeaks.kuan_filter(img, win_size=winsize, cu=cu_value)
# lee filter
image_lee = findpeaks.lee_filter(img, win_size=winsize, cu=cu_value)
# lee enhanced filter
image_lee_enhanced = findpeaks.lee_enhanced_filter(img, win_size=winsize, k=k_value2, cu=cu_lee_enhanced, cmax=cmax_value)
# mean filter
image_mean = findpeaks.mean_filter(img, win_size=winsize)
# median filter
image_median = findpeaks.median_filter(img, win_size=winsize)
plt.figure(); plt.imshow(img_fastnl, cmap='gray'); plt.title('Fastnl')
plt.figure(); plt.imshow(img_bilateral, cmap='gray'); plt.title('Bilateral')
plt.figure(); plt.imshow(image_frost, cmap='gray'); plt.title('Frost')
plt.figure(); plt.imshow(image_kuan, cmap='gray'); plt.title('Kuan')
plt.figure(); plt.imshow(image_lee, cmap='gray'); plt.title('Lee')
plt.figure(); plt.imshow(image_lee_enhanced, cmap='gray'); plt.title('Lee Enhanced')
plt.figure(); plt.imshow(image_mean, cmap='gray'); plt.title('Mean')
plt.figure(); plt.imshow(image_median, cmap='gray'); plt.title('Median')
Si quieres jugar con la biblioteca, puedes encontrar más ejemplos aquí.