はじめに
最近画像処理をしっかりと勉強していこうと思い、まずはOpenCVを用いた画像処理を勉強しています。
そこで、OpenCVの本を利用してどのような前処理があるのかや専門用語などの理解を進めています。
画像処理用の開発環境は特に用意していないので、簡単に使えるGoogle Colablatory
を利用して学習を進めていますが、OpecCVとの親和性があまり良くないためか?書籍のコードではColab上では動かないことが多いです。
今回もColab上では想定通りに動かなかったことがあったため記事にしました。
問題
動画を読み込んで再生する処理を行います。
書籍をColabで動かせるように修正を行い以下のコードを実行しました。
import sys
import cv2
cap = cv2.VideoCapture('data/campus.mp4')
if not cap.isOpened():
print('Can not open video file')
sys.exit()
while True:
ret, img = cap.read()
if not ret:
break
cv2_imshow(img)
if cv2.waitKey(30) == 27:
break
cap.release()
すると以下のように1フレームずつが、出力されてしまいます。
本来であれば、1つのウィンドウ内でフレームが出力されなければ動画にはなりません。
解決方法
How to Capture and Play Video in Google Colab?こちらの記事に解決方法がありました。
from IPython.display import HTML
from base64 import b64encode
def show_video(video_path, video_width = 600):
video_file = open(video_path, "r+b").read()
video_url = f"data:video/mp4;base64,{b64encode(video_file).decode()}"
return HTML(f"""<video width={video_width} controls><source src="{video_url}"></video>""")
show_video(video_path)
このコードを実行することでColab上でも動画を再生することができます。
また、フレームの途中で前処理(2値化)して、動画を保存する処理を行ったところ、このコードでは再生できず、以下の記事を参考にし動かすことができました。
Google Colaboratory 上の cv2 で作成した動画を表示する
import cv2
# ビデオファイルを開く
cap = cv2.VideoCapture('./data/sample2.mp4')
# ビデオファイルの保存設定
rec = cv2.VideoWriter('./data/video_dst.mp4',
cv2.VideoWriter_fourcc(*"mp4v"),
30, (640, 480))
# ループ開始
while True:
# 1フレーム読み込み
ret, src = cap.read()
if not ret:
break
# グレースケールに変換
dst = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# 2値化
ret, dst = cv2.threshold(dst, 128, 255, cv2.THRESH_BINARY)
# 3チャンネルに変換
dst = cv2.cvtColor(dst, cv2.COLOR_GRAY2BGR)
# cv2_imshow(dst)
# 1フレーム書き込み
rec.write(dst)
# キー入力待機(30 ms)。Escキーで中断。
if cv2.waitKey(30) == 27:
break
rec.release()
!ffmpeg -i ./data/video_dst.mp4 -vcodec vp9 ./out.webm
from IPython.display import HTML
import base64
import io
def play(file_path):
video = io.open(file_path, 'r+b').read()
encoded = base64.b64encode(video)
return(HTML(data='''<video width="320" height="240" controls><source src="data:video/mp4;base64,{0}" type="video/mp4" /></video>'''.format(encoded.decode('ascii'))))
play('./out.webm')
また、フレームごとの前処理で
# ビデオファイルの保存設定
rec = cv2.VideoWriter('data/video_dst.mp4',
cv2.VideoWriter_fourcc(*'H264'),
30, (640, 480))
としていましたが、H264
だと動画の保存ができなかったため、mp4v
にしています。
おわりに
OpenCVを本格的に利用していくとなるとColabでは厳しいのかなとすこし思い始めました。画像処理を勉強したらそれ用の環境をつくろうかと思います。
Dockerでも書籍のコードは動かなそうと思うと大変そうです。
Colabの相性でつまずくことが多そうなので、またつまずいたら記事にまとめていきます。