树莓派3B上scipy.signal.resample_poly降采样返回全零结果问题求助
我完全懂你这种被跨平台差异搞疯的心情!先把你的问题梳理清楚:你在PC上用scipy.signal.resample_poly做降采样完全正常,但到树莓派3B上就返回全零数组,而且换了新旧版本的numpy和scipy都没解决,确实头疼。
先贴一下你的测试代码方便大家参考:
import numpy as np from scipy.signal import resample_poly audio_data = np.array([ 43, 58, 67, 88, 89, 99, 121, 113, 88, 69]) sample_rate = 4000 file_rate = 16000 print(f"Before: {audio_data}") audio_data = resample_poly(audio_data, sample_rate, file_rate) print(f"After {audio_data}")
PC输出:
After [ 28.66957128 103.77145182 80.49835032]
树莓派3B输出:
After [0. 0. 0.]
你试过的版本:numpy-2.0.2 + scipy-1.13.1,以及numpy-1.23.0 + scipy-1.8.1,结果一致;其他版本要么没有预编译wheel,要么编译失败或导入报错。
下面给你几个排查和解决的方向:
1. 先检查数据类型的影响
你的输入数组是整数类型,虽然scipy理论上支持整数输入,但ARM架构和x86架构对整数运算的处理可能存在差异。试试先把数据转成浮点型再处理,比如:
audio_data = np.array([43, 58, 67, 88, 89, 99, 121, 113, 88, 69], dtype=np.float64)
或者在调用resample_poly前强制转换:
audio_data = resample_poly(audio_data.astype(np.float64), sample_rate, file_rate)
很多时候这种类型转换能解决跨平台的奇怪问题。
2. 排查scipy的编译依赖问题
树莓派上的scipy如果是通过pip安装的预编译wheel,可能缺少了FFTW库的支持——resample_poly底层依赖FFTW做高效的多相滤波计算,如果编译时没链接FFTW,可能会导致计算异常。
你可以尝试先安装系统级的FFTW依赖,再手动编译scipy(虽然你说编译麻烦,但值得一试):
sudo apt-get install libfftw3-dev libopenblas-dev
然后用pip编译安装指定版本:
pip install --no-binary :all: scipy==1.13.1
如果编译太耗时,也可以试试用conda-forge的ARM适配包,比如安装miniforge后:
conda install scipy numpy
3. 换用替代的降采样方案
如果resample_poly在树莓派上的问题暂时没法解决,可以换用更稳妥的“低通滤波+抽取”方案,这是降采样的标准流程,也能避免混叠:
import numpy as np from scipy.signal import firwin, lfilter audio_data = np.array([43, 58, 67, 88, 89, 99, 121, 113, 88, 69], dtype=np.float64) sample_rate = 4000 file_rate = 16000 down_factor = file_rate // sample_rate # 这里是4倍降采样 # 设计抗混叠低通滤波器,截止频率为目标采样率的一半 nyquist_freq = file_rate / 2 cutoff_freq = sample_rate / 2 filter_taps = 31 # 滤波器阶数,阶数越高滤波效果越好 low_pass_filter = firwin(filter_taps, cutoff_freq / nyquist_freq) # 先滤波再降采样 filtered_data = lfilter(low_pass_filter, 1.0, audio_data) downsampled_data = filtered_data[::down_factor] print(f"After: {downsampled_data}")
这个方案在ARM和x86平台上的表现应该是一致的,而且计算效率也不低,适合树莓派的CPU性能。
希望这些方法能帮你解决问题!
内容来源于stack exchange

