web-dev-qa-db-fra.com

OpenCV / Python: lecture d'images spécifiques à l'aide de VideoCapture

Existe-t-il un moyen d’obtenir une image spécifique en utilisant la méthode VideoCapture()?

Mon code actuel est:

import numpy as np
import cv2

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

This est mon tutoriel de référence.

33
zinon

Merci GPPK.

Les paramètres vidéo doivent être donnés sous forme d'entiers. Chaque drapeau a sa propre valeur. Voir ici pour les codes.

La solution correcte 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()
31
zinon

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 compris dans la plage 0 ... amount_of_frames. Remarque: vous devez définir 'frame_number-1' pour forcer la lecture du frame 'frame_number'. Ce n'est pas bien documenté mais les tests montrent le comportement du module VideoCapture.

'res' est le résultat booléen de l'opération, on peut l'utiliser pour vérifier si l'image a été lue avec succès. On peut obtenir une quantité d'images par:

amount_of_frames = cap.get(cv2.CV_CAP_PROP_FRAME_COUNT)
26
Alexey Antonenko

Si vous voulez une image exacte, vous pouvez simplement définir la session VideoCapture sur cette image. Il est beaucoup plus intuitif d'appeler automatiquement sur ce cadre. La solution "correcte" nécessite que vous saisissiez des données connues: telles que fps, longueur, etc. Tout ce que vous devez savoir avec le code ci-dessous est le cadre 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 souhaitez maintenir la fenêtre enfoncée, jusqu'à ce que vous appuyiez sur exit:

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