フレーム番号を指定して、Jupyter上に動画を表示する
ありそうで、見つからなかったので、メモとして残す。
import cv2
from ipywidgets import HBox, IntSlider, Label, Output, interactive
from io import BytesIO
from PIL.Image import fromarray
from IPython.display import Image
import matplotlib.pyplot as plt
cap = cv2.VideoCapture('hoge.avi')
assert cap.isOpened(), 'Could not open video device'
cnt = cap.get(cv2.CAP_PROP_FRAME_COUNT)
frame_slider = IntSlider(min=0, max=cnt-1)
msec_label = Label()
def f(frame_idx=frame_slider):
cap.set(cv2.CAP_PROP_POS_FRAMES, frame_idx) # フレーム番号を指定
ret, frame = cap.read() # フレームを取得
msec_label.value = f"{cap.get(cv2.CAP_PROP_POS_MSEC):,.1f}ms" # 指定したフレームのmsを取得
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # OpenCVの画像はBGRなので、RGBに直す
# jpegとしてフレームを保存し、表示。
f = BytesIO()
fromarray(frame).save(f, "jpeg")
display(Image(data=f.getvalue()))
# matplotlib.pyplot.imshow を使うほうが簡単かも
# ただし、目盛等がついてくる
# plt.imshow(frame)
# plt.show()
# スライダーとラベルを画像の下にしたかったので、interactive のout(画像)のみを表示
w = interactive(f)
display(w.out)
display(HBox([frame_slider, msec_label]))