将 Boxcar 平均值应用于地理空间图像
Apply Boxcar average to geospatial image
假设以下数组 A
是读取 GeoTIFF 图像的结果,例如使用 rasterio,其中 nodata 值为 masked,即数组 B
.
我想对方形邻域应用 boxcar 平均平滑。第一个问题是我不确定哪个 scipy 函数代表 boxcar 平均值?
我认为可能是 ndimage.uniform_filter。但是,与 scipy.signal 相比,ndimage 不适用于掩码数组。
from scipy.signal import medfilt
from scipy.ndimage import uniform_filter
import numpy as np
A = np.array([[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, 0, 300, 400, 200, -9999],
[-9999, -9999, -9999, -9999, 200, 0, 400, -9999],
[-9999, -9999, -9999, 300, 0, 0, -9999, -9999],
[-9999, -9999, -9999, 300, 0, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999]])
B = np.ma.masked_array(A, mask=(A == -9999))
print(B)
filtered = medfilt(B, 3).astype('int')
result = np.ma.masked_array(filtered, mask=(filtered == -9999))
print(result)
boxcar = ndimage.uniform_filter(B)
print(boxcar)
那么,我如何应用考虑无数据值的 boxcar 平均值,例如 scipy.signal.medfilt?
这似乎是一个很好的解决方案:
import numpy as np
from scipy.signal import fftconvolve
def boxcar(A, nodata, window_size=3):
mask = (A==nodata)
K = np.ones((window_size, window_size),dtype=int)
out = np.round(fftconvolve(np.where(mask,0,A), K, mode="same")/fftconvolve(~mask,K, mode="same"), 2)
out[mask] = nodata
return np.ma.masked_array(out, mask=(out == nodata))
A = np.array([[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 1 , 0 , 1 , 100],
[100, 100, 100, 1 , 0 , 1 , 0 , 100],
[100, 100, 100, 0 , 1 , 0 , 1 , 100],
[100, 100, 100, 100, 100, 100, 100, 100]])
print(boxcar(A, 100))
希望能得到一些反馈,尤其是关于改进方面的反馈!
假设以下数组 A
是读取 GeoTIFF 图像的结果,例如使用 rasterio,其中 nodata 值为 masked,即数组 B
.
我想对方形邻域应用 boxcar 平均平滑。第一个问题是我不确定哪个 scipy 函数代表 boxcar 平均值?
我认为可能是 ndimage.uniform_filter。但是,与 scipy.signal 相比,ndimage 不适用于掩码数组。
from scipy.signal import medfilt
from scipy.ndimage import uniform_filter
import numpy as np
A = np.array([[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999],
[-9999, -9999, -9999, 0, 300, 400, 200, -9999],
[-9999, -9999, -9999, -9999, 200, 0, 400, -9999],
[-9999, -9999, -9999, 300, 0, 0, -9999, -9999],
[-9999, -9999, -9999, 300, 0, -9999, -9999, -9999],
[-9999, -9999, -9999, -9999, -9999, -9999, -9999, -9999]])
B = np.ma.masked_array(A, mask=(A == -9999))
print(B)
filtered = medfilt(B, 3).astype('int')
result = np.ma.masked_array(filtered, mask=(filtered == -9999))
print(result)
boxcar = ndimage.uniform_filter(B)
print(boxcar)
那么,我如何应用考虑无数据值的 boxcar 平均值,例如 scipy.signal.medfilt?
这似乎是一个很好的解决方案:
import numpy as np
from scipy.signal import fftconvolve
def boxcar(A, nodata, window_size=3):
mask = (A==nodata)
K = np.ones((window_size, window_size),dtype=int)
out = np.round(fftconvolve(np.where(mask,0,A), K, mode="same")/fftconvolve(~mask,K, mode="same"), 2)
out[mask] = nodata
return np.ma.masked_array(out, mask=(out == nodata))
A = np.array([[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 100, 100, 100, 100],
[100, 100, 100, 100, 1 , 0 , 1 , 100],
[100, 100, 100, 1 , 0 , 1 , 0 , 100],
[100, 100, 100, 0 , 1 , 0 , 1 , 100],
[100, 100, 100, 100, 100, 100, 100, 100]])
print(boxcar(A, 100))
希望能得到一些反馈,尤其是关于改进方面的反馈!