这是基于其他几个尚未得到解答的问题,所以我开了一个新帖子。我正在寻找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补丁在输出图像上。我无法弄清楚这是怎么回事。
答案 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
。屏蔽像素可能包含许多值,包括nan
,0
,inf
,...因此,如果将这些值考虑在内(当它们应被忽略时)可以产生任何类型问题,特别是median
开始返回nan
或类似情况。
更一般地说,如果你真的想要一个中值滤波器,你不能只计算一个补丁的中位数,并用该中位数替换补丁中的所有值。您应该使用中值过滤器来考虑掩码。不幸的是,我从来没有在任何广泛的Python包中实现过这样的过滤器。但是,如果你有numba,你可以查看我的numbamisc
的一个(非常实验!)包,其中包含考虑了掩码的median_filter
。