使用 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 的调用中在ba 周围加上额外的括号? 方括号是为了防止下面的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=1axis=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 时没有

使用google可视化api时,使用dashboard时如何使用getChartLayoutInterface()

使用PUTTY+xming时出错