2
votes

Python: prendre une capture d'écran de la vidéo

L'idée est que l'utilisateur devrait pouvoir charger une vidéo à partir de sa machine locale et dire au programme de prendre une capture d'écran de la vidéo toutes les 5 ou 30 secondes. Existe-t-il une bibliothèque pour m'aider dans cette tâche? Toute idée de la façon de procéder serait utile.


1 commentaires

opencv - vous pouvez video_capture la vidéo, puis la traiter image par image (par exemple, en enregistrant celle que vous voulez obtenir "capture d'écran")


5 Réponses :


4
votes

installez opencv-python (qui est un package OpenCV pré-construit non officiel pour Python) en exécutant la commande suivante:

# Importing all necessary libraries
import cv2
import os
import time

# Read the video from specified path
cam = cv2.VideoCapture("C:/Users/User/Desktop/videoplayback.mp4")

try:

    # creating a folder named data
    if not os.path.exists('data'):
        os.makedirs('data')

    # if not created then raise error
except OSError:
    print('Error: Creating directory of data')

# frame
currentframe = 0

while (True):
    time.sleep(5) # take schreenshot every 5 seconds
    # reading from frame
    ret, frame = cam.read()

    if ret:
        # if video is still left continue creating images
        name = './data/frame' + str(currentframe) + '.jpg'
        print('Creating...' + name)

        # writing the extracted images
        cv2.imwrite(name, frame)

        # increasing counter so that it will
        # show how many frames are created
        currentframe += 1
    else:
        break

# Release all space and windows once done
cam.release()
cv2.destroyAllWindows()
pip install opencv-python


2 commentaires

Merci de répondre. Est-il également possible de définir de prendre des captures d'écran disons à 30e seconde de la vidéo, 40e seconde et 55e seconde de la vidéo?


La partie time.sleep (5) ne fait que ralentir le travail du script pas pour l'intervalle de capture d'écran



1
votes

La réponse ci-dessus est partiellement correcte mais time.sleep ici n'aide pas du tout mais rend plutôt le processus plus lent. cependant, si vous voulez prendre une capture d'écran à un certain moment d'une vidéo, vous devez comprendre que chaque fois que vous faites "ret, frame = cam.read ()", il lit l'image suivante de la vidéo. chaque seconde dans une vidéo a un certain nombre d'images dépend de la vidéo. vous obtenez ce numéro en utilisant:

  if currentframe == (3*frame_per_second):  
      cv2.imwrite(name, frame)

donc si vous devez prendre une capture d'écran de la 3ème seconde, vous pouvez conserver l'itération telle qu'elle est dans la réponse ci-dessus et ajouter simplement

  frame_per_second = cam.get(cv2.CAP_PROP_FPS) 

cela prendra une capture d'écran de la première image dans la troisième seconde.


1 commentaires

Je pense que votre condition est en fait incorrecte. Cela devrait être quelque chose comme: if currentframe% (frame_per_second * 3) == 0:



0
votes

Pour ajouter la réponse de data_sniffer. Je recommanderais d'utiliser round (fonction mathématique) sur frame_per_second lors de la vérification comme si la fréquence d'images est un nombre décimal, alors il entrera dans une boucle infinie.


2 commentaires

Salut, si ce n'est pas une réponse directe à la question, il vaut mieux le dire en commentaire. Au lieu d'une nouvelle réponse.


Je n'ai pas assez de représentants pour faire ça, mais je voulais quand même le publier.



0
votes
#ncica & Data_sniffer solution remake
import cv2
import os
import time

step = 10
frames_count = 3
cam = cv2.VideoCapture('video/example.MP4')

currentframe = 0
frame_per_second = cam.get(cv2.CAP_PROP_FPS) 
frames_captured = 0

while (True):
    ret, frame = cam.read()
    if ret:
        if currentframe > (step*frame_per_second):  
            currentframe = 0
            name = 'photo/frame' + str(frames_captured) + '.jpg'
            print(name)
            cv2.imwrite(name, frame)            
            frames_captured+=1
            if frames_captured>frames_count-1:
                ret = False
        currentframe += 1           
    if ret==False:
        break
cam.release()
cv2.destroyAllWindows()

0 commentaires

0
votes
#a generic function incorporating all the comments mentioned above.

def get_frames(inputFile,outputFolder,step,count):

  '''
  Input:
    inputFile - name of the input file with directoy
    outputFolder - name and path of the folder to save the results
    step - time lapse between each step (in seconds)
    count - number of screenshots
  Output:
    'count' number of screenshots that are 'step' seconds apart created from video 'inputFile' and stored in folder 'outputFolder'
  Function Call:
    get_frames("test.mp4", 'data', 10, 10)
  '''

  #initializing local variables
  step = step
  frames_count = count

  currentframe = 0
  frames_captured = 0

  #creating a folder
  try:  
      # creating a folder named data 
      if not os.path.exists(outputFolder): 
          os.makedirs(outputFolder) 
    
  #if not created then raise error 
  except OSError: 
      print ('Error! Could not create a directory') 
  
  #reading the video from specified path 
  cam = cv2.VideoCapture(inputFile) 

  #reading the number of frames at that particular second
  frame_per_second = cam.get(cv2.CAP_PROP_FPS)

  while (True):
      ret, frame = cam.read()
      if ret:
          if currentframe > (step*frame_per_second):  
              currentframe = 0
              #saving the frames (screenshots)
              name = './data/frame' + str(frames_captured) + '.jpg'
              print ('Creating...' + name) 
              
              cv2.imwrite(name, frame)       
              frames_captured+=1
              
              #breaking the loop when count achieved
              if frames_captured > frames_count-1:
                ret = False
          currentframe += 1           
      if ret == False:
          break
  
  #Releasing all space and windows once done
  cam.release()
  cv2.destroyAllWindows()

0 commentaires