Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV/Python:使用视频捕获读取特定帧_Python_Python 2.7_Opencv - Fatal编程技术网

OpenCV/Python:使用视频捕获读取特定帧

OpenCV/Python:使用视频捕获读取特定帧,python,python-2.7,opencv,Python,Python 2.7,Opencv,有没有办法使用VideoCapture()方法获取特定帧 我目前的代码是: import numpy as np import cv2 cap = cv2.VideoCapture('video.avi') 这是我的参考教程。谢谢GPPK 视频参数应以整数形式给出。每个标志都有自己的值。有关代码,请参阅 正确的解决方案是: import numpy as np import cv2 #Get video name from user #Ginen video name must be in

有没有办法使用
VideoCapture()
方法获取特定帧

我目前的代码是:

import numpy as np
import cv2

cap = cv2.VideoCapture('video.avi')
这是我的参考教程。

谢谢GPPK

视频参数应以整数形式给出。每个标志都有自己的值。有关代码,请参阅

正确的解决方案是:

import numpy as np
import cv2

#Get video name from user
#Ginen video name must be in quotes, e.g. "pirkagia.avi" or "plaque.avi"
video_name = input("Please give the video name including its extension. E.g. \"pirkagia.avi\":\n")

#Open the video file
cap = cv2.VideoCapture(video_name)

#Set frame_no in range 0.0-1.0
#In this example we have a video of 30 seconds having 25 frames per seconds, thus we have 750 frames.
#The examined frame must get a value from 0 to 749.
#For more info about the video flags see here: https://stackoverflow.com/questions/11420748/setting-camera-parameters-in-opencv-python
#Here we select the last frame as frame sequence=749. In case you want to select other frame change value 749.
#BE CAREFUL! Each video has different time length and frame rate. 
#So make sure that you have the right parameters for the right video!
time_length = 30.0
fps=25
frame_seq = 749
frame_no = (frame_seq /(time_length*fps))

#The first argument of cap.set(), number 2 defines that parameter for setting the frame selection.
#Number 2 defines flag CV_CAP_PROP_POS_FRAMES which is a 0-based index of the frame to be decoded/captured next.
#The second argument defines the frame number in range 0.0-1.0
cap.set(2,frame_no);

#Read the next frame from the video. If you set frame 749 above then the code will return the last frame.
ret, frame = cap.read()

#Set grayscale colorspace for the frame. 
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

#Cut the video extension to have the name of the video
my_video_name = video_name.split(".")[0]

#Display the resulting frame
cv2.imshow(my_video_name+' frame '+ str(frame_seq),gray)

#Set waitKey 
cv2.waitKey()

#Store this frame to an image
cv2.imwrite(my_video_name+'_frame_'+str(frame_seq)+'.jpg',gray)

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()

如果您想要精确的帧,您可以将视频捕获会话设置为该帧。自动调用该框架更直观。“正确”的解决方案要求您输入已知数据:如fps、长度等。使用下面的代码,您只需要知道要调用的帧

import numpy as np
import cv2
cap = cv2.VideoCapture(video_name) #video_name is the video being called
cap.set(1,frame_no); # Where frame_no is the frame you want
ret, frame = cap.read() # Read the frame
cv2.imshow('window_name', frame) # show frame on window
如果要按住窗口,直到按退出:

while True:
    ch = 0xFF & cv2.waitKey(1) # Wait for a second
    if ch == 27:
        break

是的,非常直截了当:

import cv2
cap = cv2.VideoCapture(videopath)
cap.set(cv2.CV_CAP_PROP_POS_FRAMES, frame_number-1)
res, frame = cap.read()
“frame\u number”是一个范围为0…的整数。注意:您应该设置“frame_number-1”以强制读取frame_number。虽然并没有很好的文档记录,但测试表明视频捕获模块的行为是正确的

“res”是操作的布尔结果,可以使用它检查帧是否已成功读取。 可以通过以下方式获得帧的数量:

amount_of_frames = cap.get(cv2.CV_CAP_PROP_FRAME_COUNT)

例如,要开始阅读视频的第15帧,可以使用:

