0

目标:要从视频中提取所有帧,在机器学习模型中处理这些帧,并从这些处理过的帧中重建一个新视频。

问题:我目前能够从视频中提取帧,但速度非常慢。大约每秒 2 帧。我想将其加速到每秒至少 10-20 帧。

我正在使用android的本机MediaMetadataRetriever类来提取帧Bitmap并将它们存储在List

这是代码:

fun getAllFrames(uri: Uri): List<Bitmap> {
    val frameList = ArrayList<Bitmap>()

    setDataSource(context, uri)

    // playback duration (in ms) of the data source.
    val duration: String? = extractMetadata(METADATA_KEY_DURATION)
    val durationMillis = duration!!.toInt()
    val durationMicros = durationMillis * 1000

    // to get a video output with 30fps (input can be 60 or 30fps)
    val fps30 = ((1000/30)*1000).toLong()

    for (i in 0L..durationMicros step fps30) {

        val frame = getFrameAtTime(i, OPTION_CLOSEST)

        frame?.let {
           frameList.add(frame)
        }
    }

    return frameList
}

我查看了ffmpegandjavaCV库,但我没有看到准确有效地提取所有帧的方法(也许我错过了它?)。而不是在 中使用时间间隔getFrameAtTime,我想要一个类似的方法grabeAllFrames

谁能给我任何提示如何实现这个目标???

4

1 回答 1

1

您正在处理的几乎所有视频都将以一种或另一种格式编码,而这些编码格式,例如 egh264,通常会压缩视频以节省存储空间和带宽。

权衡是您需要做一些工作来解压缩视频并获取每一帧,并且编解码器(编码器)越“高效”,它通常需要做的工作就越多。

大多数设备都有专用的硬件加速路径来解码和显示常见的视频编码格式,但这些通常是为显示而不是分析和修改视频而优化的。

如果您可以选择在服务器端完成工作,由于可用的处理能力更强,并且可能有更广泛的库和服务集可能可用,这通常会容易得多。

如果您确实必须在移动设备上工作,那么可能值得查看适用于 Android 的 OpenCV,但需要注意的是编译起来可能很棘手,并且文档通常是基于 Eclipse 的。

当然,如果您对每帧的分析不太需要处理器,那么您应该能够达到每秒 2 帧以上的速度。

首先看一个很好的简单示例是颜色俱乐部检测,它每帧检测特定颜色的对象或斑点:https ://github.com/opencv/opencv/tree/master/samples/android/color-blob-检测/src/org/opencv/samples/colorblobdetect

这个答案提供了一个带注释的摘录来解释它是如何工作的:https ://stackoverflow.com/a/40918718/334402

值得补充的是,机器学习用例也可能需要处理器和时间,因此这两者的结合可能会减慢您的用例速度。

于 2021-07-14T14:30:29.513 回答