应用 scipy.signal.convolve 产生的小价值工件

问题描述 投票:0回答:1

这个 Python 3.11.5 脚本:

import numpy as np
from skimage.io import imread
from scipy.signal import convolve

image = np.flipud(imread('conv-test.bmp').astype(np.float32))
con = convolve(image, np.ones((3, 3))/9, mode='valid')
print(image.min())
print(np.logical_and(image > 0, image < 1).any())
print(np.logical_and(con > 0, con < 0.00001).any())

产生:

0.0
False
True

如何获得小于 0.00001 的正值? 1/9 不应该是这个卷积产生的最小正值吗?

python numpy scipy convolution
1个回答
0
投票

函数

scipy.signal.convolve
有一个
method
参数,可让您选择用于计算卷积的方法。可用的方法有直接法和FFT。如果您没有显式设置方法,它将根据启发式方法选择一种方法,通常会选择更快的方法。在您的情况下,它似乎选择了 FFT 方法。 FFT 会受到正常浮点不精确性的影响,这可能会导致理论上应为零的值实际上非常小但非零。这是一个小的一维示例:

In [76]: x = np.zeros(18)

In [77]: x[9:] = 1

In [78]: convolve(x, np.ones(3)/3, method='fft', mode='valid')
Out[78]: 
array([-1.49880108e-16, -8.88178420e-17,  0.00000000e+00,  0.00000000e+00,
       -8.88178420e-17, -1.11022302e-16, -8.88178420e-17,  3.33333333e-01,
        6.66666667e-01,  1.00000000e+00,  1.00000000e+00,  1.00000000e+00,
        1.00000000e+00,  1.00000000e+00,  1.00000000e+00,  1.00000000e+00])

理论上,该结果中的前七个值应该都是0。我们可以通过选择直接方法得到该结果:

In [79]: convolve(x, np.ones(3)/3, method='direct', mode='valid')
Out[79]: 
array([0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.33333333, 0.66666667, 1.        ,
       1.        , 1.        , 1.        , 1.        , 1.        ,
       1.        ])
© www.soinside.com 2019 - 2024. All rights reserved.