frame = 15
cap.set(cv2.CAP_PROP_POS_FRAMES, frame-1)
设定一个特定的框架 从VideoCaptureProperties()的文档可以看出,在VideoCapture中设置帧的方法是:

frame = 30
cap.set(cv2.CAP_PROP_POS_FRAMES, frame)
milliseconds = 1000
cap.set(cv2.CAP_PROP_POS_MSEC, milliseconds)
请注意,您不必传递到函数
frame-1
,因为正如文档所述,标志
CAP_PROP_POS_FRAMES
表示“下一步要解码/捕获的帧的基于0的索引”

总结一个完整的示例,我希望每秒阅读一帧:

import cv2

cap = cv2.VideoCapture('video.avi')

# Get the frames per second
fps = cap.get(cv2.CAP_PROP_FPS) 

# Get the total numer of frames in the video.
frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)

frame_number = 0
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number) # optional
success, image = cap.read()

while success and frame_number <= frame_count:

    # do stuff

    frame_number += fps
    cap.set(cv2.CAP_PROP_POS_FRAMES, frame_number)
    success, image = cap.read()
与前面的完整示例一样,每秒读取一帧可以通过以下方式实现:

import cv2

cap = cv2.VideoCapture('video.avi')

# Get the frames per second
fps = cap.get(cv2.CAP_PROP_FPS) 

# Get the total numer of frames in the video.
frame_count = cap.get(cv2.CAP_PROP_FRAME_COUNT)

# Calculate the duration of the video in seconds
duration = frame_count / fps

second = 0
cap.set(cv2.CAP_PROP_POS_MSEC, second * 1000) # optional
success, image = cap.read()

while success and second <= duration:

    # do stuff

    second += 1
    cap.set(cv2.CAP_PROP_POS_MSEC, second * 1000)
    success, image = cap.read()
导入cv2
cap=cv2.VideoCapture('video.avi')
#获取每秒的帧数
fps=cap.get(cv2.cap\u PROP\u fps)
#获取视频中的总帧数。
帧计数=cap.get(cv2.cap\u PROP\u帧计数)
#以秒为单位计算视频的持续时间
持续时间=帧数/fps
秒=0
封盖设置(cv2.cap_PROP_POS_MSEC,秒*1000)#可选
成功,image=cap.read()

当您在
cap.set(1,frame_no)
中使用success和second时,请查看下面我的答案。在
python 3.5
中,使用
cap.set()
,第一个参数定义范围为0.0-1.0的帧编号。所以它是
cap.set(1,frame\u no)
。在cap.set()中,第一个参数应该是“cv2.cv.cv\u cap\u PROP\u POS\u FRAMES”,没有任何神奇的“1”或“2”。第二个是0范围内的帧编号-cv2.cv.cv_CAP_PROP_frame_COUNT-它是一个整数,而不是浮点0.0-1.0@AlexeyAntonenko需要注意的是,向“索引”的转换并不总是完美的。它不一定给出“索引”框架,我猜开发人员只是包装了旧的[0-1]代码,并且存在舍入错误。我在OpenCV页面上发布了一个问题/错误报告,因为他们主页上的实际错误报告链接已断开。使用opencv-python-4.1.1.26,找不到cv2.cv.cv_CAP_PROP_POS_框架。可能枚举已关闭,但我必须使用vid.set(1,myEndFrame)。
cv2.cv.cv.cv\u CAP\u PROP\u FRAME\u COUNT
对我不可用。我确实找到了cv2.CAP\u PROP\u FRAME\u COUNT
我猜你使用的是cv3.x。Opencv 3.x在cv2模块中定义了这些常量,但没有CV_uuu前缀。Opencv 2.x在cv2.cv模块中定义它们,并使用cv_u前缀。对于cap.set,您需要使用frame_number作为[0;amount_of_frames-1]中的索引。按照您的建议,对于第一帧,我们应该设置0-1=-1,对吗?这毫无意义,因为cap.set在该操作后返回0。但是,在一些mp4视频上,我可以设置0帧和num_of_frames并成功读取它们(因此,总共读取n+1帧),这显然是一些舍入错误。该属性现在命名为
cv2.cv2.CAP_PROP_POS_frames