OpenCV/Python: read specific frame using VideoCapture
是否可以使用
我当前的代码是:
1 2 3 4 | import numpy as np import cv2 cap = cv2.VideoCapture('video.avi') |
这是我的参考教程。
谢谢GPPK。
视频参数应以整数形式给出。每个标志都有其自己的值。有关代码,请参见此处。
正确的解决方案是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 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":\ ") #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() |
是的,非常简单:
1 2 3 4 | import cv2 cap = cv2.VideoCapture(videopath) cap.set(cv2.CV_CAP_PROP_POS_FRAMES, frame_number-1) res, frame = cap.read() |
'frame_number'是范围为0 ... amount_of_frames的整数。注意:您应该设置" frame_number-1"以强制读取框架" frame_number"。没有很好的文档说明,但是测试表明VideoCapture模块的行为。
'res'是布尔运算结果,可以使用它来检查是否成功读取了帧。
一个人可以通过以下方式获得帧数:
1 | amount_of_frames = cap.get(cv2.CV_CAP_PROP_FRAME_COUNT) |
如果要精确的帧,可以将VideoCapture会话设置为该帧。自动调用该框架更为直观。"正确"的解决方案要求您输入已知数据:例如fps,长度和诸如此类。您需要用下面的代码知道的是您要调用的框架。
1 2 3 4 5 6 | 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 |
如果要按住窗口,直到按退出:
1 2 3 4 | while True: ch = 0xFF & cv2.waitKey(1) # Wait for a second if ch == 27: break |
设置特定的框架
从VideoCaptureProperties(docs)的文档中可以看到,在VideoCapture中设置帧的方式是:
1 2 | frame = 30 cap.set(cv2.CAP_PROP_POS_FRAMES, frame) |
请注意,您不必传递给函数
我想每秒读取一帧的一个完整示例是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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() |
设定特定时间
在上面链接的文档中,可以看到在VideoCapture中设置特定时间的方式是:
1 2 | milliseconds = 1000 cap.set(cv2.CAP_PROP_POS_MSEC, milliseconds) |
就像在完整示例之前每秒读取一帧一样,可以这样实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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() |
例如,要开始阅读视频的第15帧,可以使用:
1 2 | frame = 15 cap.set(cv2.CAP_PROP_POS_FRAMES, frame-1) |