OpenCV/ Python: lire la trame spécifique en utilisant VideoCapture

y a-t-il un moyen d'obtenir un cadre spécifique en utilisant VideoCapture() méthode?

Mon code actuel:

import numpy as np
import cv2

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

est mon tutoriel de référence.

19
demandé sur zinon 2015-11-11 15:53:30

3 réponses

Merci GPPK.

les paramètres vidéo doivent être donnés en nombres entiers. Chaque drapeau a sa propre valeur. Voir ici pour les codes.

la bonne solution est:

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()
21
répondu zinon 2017-05-23 11:47:11

si vous voulez un cadre exact, vous pouvez simplement régler la session de VideoCapture sur ce cadre. Il est beaucoup plus intuitif de faire appel automatiquement à ce cadre. La solution "correcte" exige que vous saisissiez des données connues: comme fps, longueur, etc. Tout ce que vous devez savoir avec le code ci-dessous est l'image que vous souhaitez appeler.

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

si vous voulez maintenir la fenêtre, jusqu'à ce que vous appuyez sur exit:

while True:
    ch = 0xFF & cv2.waitKey(1) # Wait for a second
    if ch == 27:
        break
12
répondu JParrish88 2016-02-14 11:00:09

Oui, c'est très simple:

import cv2
cap = cv2.VideoCapture(videopath)
cap.set(cv2.CV_CAP_PROP_POS_FRAMES, frame_number-1)
res, frame = cap.read()

'frame_number' est un entier de la gamme 0...amount_of_frames. REMARQUE: Vous devez définir 'frame_number-1' pour forcer la lecture 'frame_number'. Ce n'est pas bien documenté mais le test montre que le comportement du module de VideoCapture.

'res' est le résultat booléen de l'opération, on peut l'utiliser pour vérifier si l'image a été correctement lu. On peut obtenir la quantité d'images par:

amount_of_frames = cap.get(cv2.CV_CAP_PROP_FRAME_COUNT)
12
répondu Alexey Antonenko 2018-06-12 21:02:06