When running the examples from the OpenCV video processing python tutorials, they all pop up in a dedicated window. I know that the IPython notebook can display videos from disk and YouTube, so I wonder if there is a way to direct the OpenCV video playback to the Notebook browser and have it play in the output cell instead of a separate window (preferably without saving it to disk and then playing it from there).
Below is the code from the OpenCV tutorial.
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()
How do you view videos on a Jupyter Notebook? To display local video files in the Jupyter notebook, we should use an Html video tag ( <video ), and set the base64 encoded video file content to the src attribute of the Html video tag ( <video .. src='data:video/x-m4v;base64, ' ).
Type the command “pip install opencv-python” to install python lib You should see 'Successfully installed' to finish installing opencv-python. 7. Use Jupyter notebook to run python code Open the Windows Start menu in your Desktop, click “Anaconda3 (64-bit)”, and then click “Jupyter Notebook(anaconda3)”.
It uses the power of the WebRTC browser API to allow video streaming inside of the Jupyter Notebook. The API of ipywebrtc is very simple: first, the user would create what we call a MediaStream widget.
You can do it with Bokeh and probably it is a bit faster.
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)
To make the display faster use only IPython.display.display
inside the notebook and JPG format instead of PNG. (Note displaying with cv2.imshow
natively outside the notebook is much faster, but this is not what the question asks for):
The code below will test all the supported file formats to find the fastest one (extracted from __doc__
with a regex, not reliable)
from IPython.display import clear_output, Image, display, HTML import cv2 # Read one frame from the camera for testing video = cv2.VideoCapture(0) _, frame = video.read() video.release() import re from timeit import timeit import math extensions=re.findall(r"\\\*(\.\w*)", cv2.imread.__doc__) def test(extension): try: totalTime=0 numTry=3 for _ in range(numTry): totalTime+=timeit(lambda: display(Image(data=cv2.imencode(extension, frame)[1])), number=1) clear_output(wait=True) return totalTime/numTry, extension except cv2.error as e: #usually "unsupported file type" return (math.inf, extension, e) for x in sorted( [test(extension) for extension in extensions], key=lambda x: x[0] ): print(x)
In my case, .jpeg
is the fastest. Make sure that the browser display also support that extension:
Image(data=cv2.imencode(".jpeg", frame)[1].tobytes())
Then, to play the video:
import cv2 from IPython.display import display, Image video = cv2.VideoCapture(0) display_handle=display(None, display_id=True) try: while True: _, frame = video.read() frame = cv2.flip(frame, 1) # if your camera reverses your image _, frame = cv2.imencode('.jpeg', frame) display_handle.update(Image(data=frame.tobytes())) except KeyboardInterrupt: pass finally: video.release() display_handle.update(None)
update
is a little faster than clear_output
+ display
every time; however compare to the rendering it isn't a significant improvement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With