You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用scipy.signal.convolve为何出现远小于1/9的极小正值?

均值卷积后出现极小正值的原因分析

测试代码

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,且不存在0到1之间的数值,使用3×3均值核(核值为1/9)进行valid模式卷积后,却出现了大于0且小于0.00001的正值。按理论最小正值应为1/9,这一现象如何解释?


原因解析

这种现象完全由浮点数精度限制和卷积运算的实现误差导致,具体如下:

  • 浮点数无法精确表示1/9:1/9是无限循环的二进制小数,无法用float32(或任何二进制浮点数类型)精确存储,实际存储的是近似值。当对全0像素窗口卷积时,理论结果应为0,但九个近似的1/9与0相乘后相加的过程中,浮点数运算的舍入误差会累积出极小的非零正值。
  • 卷积实现的误差放大:scipy.signal.convolve默认会根据输入尺寸自动选择计算方式(直接卷积或FFT加速)。当使用FFT完成卷积时,迭代计算过程中的浮点误差会进一步放大,导致原本应为0的结果出现微小偏移,表现为极小的正值。

验证方法

用全0图像可复现该现象:

import numpy as np
from scipy.signal import convolve

# 创建全0的float32图像
image = np.zeros((5, 5), dtype=np.float32)
# 3×3均值核卷积
con = convolve(image, np.ones((3, 3), dtype=np.float32)/9, mode='valid')
# 检查是否存在极小正值
print(np.logical_and(con > 0, con < 0.00001).any())  # 输出为True

内容的提问来源于stack exchange,提问作者Paul Jurczak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:00:25