【问题标题】:python opencv cv2.cv.CV_CAP_PROP_FRAME_COUNT get wrong numberspython opencv cv2.cv.CV_CAP_PROP_FRAME_COUNT 得到错误的数字
【发布时间】:2015-07-17 09:08:53
【问题描述】:
import os
import cv2
path='/home/nlpr4/video-data/UCF-101/GolfSwing/v_GolfSwing_g24_c06.avi'
cap=cv2.VideoCapture(path)
video_length=int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))

success=True
count=0
while success:
    success,image=cap.read()
    if success==False:
        break
    count=count+1

print video_length,count

输出:

149 
146

为什么这两个数字不同? 怎么了?

【问题讨论】:

  • 不确定,但我认为读取 FRAME COUNT 需要从文件元数据中读取总帧数,但 count 变量需要对帧进行实际解码。如果第 147 帧解码失败,这将导致问题。
  • 2 年过去了。并且没有更多新的答案。可以接受我的回答吗?

标签: python opencv


【解决方案1】:

CAP_PROP_FRAME_COUNT 的 get() 永远不应该是准确的!如果您检查opencv源代码。你可以找到这个:

int64_t CvCapture_FFMPEG::get_total_frames() const
{
    int64_t nbf = ic->streams[video_stream]->nb_frames;

    if (nbf == 0)
    {
        nbf = (int64_t)floor(get_duration_sec() * get_fps() + 0.5);
    }
    return nbf;
}

这意味着它将首先查看nb_frames 的流标头,您可以使用 ffprobe 进行检查。如果没有这个字段,那么没有比直接解码视频更好的获取帧数的方法了。 opencv 通过get_duration_sec() * get_fps() + 0.5 进行了粗略估计,这肯定不意味着准确性。

因此,要获得正确的帧号,您必须解码并读取整个流,或者您必须要求视频生成器生成带有nb_frames 字段的正确流标头。

【讨论】:

  • 此答案不正确且具有误导性。这里OpenCV的计算没有错;它采用预期的帧数并将其四舍五入到最接近的整数。这种舍入没有什么不准确的,因为视频的持续时间始终是 1/FPS 的倍数。 @ilke444 的答案是真实的答案。
  • 即使答案不是 100% 准确,但分享实施细节可以很容易地理解幕后发生的事情 - 并且可以清楚地表明可能发生的错误(nb_frames 不存在,不准确fps,舍入误差...)
【解决方案2】:

CV_CAP_PROP_FRAME_COUNT 给出来自视频标题的“帧数”属性。另一个数字基本上是“我可以从这个视频文件中读取多少帧?”。

如果视频包含无法读取/解码的帧(例如,由于损坏),OpenCV 会跳过这些帧(在尝试读取它们之后)并为您提供下一个有效帧。因此,您的两个数字之间的差异是无法读取的帧数。

此外,如果您的视频标头已损坏和/或无法被 OpenCV 使用的底层编解码器解析,那么这些数字也可能不同。

【讨论】:

  • 前面显然没有CV_,只是CAP_
【解决方案3】:

试试这个代码:

#!/usr/bin/env python

import numpy as np
import cv2

video = "../videos/sample.avi"

video_capture = cv2.VideoCapture(video)
video_length = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))

count = 0
while(True):
        # Capture frame-by-frame
        ret, frame = video_capture.read()
        if not ret:
            break

        count += 1

print video_length, count
# When everything done, release the capture
video_capture.release()
cv2.destroyAllWindows()

在我的机器上它给了我:

$ ./openstack_video_frames.py 
1232 1232

【讨论】:

  • 我有同样的问题,它为某些视频提供了正确的 video_length,但对其他视频却失败了,所有视频都是相同的格式,相同的压缩,可能存在 0、1、2 的差异, 3, 在我测试了 20 个视频后最多 3 个。不知道是不是opencv的bug....
猜你喜欢
  • 1970-01-01
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-20
  • 1970-01-01
  • 2019-02-28
相关资源
最近更新 更多