OpenCVで動画を再生させたり、動画のフレーム数を変えたり、フレームレート切り替えたり、、、
動画を切った貼ったやっていると、
あれ??今フレームレート想定通りになっているかな??遅くない??早くない??
と不安になることがあります。
動画を見比べて判断すればよいのですが、
ただの動画だと分かりにくい。。
ということで、自作でサンプル動画を作成してみることにしました。
ただ連番画像を動画にするだけだと画像作成面倒ですし、やりなれた方法ですので、
今回は、OpenCVのライブラリとして提供されている、
rectangleとTextを用いて、自作で動画を作成してみることにしました。
■作成した動画
今回自作できた動画はこちら。
ただ0~9までの数字を動かしているだけです。
フレームレートは10fpsで録画したものです。
■rectangle、putText関数の仕様
冒頭でも述べた通り、OpenCVのライブラリを用いて
長方形や文字を入れ込んでいきます。
OpenCVでは長方形や文字を入れるための関数として、
rectangle、putText関数があります。
まずrectangleですが、枠線や塗りつぶした矩形、長方形を描画できます。
こちらのように定義されており、
rectangle(Mat& img, Point pt1, Point pt2, const Scalar& color, int thickness=1, int lineType=8, int shift=0)
引数は、
img – 画像.
pt1 – 矩形の1つの頂点.
pt2 – pt1 の反対側にある矩形の頂点.
color – 矩形の色,あるいは輝度値(グレースケール画像).
thickness – 矩形の枠線の太さ. CV_FILLED などの負の値の場合,塗りつぶされた矩形が描かれます.
lineType – 枠線の種類. line() を参照してください.
shift – 点の座標において,小数点以下の桁を表すビット数.
となります。
※参考:描画関数 — opencv 2.2 documentation
次にputTextですが、文字列を画像上に描画することが出来、
こちらのように定義されております。
putText(Mat& img, const string& text, Point org, int fontFace, double fontScale, Scalar color, int thickness=1, int lineType=8, bool bottomLeftOrigin=false)
引数ですが、
img – 画像.
text – 描かれる文字列.
org – 文字列の左下角の,画像中の座標.
fontFace – フォントの種類.以下のうちの1つ. FONT_HERSHEY_SIMPLEX , FONT_HERSHEY_PLAIN , FONT_HERSHEY_DUPLEX , FONT_HERSHEY_COMPLEX , FONT_HERSHEY_TRIPLEX , FONT_HERSHEY_COMPLEX_SMALL , FONT_HERSHEY_SCRIPT_SIMPLEX , FONT_HERSHEY_SCRIPT_COMPLEX .また,各フォントIDを, FONT_HERSHEY_ITALIC と組み合わせて,斜体文字にすることもできます.
fontScale – フォントのスケールファクタ.これがフォント特有の基本サイズに掛け合わされます.
color – 文字列の色.
thickness – フォントの描画に利用される線の太さ.
lineType – 線の種類.詳細は line を参照してください.
bottomLeftOrigin – true の場合は画像データの原点が左下,そうでない場合は左上になります.
となります。
※参考:描画関数 — opencv 2.2 documentation
■rectangleとputTextを用いて動画を作成してみる
先ほど記載しました通り、rectangleやputTextでは座標を指定して描画しますので、
動いているように見せるためには座標をフレーム毎に変更させればOKです。
今回作成したコードはこちら。
import cv2 import numpy as np BASEPOS_WIDTH = 100 BASEPOS_HEIGHT = 100 HOLISONTALNUM = 4 VERTICALNUM = 4 LOOP_COUNT = 12 VIDEO_SIZE = (HOLISONTALNUM * BASEPOS_WIDTH,VERTICALNUM * BASEPOS_HEIGHT) FONT = cv2.FONT_HERSHEY_SIMPLEX outputFile = 'ImgVideo.mp4' fourcc = cv2.VideoWriter_fourcc('m','p','4', 'v') frameRate = 10.0 def MakeSampleVideo(): video = cv2.VideoWriter(outputFile, fourcc, frameRate, (VIDEO_SIZE)) imgNum = 0 count = 0 while True: white_img = np.zeros((VERTICALNUM * BASEPOS_HEIGHT, HOLISONTALNUM * BASEPOS_WIDTH,3), dtype='uint8') white_img.fill(255) for v in range(VERTICALNUM): for h in range(HOLISONTALNUM): left = BASEPOS_WIDTH * h right = BASEPOS_WIDTH * (h+1) top = BASEPOS_HEIGHT * v bottom = BASEPOS_HEIGHT * (v+1) white_img = cv2.rectangle(white_img,(left,top),(right,bottom),(0,0,0),2) cv2.putText(white_img,str(imgNum),(left+25,bottom-25),FONT,2,(0,0,0),3) #動画を見るだけならこちらを利用 # cv2.imshow('sample', white_img) # if cv2.waitKey(100) & 0xff == ord('q'): # break #動画を保存するとき video.write(white_img) if imgNum > (VERTICALNUM * HOLISONTALNUM - 2): imgNum = 0 else: imgNum+=1 if count > LOOP_COUNT: break else: count += 1 video.release() MakeSampleVideo()
まずベースとなる画像ですが、
white_img = np.zeros((VERTICALNUM * BASEPOS_HEIGHT, HOLISONTALNUM * BASEPOS_WIDTH,3), dtype='uint8') white_img.fill(255)
で作成した真っ白な画像になります。
画像サイズは、400px × 400pxです。
今回rectangle、putTextの描画位置を動かしている処理はこちら。
left = BASEPOS_WIDTH * h right = BASEPOS_WIDTH * (h+1) top = BASEPOS_HEIGHT * v bottom = BASEPOS_HEIGHT * (v+1) white_img = cv2.rectangle(white_img,(left,top),(right,bottom),(0,0,0),2) cv2.putText(white_img,str(imgNum),(left+25,bottom-25),FONT,2,(0,0,0),3)
BASEPOS_WIDTH、BASEPOS_HEIGHTはそれぞれ100pxで、
v、hは0~3が入ります。
上記パラメータを用いて、
left、right、top、bottomという、座標位置を算出。
これにより、
rectangleでは100px × 100pxの四角形を左上から右下へ順番に表示させることが出来ます。
putTextも同様に、左下の座標をleft,bottomで指定しております。
後は、一周だけだと寂しいので今回は10週数字が動くようにしました。
if count > LOOP_COUNT: break else: count += 1
ここはもう少し工夫すれば簡潔に書くことが出来るかも。
■最後に
今回はrectangleやputTextを用いて、OpenCVが用意するライブラリで描画した四角形や文字で動かし、
動画を作成してみました。
作ってみたけど、30fpsや60fpsにすると流石に早すぎて目が追えない。。
まぁ、低速であれば使い道はあるかな??
結局無駄なものを作ってしまったかも。。