首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用scipy.ndimage.uniform_filter查找星空照片中的恒星,但结果令人困惑

用scipy.ndimage.uniform_filter查找星空照片中的恒星,但结果令人困惑
EN

Stack Overflow用户
提问于 2017-01-05 16:12:41
回答 1查看 794关注 0票数 0

我正在寻找夜空中的星星,在做了一个面具后,我用不同大小的scipy.ndimage.uniform_filter来寻找星星。它看起来运行得相当好,但我预计一旦我使用了一个足够小的尺寸,我就会得到更多的点击,因为我进一步缩小了尺寸,但它没有做到这一点,,我只是有点困惑。

在底部的一个受灾区域附近有一个摘录。

下面的代码告诉我:

代码语言:javascript
运行
复制
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号尺码的点击率为零?我觉得这很奇怪!

代码语言:javascript
运行
复制
 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)))

面具的一部分集中在一颗恒星上:

代码语言:javascript
运行
复制
>>> 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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-01-05 17:40:59

这看起来像一个bug,或者至少是一个令人讨厌的实现细节,它会导致用户代码中的bug。

首先,阅读uniform_filter文档字符串中的注释:

代码语言:javascript
运行
复制
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.

因此,让我们看看uniform_filter1d如何为不同大小的过滤器处理输入数组的一行。

这里有一个小的一维输入:

代码语言:javascript
运行
复制
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])

使用大小越来越大的uniform_filter1d

代码语言:javascript
运行
复制
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时,输出都是零。

我怀疑这是一个浮点精度问题。注意,当我们将输入作为浮点值数组时会发生什么:

代码语言:javascript
运行
复制
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

因此,使用浮点计算的中间值不会给出输出的中间值1的期望值。当此数组被转换回输入数据类型(int)时,结果为所有零:

代码语言:javascript
运行
复制
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之前将输入数组转换为浮点,并添加最后一步,该步骤以您控制的方式将结果转换回整数,并与您想要对“命中”进行分类的方式相匹配。或者甚至使用完全不同的功能。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41489650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档