中值过滤器在FITS文件上产生意外结果

时间:2017-08-20 21:00:51

标签: python arrays numpy filter mask

这是基于其他几个尚未得到解答的问题,所以我开了一个新帖子。我正在寻找50像素补丁中掩码阵列的中位数。图像和掩模都是901x877望远镜图像。

import numpy as np
import matplotlib.pyplot as plt
from astropy.io import fits

#   Use the fits files as input image and mask
hdulist = fits.open('xbulge-w1.fits')
w1data = hdulist[0].data
hdulist3 = fits.open('xbulge-mask.fits')
mask = 1 - hdulist3[0].data
w1masked = np.ma.array(w1data, mask = mask)

#   Use general arrays as input image and mask
#w1data = np.arange(790177).reshape(901,877)
#w1masked = np.ma.masked_inside(w1data, 30000, 60000)


side = 50                                                                                                                                                                                
w, h = w1data.shape                                                                                                                                                                                            
width_index   = np.array(range(w//side)) * side                                                                                                                                                             
height_index  = np.array(range(h//side)) * side                                                                                                                                                             

def assign_patch(patch, median, side):                                                                                                                                                                     
    """Break this loop out to prevent 4 nested 'for' loops"""                                                                                                                                              
    for j in range(side):                                                                                                                                                                                  
        for i in range(side):                                                                                                                                                                              
            patch[i,j] = median                                                                                                                                                                            
    return patch                                                                                                                                                                                           

for width in width_index:                                                                                                                                                                                  
    for height in height_index:                                                                                                                                                                            
        patch  = w1masked[width:width+side, height:height+side]                                                                                                                                                  
        median = np.median(patch)                                                                                                                                                                          
        assign_patch(patch, median, side)                                                                           

plt.imshow(w1masked)
plt.show()

问题是,当我使用通用数组作为输入图像和掩码(注释掉的部分)时,它工作正常,但是当我使用FITS文件时,它会生成' side-the-size补丁在输出图像上。我无法弄清楚这是怎么回事。

1 个答案:

答案 0 :(得分:0)

我不知道你的FITS文件是怎样的,但有几件事情突出:

  • np.median未考虑mask。事实上,在最近的NumPy版本中,如果尝试,这(正确)会打印一个警告。您应该使用np.ma.median代替。如果您要更新NumPy,您可能会看到:
  

用户警告:警告:'分区'将忽略'掩码' MaskedArray。

  • 当您知道可以使用切片分配时,assign_patch函数是不必要的:

    w1masked[width:width+side, height:height+side] = median
    # instead of "assign_patch(patch, median, side)"
    

这比使用双循环替换每个值要快得多。

我认为问题实际上是因为您使用的是np.median而不是np.ma.median。屏蔽像素可能包含许多值,包括nan0inf,...因此,如果将这些值考虑在内(当它们应被忽略时)可以产生任何类型问题,特别是median开始返回nan或类似情况。

更一般地说,如果你真的想要一个中值滤波器,你不能只计算一个补丁的中位数,并用该中位数替换补丁中的所有值。您应该使用中值过滤器来考虑掩码。不幸的是,我从来没有在任何广泛的Python包中实现过这样的过滤器。但是,如果你有numba,你可以查看我的numbamisc的一个(非常实验!)包,其中包含考虑了掩码的median_filter