Reading every nth frame from VideoCapture in OpenCV
I'm afraid there's not much you can do and it's not just a shortcoming of OpenCV. You see, modern video codecs, are, generally, complex beasts. To get a higher compression rate the encoding of a frame is often dependent on previous and sometimes even successive frames.
So, most of the time you have to decode frames before the desired one even if you don't need them.
There are rather non-trivial tricks to specifically encode a video file, so that it would be cheap to get every Nth frame, but it's not feasible in general case.
That said, you can try the seeking functionality OpenCV provides (see OpenCV Seek Function/Rewind). It may (as well as may not) work faster depending on the circumstances. However, personally, I wouldn't bet on it.
OpenCV/Python: read specific frame using VideoCapture
Thank you GPPK.
The video parameters should be given as integers. Each flag has its own value. See here for the codes.
The correct solution is:
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()
Python: Extract 'n' frames in different length of video
You can get the total number of frames, divide it by n to have the number of frames you'll skip at each step and then read the frames
vidcap = cv2.VideoCapture(video_path)
total_frames = vidcap.get(cv2.CAP_PROP_FRAME_COUNT)
frames_step = total_frames//n
for i in range(n):
#here, we set the parameter 1 which is the frame number to the frame (i*frames_step)
vidcap.set(1,i*frames_step)
success,image = vidcap.read()
#save your image
cv2.imwrite(path,image)
vidcap.release()
Cutting Video on frames, save only every 3rd?
All you need to do is to check if count % 3 == 0
. However, there's another catch in your code
import cv2
vidcap = cv2.VideoCapture('myvid.mp4')
success,image = vidcap.read()
count = 0;
# number of frames to skip
numFrameToSave = 3
print "I am in success"
while success: # check success here might break your program
success,image = vidcap.read() #success might be false and image might be None
#check success here
if not success:
break
# on every numFrameToSave
if (count % numFrameToSave ==0):
cv2.imwrite("img_%3d.jpg" % count, image)
if cv2.waitKey(10) == 27:
break
count += 1
read a frame and the 10th previous frame every time from a video
This is how u can do it. This is a simple code which takes a list and stores the frame in the list from 1 to 10 then when 11 frame comes it deletes the first frame and shows the 1st and 10th frame and I added time delay before destroying the previous window otherwise it will open so many windows or sometimes crash and sometimes works all fine just try to comment them out if it works fine for you.
import cv2
import numpy as np
import face_recognition
import time
video=cv2.VideoCapture(0)
count=0
l=[]
while True:
ret, frame = video.read()
count+=1
l.append(frame)
if count>10:
cv2.imshow("1",l[10])
cv2.imshow("10",l[0])
l.remove(l[0])
time.sleep(1)
cv2.destroyAllWindows()
if cv2.waitKey(1) & 0xFF == ord('q'):
break
Related Topics
Divide Array into K Contiguos Partitions Such That Sum of Maximum Partition Is Minimum
Why Can Templates Only Be Implemented in the Header File
What Is the Most Effective Way For Float and Double Comparison
Why Do People Say There Is Modulo Bias When Using a Random Number Generator
Why Does Dividing Two Int Not Yield the Right Value When Assigned to Double
What's the Correct Way to Use Printf to Print a Size_T
How to Convert a Std::String to Int
Difference Between 'Typedef' and 'Using' in C++11
Why C++11 In-Class Initializer Cannot Use Parentheses
Timer Function to Provide Time in Nano Seconds Using C++
Convert from an Infix Expression to Postfix (C++) Using Stacks
Why Is Iostream::Eof Inside a Loop Condition (I.E. 'While (!Stream.Eof())') Considered Wrong
When and Why Will a Compiler Initialise Memory to 0Xcd, 0Xdd, etc. on Malloc/Free/New/Delete
Why Can't Variables Be Declared in a Switch Statement
Opengl - Vertex Normals in Obj
Returning Multiple Values from a C++ Function