お久しぶりでございます。scalaでバックエンドを開発しているaxtstar(@axtstart)です。
今回は、趣向を変えまして、エンジニアは家にかえってもやっぱり エンジニア だと思うので、 ご家庭にいらっしゃる時によくIT系の頼まれごとなんかをママ(パパ)からされたりすると思います。
特に、お子さんのいらっしゃる家庭ではだいたい、お子さんの動画の管理とか、ITに詳しいパパ(ママ)の役目であることが多いかと思います。
うちもご多分に漏れず、子供の動画が結構あって、samba上に置いて私が管理しています。
そんな管理の中で、まぁ私的に役に立ったアレコレを紹介してみます。
今回使うツールは動画を扱うならこれしかないツールの FFMpeg 、OpenCV です。
サンプルで以下の動画を使います
はい。娘が昔作った、自由工作みたいなやつです。。。
※本人の公開許諾済み
動画の時間切り取り
これは何に使うかというと、一連の長い動画を必要な部分だけ、切り取って扱いやすくします。
ffmpeg -ss 01:00 -i input.mp4 -t 05:00 -vcodec copy -acodec copy output.mp4
input.mp4を入力として、1:00から05:00間切り取ってoutput.mp4に出力する video audioのコーデックはコピー
こちら切り取りが早く終わる方法です。
どうも-ssと-iの位置関係には意味があるようで、逆にすると切り取られる場所がずれたりします。
コーデックの指定が異なると(デフォルト設定でも)、再デコード・エンコードが走るせいか、処理時間が長くなります。
運動会や音楽会など、とりあえず1ファイルで撮影していたが、それを分割して保存する場合など活躍するシーンが多いです。
動画の圧縮
これは何に使うかというと、ストレージ容量を節約するために動画の圧縮に使います。
ffmpeg -analyzeduration 30M -probesize 30M -i input.mp4 -c:v libx264 -crf 22 -c:a copy output.mp4
-crf 22・・・22の部分で品質を固定した圧縮を行なっています。
うちもなんだかんだいって、子供の動画のファイルで10年分ほどたまっていて、
生データのまま置いておくのは馬鹿にならない容量なので重宝しています。
動画のクロップ+水平反転
これは何に使うかというと、お遊戯や、劇を撮影したものを、注目する部分のみを拡大し、左右反転することで、子供がそれを見て同じ動作で練習するのに使います。
ffmpeg -i input.mp4 -vf crop=w=640:h=400:x=300:y=0,"hflip" output.mp4
開始位置x(よこ)=300、y(たて)=0、w(幅)=640、h(高さ)=300で切り取って、それを水平に反転(つまりミラー状態に)します。
画像がミラーになるので、画面の左手の動きに合わせて、左手、右手に合わせて右手を動かすというように、左右を対称で考える必要が無くなります。
こんな感じです。
OpenCVの前準備
OpenCVをContribと共にソースからビルドします。
cmakeのファイルを以下におきましたがバージョン・環境でどうもいろいろ試行錯誤した後なのでもしかしたらこれだけではダメかもしれません。
※実はこのビルドが一番苦労したところです。苦労しすぎて何が正解だったかまとめきれていません。。。
また、説明を簡単にするため、以下の雛形を用意しました。これはただ単に、動画のコピーを行うだけの処理ですが、
この下の説明で54行目のところの処理を変更することで、続く各処理をできるようにしています。
使い方: カラー動画が期待される場合
python opencv_simple.py -i input.mp4 -o output.mp4 -c
白黒動画が期待される場合(今回だと、画像のエッジ検出)
python opencv_simple.py -i input.mp4 -o output.mp4
上記の出力は動画のモーションのみのため、音声を別途抜き出し、
出力のoutput.mp4と音声ファイルを結合して再エンコードする必要があります。
これは下記のようにffmpegで作成してます。
ffmpeg -i input.mp4 -ab 128k sound.mp3 ffmpeg -i output.mp4 -i sound.mp3 output_w_sound.mp4
※今回のサンプルではこの処理はやっていません。
画像のエッジ検出
これは何に使うかというと、撮影した動画のエッジを検出して、輪郭のみの動画を作り、お遊戯や劇の練習に役立てようというのに使います。
conv_frame = cv2.Canny(frame, 100,200)
こんな感じです。
実は娘が劇団に入っており、そのダンスの練習に活用してもらおうかと画策中です。
動画のテキスト検出
これは何に使うかというと、タイトルのついた動画を文字認識し、例えばメタ情報として記録する、あるいは動画ファイルのタイトルにしてしまおうというのに使います。
文字認識にtesseract-ocrを使用しているため、ディレクトリに認識したい言語に応じた、学習済みのデータが必要です。
import pytesseract from PIL import Image# img = Image.fromarray(frame) text = pytesseract.image_to_string(img, lang='jpn') print(text) conv_frame = frame
今回の動画だとあまりいい結果ではなかったです。
一部貼り付けると、
ダ & に っ て ( く な ぅ し た と こ ろ . % て g し ぃ と こ ろ な ど 作 々 ミ テ ロ ェ ッ ま / | m&c っ u て < ぁ ぅ し と =a、 見 て mLu と こ ぁ な ら 佳 沼 ミロ ( に ェ ュ こ) ま り ェ ラ | s ズ は ⑧ Se _a〝哨麟}}〟 | 縄 い G 体 い い
何書いているかわからない。。。
うーん。手書き文字が結構入っているため、そのあたりかなり不利な動画を選んでしまったかもしれません。
動画の特徴点抽出(Akaze)
こちらは画像のエッジを検出してその場所を判定しています。
akaze = cv2.AKAZE_create() # find and draw the keypoints kp = akaze.detect(frame,None) cv2.drawKeypoints(frame, kp, frame) conv_frame = frame
何に使うかというと、、、現在試行中です。。
こちらAkazeは使用する際は作者の方が連絡をしてほしいとのことですのでここにもその旨記載しておきます。
最後の方はどんどん自分の興味のある方向に走ってしまい、 家庭の雑用をやっているというより遊んでるようにしか見られなくなるかもしれないのでそこは注意した方がいいですね。
最後になりましたが、弊社ではデザイナー・エンジニアを募集しております。 以下の採用サイトからご応募いただければと思います。