本文介绍了用Python在Nan中高斯滤波图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从2D坐标列表和第三个变量(力度),我创建了一个覆盖整个采样区域的2D numpy数组。我的目的是创建一个图像,其中每个像素包含其中的点的平均速度。之后使用高斯滤波器过滤该图像。

From a list of 2D coordinates, and a third variable (velocity), I have created a 2D numpy array covering the whole sampled area. My intention is to create an image, in which each pixel contains the mean velocity of the points lying within it. After that filter that image with a gaussian filter.

问题是该区域未被均匀采样。因此,我在图像中间有几个没有信息的像素( Nan )。当我尝试通过高斯滤波器过滤数组时, Nan 传播会破坏整个图像。

The problem is that the area is not uniformly sampled. Therefore I have several pixels without information (Nan) in the middle of the image. When I try to filter the array through a gaussian filter, the Nan propagate ruining the whole image.

我需要过滤此图像,但拒绝所有没有信息的像素。换句话说,如果一个像素不包含信息,那么过滤就不应该考虑它。

I need to filter this image, but rejecting all pixels without information. In other words, If a pixel does not contain information, then it should be not taken into account for the filtering.

这是我的平均代码示例:

Here is an example of my code for averaging:

Mean_V = np.zeros([len(x_bins), len(y_bins)])

for i, x_bin in enumerate(x_bins[:-1]):
    bin_x = (x > x_bins[i]) & (x <= x_bins[i+1])
    for j, y_bin in enumerate(y_bins[:-1]):
        bin_xy = (y[bin_x] > y_bins[j]) & (y[bin_x] <= y_bins[j+1])
        if (sum(x > 0 for x in bin_xy) > 0) :
            Mean_V[i,j]=np.mean(V[bin_x][bin_xy])
        else:
            Mean_V[i,j]=np.nan

编辑:

网上冲浪我已经结束了我在2013年提出的这个问题。这个问题的解决方案可以在astropy library:

Surfing the web I have ended into this question I made in 2013. The solution to this problem can be found in the astropy library:

Astropy的卷积用来自邻居的内核加权插值替换NaN像素。

Astropy's convolution replaces the NaN pixels with a kernel-weighted interpolation from their neighbors.

谢谢大家!!

推荐答案

in words:

通过将标准高斯滤波器应用于两个辅助阵列,可以轻松获得忽略给定阵列 U 中的NaN的高斯滤波器 V W 并取t的比率我得到结果 Z

A Gaussian filter which ignores NaNs in a given array U can be easily obtained by applying a standard Gaussian filter to two auxiliary arrays V and W and by taking the ratio of the two to get the result Z.

这里, V 是原始 U的副本 NaNs被零替换,而 W 是一个零的数组,表示NaN在原始 U 中的位置。

Here, V is copy of the original U with NaNs replaced by zeros and W is an array of ones with zeros indicating the positions of NaNs in the original U.

这个想法是用零替换NaN会在滤波后的数组中引入一个错误,但是可以通过将相同的高斯滤波器应用到另一个辅助数组并将两者合并来补偿。

The idea is that replacing the NaNs by zeros introduces an error in the filtered array which can, however, be compensated by applying the same Gaussian filter to another auxiliary array and combining the two.

在Python中:

import scipy as sp
import scipy.ndimage

U=sp.randn(10,10)          # random array...
U[U<2]=np.nan              # ...with NaNs for testing

V=U.copy()
V[U!=U]=0
VV=sp.ndimage.gaussian_filter(V,sigma=2.0)

W=0*U.copy()+1
W[U!=U]=0
WW=sp.ndimage.gaussian_filter(W,sigma=2.0)

Z=VV/WW

的数字:

为了演示目的,高斯滤波器的系数设置为[0.25,0.50,0.25],它们总和为一个0.25 + 0.50 + 0.25 = 1,不失一般性。

Here coefficients of the Gaussian filter are set to [0.25,0.50,0.25] for demonstration purposes and they sum up to one 0.25+0.50+0.25=1, without loss of generality.

用零替换NaN并应用高斯滤波器(参见下面的VV)后,很明显零引入了错误,即,由于缺失数据,系数0.25 + 0.50 = 0.75不再相加,因此低估了真实值。

After replacing the NaNs by zeros and applying the Gaussian filter (cf. VV below) it is clear that the zeros introduce an error, i.e., due to the "missing" data the coefficients 0.25+0.50=0.75 do not sum up to one anymore and therefore underestimate the "true" value.

然而,这可通过使用第二辅助阵列进行补偿(参见下面的WW),用相同的高斯滤波后,只包含系数之和。

However, this can be compensated by using the second auxiliary array (cf. WW below) which, after filtering with the same Gaussian, just contains the sum of coefficients.

因此,将两个滤波后的辅助阵列分开,重新调整系数,使它们相加NaN位置被忽略一个。

Therefore, dividing the two filtered auxiliary arrays rescales the coefficients such that they sum up to one while the NaN positions are ignored.

array U         1   2   NaN 1   2
auxiliary V     1   2   0   1   2
auxiliary W     1   1   0   1   1
position        a   b   c   d   e

filtered VV_b   = 0.25*V_a  + 0.50*V_b  + 0.25*V_c
                = 0.25*1    + 0.50*2    + 0
                = 1.25

filtered WW_b   = 0.25*W_a  + 0.50*W_b  + 0.25*W_c
                = 0.25*1    + 0.50*1    + 0
                = 0.75

ratio Z         = VV_b / WW_b
                = (0.25*1 + 0.50*2) / (0.25*1    + 0.50*1)
                = 0.333*1 + 0.666*2
                = 1.666

这篇关于用Python在Nan中高斯滤波图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 06:16