使用scipy.ndimage.uniform_filter在天文照片中查找星星,但结果感到困惑 [英] Using scipy.ndimage.uniform_filter to find stars in astro photo, but puzzled by results

查看:883
本文介绍了使用scipy.ndimage.uniform_filter在天文照片中查找星星,但结果感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am searching for stars in an umage of night sky, after making a mask I use scipy.ndimage.uniform_filter at different sizes to find the stars. It looks to work reasonably well, but I expected once I used a small enough size, I would just get more hits as I reduced the size further, but it doesn't do this consistently, I am just a bit baffled by this.

底部的一个热门区域有一个摘录

There is an extract from around one of the hit areas at the bottom

下面的代码告诉我:

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点击率为零?这对我来说似乎很奇怪!

Why do size 6 & 7 give zero hits? This seems totally bizarre to me!

 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)))

这是以其中一颗星为中心的面具的一部分:

Here's part of the mask centred on one of the stars:

>>> 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,或者至少是一个讨厌的实现细节,会导致用户代码中的错误。

This looks like a bug, or at least a nasty implementation detail that will result in bugs in users' code.

首先,请阅读 uniform_filter docstring:

First, read the note in the uniform_filter 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.

让我们看一下 uniform_filter1d 不同大小的过滤器。

So let's look at how one row of your input array is processed by uniform_filter1d for different size filters.

这是一个小的一维输入:

Here's a small one-dimensional input:

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 随着尺寸的增加:

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。

Like your example, the output is all zeros when the size is 6 or 7.

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

I suspect this is a floating point precision problem. Note what happens when we make the input an array of floating point values:

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)时,结果全为零:

So the intermediate values computed using floating point do not give the expected value of 1 in the "middle" of that output. When this array is converted back to the input data type (int), the result is all zeros:

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 之前将输入数组转换为浮点数,并添加一个最终步骤,以控制的方式将结果转换回整数这符合你想要如何分类命中。甚至完全使用不同的功能。

Given that behavior, I recommend converting your input array to floating point before calling uniform_filter, and adding a final step that converts the result back to integers in a way that you control, and that matches how you want to classify a "hit". Or even use a different function altogether.

这篇关于使用scipy.ndimage.uniform_filter在天文照片中查找星星,但结果感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