After reading the documentation of VideoCapture. I figured out that you can tell VideoCapture, which frame to process next time we call VideoCapture.read() (or VideoCapture.grab()).
The problem is that when you want to read() a frame which is not ready, the VideoCapture object stuck on that frame and never proceed. So you have to force it to start again from the previous frame.
Here is the code
import cv2
cap = cv2.VideoCapture("./out.mp4")
while not cap.isOpened():
cap = cv2.VideoCapture("./out.mp4")
cv2.waitKey(1000)
print "Wait for the header"
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
while True:
flag, frame = cap.read()
if flag:
# The frame is ready and already captured
cv2.imshow('video', frame)
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
print str(pos_frame)+" frames"
else:
# The next frame is not ready, so we try to read it again
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
print "frame is not ready"
# It is better to wait for a while for the next frame to be ready
cv2.waitKey(1000)
if cv2.waitKey(10) == 27:
break
if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
Answer from Mehran on Stack OverflowHow to process images of a video, frame by frame, in video streaming using OpenCV and Python - Stack Overflow
How is a video file is read frame by frame without loading the entire video file in memory?
How to read specific frames from a video using OpenCV's Cuda Video Reader in Python? - Python - OpenCV
How to get FPS of a video file?
You should be able to get it with OpenCV
More on reddit.comAfter reading the documentation of VideoCapture. I figured out that you can tell VideoCapture, which frame to process next time we call VideoCapture.read() (or VideoCapture.grab()).
The problem is that when you want to read() a frame which is not ready, the VideoCapture object stuck on that frame and never proceed. So you have to force it to start again from the previous frame.
Here is the code
import cv2
cap = cv2.VideoCapture("./out.mp4")
while not cap.isOpened():
cap = cv2.VideoCapture("./out.mp4")
cv2.waitKey(1000)
print "Wait for the header"
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
while True:
flag, frame = cap.read()
if flag:
# The frame is ready and already captured
cv2.imshow('video', frame)
pos_frame = cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES)
print str(pos_frame)+" frames"
else:
# The next frame is not ready, so we try to read it again
cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos_frame-1)
print "frame is not ready"
# It is better to wait for a while for the next frame to be ready
cv2.waitKey(1000)
if cv2.waitKey(10) == 27:
break
if cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES) == cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT):
# If the number of captured frames is equal to the total number of frames,
# we stop
break
Use this:
import cv2
cap = cv2.VideoCapture('path to video file')
count = 0
while cap.isOpened():
ret,frame = cap.read()
cv2.imshow('window-name', frame)
cv2.imwrite("frame%d.jpg" % count, frame)
count = count + 1
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows() # destroy all opened windows
As I understand that a video file is a binary file, the frames are not really present in a contiguous manner in a video file, so reading the video file by doing a seek and reading it frame by frame wouldn't work until you have loaded the entire file into memory and then go through it frame by frame.
But if you see any video file reading library eg opencv code, you can read each frame one by one by calling read multiple times in a loop.
video=cv2.VideoCapture(video_path)
grabbed, frame=video.read()
My question is how do they(such libraries) work internally to read the frames one by one without loading the entire video file in memory since frames are not really present in a video file in a contiguous manner so the seek and read x+size data wouldn't work.