中值筛选器在 FITS 文件上产生意外结果



这是基于其他几个尚未完全回答的问题,所以我开始了一篇新文章。我正在努力在 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 文件时,它会在输出图像上生成"侧面"大小的补丁。我不知道这是怎么回事。

我不知道你的 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开始返回nanS 或类似内容。


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

最新更新