Image processing 使用scipy.ndimage.uniform_过滤器在天文照片中查找恒星,但对结果感到困惑
我正在夜空中寻找星星,在制作了一个面具后,我使用不同大小的scipy.ndimage.uniform_过滤器来寻找星星。它看起来工作得相当好,但我预计一旦我使用了足够小的尺寸,我会得到更多的点击,因为我进一步缩小了尺寸,但它并没有一直这样做,我只是对此有点困惑 在底部的一个受灾地区附近有一个摘录 下面的代码告诉我:Image processing 使用scipy.ndimage.uniform_过滤器在天文照片中查找恒星,但对结果感到困惑,image-processing,scipy,Image Processing,Scipy,我正在夜空中寻找星星,在制作了一个面具后,我使用不同大小的scipy.ndimage.uniform_过滤器来寻找星星。它看起来工作得相当好,但我预计一旦我使用了足够小的尺寸,我会得到更多的点击,因为我进一步缩小了尺寸,但它并没有一直这样做,我只是对此有点困惑 在底部的一个受灾地区附近有一个摘录 下面的代码告诉我: size: 3, len: 621 size: 4, len: 340 size: 5, len: 200 size: 6, len: 0 size: 7, len: 0 size:
size: 3, len: 621
size: 4, len: 340
size: 5, len: 200
size: 6, len: 0
size: 7, len: 0
size: 8, len: 24
size: 9, len: 8
size: 10, len: 0
size: 11, len: 0
size: 12, len: 0
为什么6号和7号的点击率为零?这对我来说似乎完全奇怪
def __init__(self, filename):
self.good=False
self.img = scipy.ndimage.imread(filename, flatten=True)
def checkcandidates(self, meanfact=3.0, maxwindow=25):
mask = self.img > self.img.mean()*meanfact
for wsize in range(3,maxwindow):
m2 = scipy.ndimage.uniform_filter(mask, size=wsize)
xc,yc = m2.nonzero()
print("size: %d, len: %d" %(wsize, len(xc)))
这是面具的一部分,以其中一颗星星为中心:
>>> sc1.showCoords(1360,493,10,usemask=True)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
这看起来像一个bug,或者至少是一个令人讨厌的实现细节,会导致用户代码中出现bug 首先,阅读docstring中的注释:
The multi-dimensional filter is implemented as a sequence of
one-dimensional uniform filters. The intermediate arrays are stored
in the same data type as the output. Therefore, for output types
with a limited precision, the results may be imprecise because
intermediate results may be stored with insufficient precision.
让我们看看输入数组的一行是如何被不同大小的过滤器处理的
下面是一个小的一维输入:
In [416]: x
Out[416]: array([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0])
随着尺寸的增加,使用均匀的过滤器1d:
In [417]: from scipy.ndimage.filters import uniform_filter1d
In [418]: uniform_filter1d(x, 3)
Out[418]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
In [419]: uniform_filter1d(x, 4)
Out[419]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
In [420]: uniform_filter1d(x, 5)
Out[420]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0])
In [421]: uniform_filter1d(x, 6)
Out[421]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [422]: uniform_filter1d(x, 7)
Out[422]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [423]: uniform_filter1d(x, 8)
Out[423]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0])
In [424]: uniform_filter1d(x, 9)
Out[424]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
与您的示例一样,当大小为6或7时,输出为全零
我怀疑这是一个浮点精度问题。请注意,将输入设为浮点值数组时会发生什么情况:
In [439]: f = uniform_filter1d(x.astype(float), 6)
In [440]: f
Out[440]:
array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
1.66666667e-01, 3.33333333e-01, 5.00000000e-01,
6.66666667e-01, 8.33333333e-01, 1.00000000e+00,
1.00000000e+00, 1.00000000e+00, 1.00000000e+00,
8.33333333e-01, 6.66666667e-01, 5.00000000e-01,
3.33333333e-01, 1.66666667e-01, 5.55111512e-17,
5.55111512e-17, 5.55111512e-17])
In [441]: f.max()
Out[441]: 0.99999999999999989
<> P>因此,使用浮点计算的中间值在输出的中间不给出1的期望值。将此数组转换回输入数据类型int时,结果为全零:
In [442]: f.astype(int)
Out[442]: array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
考虑到这种行为,我建议在调用uniform_filter之前将输入数组转换为浮点,并添加最后一个步骤,以您控制的方式将结果转换回整数,并匹配您希望对命中进行分类的方式。甚至可以完全使用不同的函数。Aha,我刚刚用1D数组进行了实验,发现了这个,我回来是想添加一条注释的!。奇怪的是,到目前为止,这只发生在6点和7点,8点又恢复了。虽然我相信代码应该是圆的,但创建一个浮点数组并使用输出参数并不是转换输入数组