web-dev-qa-db-fra.com

Est-il possible d'afficher une vidéo OpenCV dans le bloc-notes IPython/JuPyter?

Lors de l’exécution des exemples tirés des didacticiels de traitement vidéo Python pour OpenCV, ils apparaissent tous dans une fenêtre dédiée. Je sais que le bloc-notes IPython peut afficher des vidéos à partir du disque et de YouTube. Je me demande donc s'il existe un moyen de diriger la lecture vidéo OpenCV vers le navigateur Notebook et de la lire dans la cellule de sortie au lieu d'une fenêtre séparée (de préférence sans l'enregistrer). sur le disque puis en le jouant à partir de là).

Vous trouverez ci-dessous le code du tutoriel OpenCV.

import cv2

cap = cv2.VideoCapture('/path/to/video') 

while(True):
    # Capture frame-by-frame
    ret, frame = cap.read()

    # Our operations on the frame come here
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    # Display the resulting frame
    cv2.imshow('frame',gray)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
24
joelostblom

Les données vidéo encodées (si dans un format que le navigateur peut décoder, par exemple. Encodées en h264 dans un conteneur ISO mp4) peuvent être affichées à l'aide d'une balise HTML <video> et de IPython.core.display.HTML(), ceci fournira des performances de lecture standard.

Le <video> peut être un lien ou avoir des données incorporées en base64 (ce dernier est ce que matplotlib.animation fait, par exemple), et ses données peuvent bien sûr être générées dans votre bloc-notes, en utilisant OpenCV (par exemple, VideoWriter).

2
cJ Zougloub

Vous pouvez le faire avec Bokeh et c'est probablement un peu plus rapide.

from bokeh.plotting import figure
from bokeh.io import output_notebook, show, Push_notebook
import cv2
import time
output_notebook()

cap = cv2.VideoCapture(0)
ret, frame = cap.read()
frame=cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) # because Bokeh expects a RGBA image
frame=cv2.flip(frame, -1) # because Bokeh flips vertically
width=frame.shape[1]
height=frame.shape[0]
p = figure(x_range=(0,width), y_range=(0,height), output_backend="webgl", width=width, height=height)
myImage = p.image_rgba(image=[frame], x=0, y=0, dw=width, dh=height)
show(p, notebook_handle=True)
while True:
    ret, frame = cap.read()
    frame=cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
    frame=cv2.flip(frame, -1)
    myImage.data_source.data['image']=[frame]
    Push_notebook()
    time.sleep(0.3)
1
Enrico Pallazzo

Oui. Mais ce sera slooowwww ....

Code avec Python 3 et OpenCV 3.3 qui lit à partir de la webcam (à partir du fichier, changez simplement cv2.VideoCapture ("filename.mp4")):

from IPython.display import clear_output, Image, display, HTML
import numpy as np
import cv2
import base64

def arrayShow (imageArray):
    ret, png = cv2.imencode('.png', imageArray)
    encoded = base64.b64encode(png)
    return Image(data=encoded.decode('ascii'))
video = cv2.VideoCapture(0)
while(True):
    try:
        clear_output(wait=True)
        _, frame = video.read()
        lines, columns, _ =  frame.shape
        frame = cv2.resize(frame, (int(columns/4), int(lines/4))) 
        img = arrayShow(frame)
        display(img)
    except KeyboardInterrupt:
        video.release()

Vous devrez peut-être modifier la limite de débit de données IOPub . Vous pouvez modifier cela dans votre configuration .jupyter ou simplement exécuter Jupyter notebook --NotebookApp.iopub_data_rate_limit = 1000000000

L'interruption du clavier ne fonctionne pas correctement, cependant.

0
Fred Guth