python opencv videoWriter帧/秒舍入

fivyi3re  于 2022-11-24  发布在  Python
关注(0)|答案(2)|浏览(191)

我正在尝试测量输入视频文件中的某个事件:这是通过在几个步骤中处理视频来完成的,其中每个步骤对视频数据执行一些操作,并将中间结果写入新的视频文件。
输入视频的fps为:每秒29.42346629489295帧
下面我写了一个脚本来测试这个问题。当我用这个脚本写一个新文件时,fps在outputfile中被四舍五入到29. 0 fps,这就是问题所在。

import cv2
import sys

inputfilepath = "test.mp4"
outputfilepath = "testFps.mp4"

video = cv2.VideoCapture(inputfilepath)

fps = video.get(cv2.CAP_PROP_FPS)
framecount = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))

print("original fps: ", fps)
# fps = 29.4
print("writing fps: ", fps)

writer = cv2.VideoWriter(outputfilepath, 0x00000020, fps, (width, height))

for i in range(framecount):
    success, image = video.read()
    if not success:
        break

    writer.write(image)

writer.release()
video.release()

video = cv2.VideoCapture(outputfilepath)
fps = video.get(cv2.CAP_PROP_FPS)

# the next line will not print the same fps as I passed to cv2.VideoWriter(...) above.
print("output fps: ", fps)
video.release()

我尝试过硬编码不同的fps值。似乎29. 5 fps以下的所有内容都四舍五入为零小数(29 fps),而以上的所有内容都四舍五入为一小数(29. x fps)
所以我的问题是:
有没有可能得到任何fps与mp4格式?
输出文件中实际使用的fps是多少?
如何在输出文件中获得正确的fps?

其他信息

我尝试了从28 fps到31 fps的许多不同的值,并绘制了实际输出文件的帧率与预期的帧率。这显示了某种分形行为,也许这个提示会激发一些数学向导在这里:)

bkkx9g8r

bkkx9g8r1#

OpenCV使用一些工具包来编写。在我的例子中,在iOS上,OpenCV使用原生的AVFoundation库。看起来AVFoundation(或OpenCV api)不能很好地处理一个有很多有效数字的fps值,比如29.7787878779,并且在OpenCV的api或AVFoundation中有一些东西被错误地舍入了。
为了解决这个问题,在调用VideoWriter::open之前,我对一些有效数字进行了舍入

normalizedFPS = round(1000.0 * normalizedFPS) / 1000.0;

希望它对你也有效!
我曾看到30,000用作时间表建议,因此,或许可以测试一下1000.0与30,000.0

gtlvzcf8

gtlvzcf82#

不幸的是OpenCV内部有一个bug,我读写了一部46分钟的电影,少了2秒钟(相同的帧数,但不同的FPS写在文件的头)对我来说是一个大问题,因为我试图加入另一个编辑器中的音频信息,你可以看到2丢失秒原始电影是fps =(60/1.001)= 59.94005994...并且OpenCv将此fps四舍五入为60,无论我是否在2个位置写入了59.94005994
1.视频编辑器=新的视频编辑器(完整文件名,四CC,fps,缩放大小,真);
1.设置(CAP_PROP_FPS,帧/秒);
坏消息-我在opencv源代码中发现了此代码

outfps = cvRound(fps);

bool AVIWriteContainer::initContainer(const String& filename, double fps, Size size, bool iscolor){
    outfps = cvRound(fps);
    width = size.width;
    height = size.height;
    channels = iscolor ? 3 : 1;
    moviPointer = 0;
    bool result = strm->open(filename);
    return result;
}

我们必须向OpenCv团队上报此错误(我使用opencv-460.jar),我将尝试使用其他程序手动更改标题-这可能会保存局面
解释丢失秒数的数学计算x1c 0d1xx 1c 1d 1x

相关问题