python opencv cv2.cv.cv_CAP_PROP_FRAME_COUNT获取错误号码

2024-10-02 14:28:35 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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


Tags: pathimporthomedataosvideocountcv2
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

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使用的底层编解码器解析,那么这些数字也可能不同。

相关问题 更多 >