使用 scipy.signal.lfilter 时,实现 Butterworth 带通滤波器遇到:“ValueError: object of too small depth for desired
Posted
技术标签:
【中文标题】使用 scipy.signal.lfilter 时,实现 Butterworth 带通滤波器遇到:“ValueError: object of too small depth for desired array”错误【英文标题】:Implementing Butterworth bandpass filter running into: "ValueError: object of too small depth for desired array" error when using scipy.signal.lfilter 【发布时间】:2022-01-05 08:31:22 【问题描述】:我正在尝试按照this 论文实现欧拉视频放大,但是在使用巴特沃斯带通滤波器时,它不断遇到“ValueError: object of too small depth for desired array”
这是我的巴特沃斯带通滤波器代码:
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = scipy.signal.lfilter([b], [a], data, axis=0) #The line that errors
return y
def butter_bandpass(lowcut, highcut, fs, order=5):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = scipy.signal.butter(order, [low, high], btype='band')
return b, a
我在以下代码行中使用了 butter_bandpass_filter:
magnify_motion(tired_me, 0.4, 3)
def magnify_motion(video, low, high, n=4, sigma=3, amp=20):
lap_video_lst = video.get_laplacian_lst(n=n, sigma=sigma)
print("lap_video_lst shapes:")
for i in range(n):
print(":".format(i), get_list_shape(lap_video_lst[i]))
ret_lst = []
for layer in range(n):
filtered_layer = butter_bandpass_filter(lap_video_lst[layer], low, high, video.fps) #This line
filtered_layer *= amp
ret_lst.append(filtered_layer)
return ret_lst
其中每个 lap_video_lst[layer] 被格式化为具有形状 (frame_count, height, width, colour_channels) 的视频所有帧的 numpy 数组,打印时如下:
0: (330, 360, 640, 3)
1: (330, 180, 320, 3)
2: (330, 90, 160, 3)
3: (330, 45, 80, 3)
请注意,每个“层”具有不同维度的原因是它们是原始视频的拉普拉斯金字塔。
如果有用的话,I 这是 b 和 np 数组的形状,以及它们各自的值。
b: (1, 11)
[[ 0.00069339 0. -0.00346694 0. 0.00693387 0.
-0.00693387 0. 0.00346694 0. -0.00069339]]
a: (1, 11)
[[ 1. -8.02213491 29.18702261 -63.4764537 91.44299881
-91.21397148 63.81766134 -30.92689236 9.93534351 -1.91057439
0.16700076]]
这是完整的错误跟踪,以防我忽略了一些细节:
Traceback (most recent call last):
File "d:\Desktop\Stuff\Uni notes B\2021 Fall\Cs194\Projects\Project Final 1\tester.py", line 84, in <module>
main()
File "d:\Desktop\Stuff\Uni notes B\2021 Fall\Cs194\Projects\Project Final 1\tester.py", line 71, in main
magnify_motion(tired_me, 0.4, 3)
File "d:\Desktop\Stuff\Uni notes B\2021 Fall\Cs194\Projects\Project Final 1\tester.py", line 32, in magnify_motion
filtered_layer = butter_bandpass_filter(lap_video_lst[layer], low, high, video.fps)
File "d:\Desktop\Stuff\Uni notes B\2021 Fall\Cs194\Projects\Project Final 1\tester.py", line 17, in butter_bandpass_filter
y = scipy.signal.lfilter([b], [a], data, axis=0)
File "C:\Users\nick-\AppData\Roaming\Python\Python38\site-packages\scipy\signal\signaltools.py", line 1972, in lfilter
raise ValueError('object of too small depth for desired array')
ValueError: object of too small depth for desired array
任何提示都会有所帮助!谢谢:D
更新: 我在“b”和“a”周围使用方括号的原因是因为没有它我会得到以下错误,我被告知我应该如何解决这个问题
ValueError: could not convert b, a, and x to a common type
【问题讨论】:
“这是我的巴特沃斯带通滤波器代码:...” 这看起来与我的旧代码(从 2012 年开始)相似:***.com/questions/12093594/…。但是你为什么在lfilter
的调用中在b
和a
周围加上额外的括号?
方括号是为了防止下面的Valueerror; "ValueError: could not convert b, a, and x to a common type" 不知道为什么会发生。
【参考方案1】:
我没有看报纸。
您看到的问题已通过应用解决
y = scipy.signal.lfilter(b, a, data, axis=0)
这意味着过滤器会将每个数组data[:,x,y,c]
视为一个信号,过滤每个像素的值,可能会使视频产生一些运动模糊,这与用于使边缘更清晰或更平滑的空间过滤不同。对于空间过滤,您可以使用axis=1
或axis=2
。
这是一个将过滤器应用于黑屏视频的示例。
def butter_bandpass_filter(data, lowcut, highcut, fs, order=5):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = scipy.signal.lfilter([b], [a], data, axis=0) #The line that errors
return y
def butter_bandpass(lowcut, highcut, fs, order=5):
nyq = 0.5 * fs
low = lowcut / nyq
high = highcut / nyq
b, a = scipy.signal.butter(order, [low, high], btype='band')
return b, a
# is reasonable to expect that image data will be uint8
data = np.zeros((330, 360, 640, 3), dtype=np.uint8)
b,a = butter_bandpass(0.1, 0.4, 200)
y = scipy.signal.lfilter(b, a, data)
【讨论】:
我添加了方括号,因为否则我会收到“ValueError: could not convert b, a, and x to a common type”错误,另一个堆栈溢出帖子说这就是你修复的方法它。 因此,您的视频数据可能与简单的数字类型的 3D 数组不同。答案是什么(对上下文感到好奇)。以上是关于使用 scipy.signal.lfilter 时,实现 Butterworth 带通滤波器遇到:“ValueError: object of too small depth for desired 的主要内容,如果未能解决你的问题,请参考以下文章
使用 php artisan migrate 时,迁移时更改表名,使用 tinker 保存对象时出错
使用前台服务时允许“使用应用程序时”而不是“始终允许”是不是可以?
使用自定义效果时缺少网格颜色,但使用 BasicEffect 时没有