在海洋数据处理中,不可避免地会遇到NAN值的处理,当全部将NAN替换成“0”进行处理,有时候的结果可能不准确。这里以Matlab为例,对流场数据进行滤波,这里采用smooth2a、中值滤波两种方法进行对比:
中值滤波的结果,窗口7x7
smooth2a的结果,窗口7x7
可以看到smooth2a的效果很不理想,而中值滤波在边界处呈现白边。
为了解决这个问题,我们自己定义一个针对包含nan数组(矩阵)的滤波函数slidingWindowFilter。
function filteredMatrix = slidingWindowFilter(matrix, windowSize, filterType)
[rows, cols] = size(matrix);
filteredMatrix = NaN(rows, cols);
halfWindowSize = floor(windowSize / 2);
for i = 1:rows
for j = 1:cols
r1 = max(1, i - halfWindowSize);
r2 = min(rows, i + halfWindowSize);
c1 = max(1, j - halfWindowSize);
c2 = min(cols, j + halfWindowSize);
window = matrix(r1:r2, c1:c2);
if all(~isnan(window(:)))
switch filterType
case 'mean'
filteredMatrix(i, j) = mean(window(:));
case 'median'
filteredMatrix(i, j) = median(window(:));
case 'gaussian'
sigma = 1;
[X, Y] = meshgrid(-halfWindowSize:halfWindowSize, -halfWindowSize:halfWindowSize);
G = exp(-(X.^2 + Y.^2) / (2*sigma^2));
G = G / sum(G(:));
filteredMatrix(i, j) = sum(sum(window .* G));
case 'max'
filteredMatrix(i, j) = max(window(:));
case 'min'
filteredMatrix(i, j) = min(window(:));
case 'laplacian'
LaplacianKernel = [1 -2 1; -2 4 -2; 1 -2 1];
filteredMatrix(i, j) = sum(sum(window .* LaplacianKernel));
case 'rms'
filteredMatrix(i, j) = sqrt(mean(window(:).^2));
case 'bilateral'
sigma_spatial = 1;
sigma_intensity = 1;
[X, Y] = meshgrid(-halfWindowSize:halfWindowSize, -halfWindowSize:halfWindowSize);
spatialWeights = exp(-(X.^2 + Y.^2) / (2*sigma_spatial^2));
intensityWeights = exp(-(window - matrix(i, j)).^2 / (2*sigma_intensity^2));
bilateralWeights = spatialWeights .* intensityWeights;
bilateralWeights = bilateralWeights / sum(bilateralWeights(:));
filteredMatrix(i, j) = sum(sum(window .* bilateralWeights));
case 'adaptive'
localVariance = var(window(:));
globalVariance = var(matrix(:));
adaptiveFactor = globalVariance / (globalVariance + localVariance);
filteredMatrix(i, j) = adaptiveFactor * mean(window(:)) + ...
(1 - adaptiveFactor) * matrix(i, j);
otherwise
error('Unknown filter type.');
end
end
end
end
end
调用示例:
% 使用拉普拉斯滤波
filteredMatrix = slidingWindowFilter(matrix, windowSize, 'laplacian');
结果:
想要效果更好,可以再加入其他滤波进行处理。