这是我的一个快速集思广益的想法,以及策略和 Python 代码。注意:我打算只发表评论,但为了说明这个想法,我需要输入一些代码。所以我们开始吧! (喝杯咖啡/建议喝点烈酒……)
当前状态
- 我们有视频 1
vid1 4D 形状 (185, 100, 50, 3)
- 我们有视频 2
vid2 4D 形状 (64, 100, 50, 3)
- ... 其中形状代表
(frame ID, width, height, RGB channels)
- 我们希望将两个视频“堆叠”在一起,作为一个具有 5D 形状
(2, n, 100, 50, 3) 的 numpy 数组。注意:2 因为我们正在堆叠 2 个视频。 n 是我们可以选择的超参数。我们保持视频大小不变 (100 width x 50 height x 3 RGB channels)
机会
我看到的第一件事是vid1 的帧数大约是vid2 的 3 倍。我们用60 作为公因数呢?即让我们将超参数n 设置为60。 (注意:可能需要一些“帧裁剪”/“帧丢弃” - 这将在下面介绍。)
策略
第 1 阶段 - 裁剪两个视频(丢弃一些帧)
让我们将vid1 和vid2 裁剪为60 的倍数的整数(我们的n - 超参数)。具体来说:
- 裁剪
vid1,使形状变为(180, 100, 50, 3)。 (即我们丢弃最后 5 帧)。我们将此新裁剪的视频称为vid1_cropped。
- 裁剪
vid2,使形状变为(60, 100, 50, 3)。 (即我们丢弃最后 4 帧)。我们将此新裁剪的视频称为vid2_cropped。
第 2 阶段 - 将两个视频都设为 60 帧
-
vid2_cropped 已经是 60 帧,形状为 (60, 100, 50, 3)。所以我们不要管它。
-
vid1_cropped 但是是 180 帧。所以我建议我们通过平均 3 帧批次中的 RGB 通道值来将此视频减少到 60 帧 - 对于所有像素位置(沿宽度和高度)。在这个过程结束时,我们将得到一个有点“稀释”(平均)的视频,其形状与vid2_cropped - (60, 100, 50, 3) 相同。我们将这个稀释视频称为vid1_cropped_diluted。
第 3 阶段 - 将两个相同形状的视频堆叠在一起
现在vid2_cropped 和vid1_cropped_diluted 都具有相同的4D 形状(60, 100, 50, 3)。我们可以将它们堆叠在一起以获得最终的 5D 形状的 numpy 数组(2, 60, 100, 50, 3) - 我们称之为vids_combined。
我们完成了!
演示
将策略转化为代码。我是在 Python 3.6(使用 Jupyter Notebook / Jupyter Console)中完成的。
一些注意事项:
-
我尚未验证代码(并根据需要进行修改)。同时,如果您发现任何错误,请大声疾呼-我很乐意更新。
-
我有一种直觉,下面的第 10 行关于“稀释”(np.average 步骤)可能包含错误。即我的意思是对所有像素位置仅针对 RGB 通道值执行 3 帧平均。我需要仔细检查语法。 (同时请检查第 10 行!)
-
这篇文章说明了概念和一些代码实现。理想情况下,我会通过更小的视频尺寸更深入地了解这一点,这样我们就可以逐个像素地获得更好的直觉/可视化每一步。 (当我有时间时,我可能会回到这个)。目前,我相信 numpy 数组形状分析足以传达这个想法。
In [1]: import numpy as np
In [2]: vid1 = np.random.random((185, 100, 50, 3))
In [3]: vid1.shape
Out[3]: (185, 100, 50, 3)
In [4]: vid2 = np.random.random((64, 100, 50, 3))
In [5]: vid2.shape
Out[5]: (64, 100, 50, 3)
In [6]: vid1_cropped = vid1[:180]
In [7]: vid1_cropped.shape
Out[7]: (180, 100, 50, 3)
In [8]: vid2_cropped = vid2[:60]
In [9]: vid2_cropped.shape
Out[9]: (60, 100, 50, 3)
In [10]: vid1_cropped_diluted = np.average(vid1_cropped.reshape(3,60,100,50,3),
: axis=0)
In [11]: vid1_cropped_diluted.shape
Out[11]: (60, 100, 50, 3)
In [12]: vids_combined = np.stack([vid1_cropped_diluted, vid2_cropped])
In [13]: vids_combined.shape
Out[13]: (2, 60, 100, 50, 3)