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.