我在OSX(10.10.5)的python中使用OpenCV。我是OpenCV的新手。现在,我只是想查找视频中发生某个事件的帧号。我正在使用轨迹栏浏览视频。

我遇到的问题是OpenCV正在报告非整数帧号。我的程序应将帧号设置为轨迹栏位置。轨迹栏位置始终是整数,但帧编号不是。对于较长的视频,问题似乎更严重:对于较短的视频,当轨迹栏位置为254时,帧号(如果不是整数)类似于253.99999999999994。但是,对于较长的视频,帧号与整数之间的距离越来越远值(例如,当跟踪栏位置为11212时为11212.20588235294,或者当跟踪栏位置为26631时为26631.529411764703。)请注意,这些数字并不总是四舍五入或截断为与跟踪栏位置相同的整数。

每个视频的总帧数也不是整数:我正在测试的较短视频为1547.9999999999998,而我正在测试的较长视频为92651.38235294117。较短的视频是.mov文件,而较长的视频是.mp4,我使用ffmpeg从.mpg对其进行了转码。

为什么会这样呢?我如何找出帧号?谢谢你的帮助!这是我一直在使用的测试代码(请注意,它基于http://giusedroid.blogspot.com/2015/05/python-opencv-frame-grabber.html的抓帧器):

import numpy as np
import cv2

video_path = '#set video path here'

# grab a VideoCapture object
cap = cv2.VideoCapture(video_path)

#set some shorthand names
current_frame_flag = cv2.cv.CV_CAP_PROP_POS_FRAMES
total_frames_flag = cv2.cv.CV_CAP_PROP_FRAME_COUNT
win_name = "Frameshift calculator"
pos_trackbar='pos_trackbar'

cv2.namedWindow(win_name)


def seek_callback(x):

    # we want to change the value of the frame variable globally
    global frame
    # by getting the position of the trackbar
    i = cv2.getTrackbarPos(pos_trackbar, win_name)
    # and skipping to the selected frame
    cap.set(current_frame_flag, i)
    _, frame = cap.read()
    # and then update the window
    cv2.imshow(win_name, frame)
    #print out the current frame flag and the trackbar position
    print(cap.get(current_frame_flag), i)

cv2.createTrackbar(pos_trackbar, win_name, 0, int(cap.get(total_frames_flag)), seek_callback)

while True:
    # shows the image
    cv2.imshow(win_name, frame)
    # waits for keystroke
    if cv2.waitKey(0) & 0xFF == ord('q'):
        break
    key = cv2.waitKey(0)

cap.release
cv2.destroyAllWindows()

一些样本(帧号,轨迹栏位置)对:

较短的视频(.mov):
(1.0,0)
(171.99999999999997,172)
(842.9999999999999,843)
(1141.0,1141)
(1330.0,1330)
(111.99999999999999,112)
(235.99999999999997,236)
(590.9999999999999,591)
(1546.9999999999998,1547)

较长的视频(.mp4):
(1.0,0)
(6642.911764705882,6642)
(27496.11764705882,27496)
(49707.529411764706,49707)
(64786.294117647056,64786)
(84065.38235294117,84065)

最佳答案

这很可能是因为您的帧频不是整数。对于每个视频,请调查视频的实际帧速率是多少:

frame_rate = cv2.cv.CV_CAP_PROP_FPS

实际上,对于某些视频,存在浮点帧速率。通常在电视中……至少在北美标准中,预期帧率为30 FPS。但是,您很有可能拥有29.97 FPS。本文将对此进行详细说明:http://theautomaticfilmmaker.com/blog/2009/2/23/about-frame-rates-or-why-2997.html

但是,如果我可以总结一下,可以追溯到1970年代,在先进的电子设备处理这种情况之前,在将彩色图像引入电视之前,广播的速度实际上达到了30 FPS,但是由于发送彩色信息所需的额外信息,实际上干扰声音信息,因此他们必须将FPS延迟0.03 FPS,以补偿声音信息和颜色信息并将它们稍微移相。

但这不是重点。之所以要获得一个视频相对于另一个视频的浮点帧数,完全取决于帧速率。因此,通过尝试在所需位置获得帧号,可能会出现所需的帧号与视频中的实际帧不完全一致的情况,因此它将为您提供该帧号。由于浮点帧速率,因此对应于最佳值,这就是为什么要获得浮点结果的原因。

当您开始使帧索引变大时,也会出现偏移的原因再次是因为帧速率。当您开始指定更高的帧号时,请记住,对于30 / 29.97场景,您希望所获取的帧是索引,但是因为每30 FPS落后0.03,对于较大的帧索引,此差异会加剧,因为您每30帧就要增加0.03的差异。

关于获取确切的帧号,我在这里真的没有建议。但是,您可以提取所需的设置帧索引之前和之后的一帧,然后从中查看情况。在实践中很少使用指定实际的帧索引本身(至少从我所看到的),这就是为什么这样的确切原因。

关于python - OpenCV中的非整数帧号?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33573312/

10-10 11:54