OS X に OpenCV を Homebrew で入れて python で動画入出力をする

  • 123
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

OpenCVちょっと動かしたいなーと思って、macに気軽にインストールしてみたらはまったので、備忘録代わりにAVIファイルを表示させて保存するまでの記事です。

この記事で行うこと

  • OS X Mavericksに、Homebrew使ってOpenCVを導入
  • OpenCV2 + PythonでAVIファイルを読み込んで保存する

この記事でわからないこと

  • Homebrewのインストール方法

インストール

Homebrewは最新にしておきましょう。

pythonの環境は、pyenv系のバージョン切り替えて使う環境の場合、Homebrew経由のopencvインストールと相性が悪いようで、コンパイルが通りませんでした。

pyenvは諦めて、Homebrewからpythonをインストールする形にしています。
デフォルトのHomebrewにはOpenCVが用意されていないので、コンピュータサイエンス向けのライブラリのインストールが必要です。

参考1:Homebrew でOpenCVをインストールする方法

それではインストールと行きたいところですが、OpenCVを入れる前に動画を扱うためのあれこれをインストールしておきます。これをしないと静止画はいいのですが、動画を処理しようとしてエラーで悩みます。

参考2:virtualenvwrapperによるOpenCV + Python環境の構築 (2)
参考3:Mac OS XでFFmpegのインストールとWebM動画の作り方

pythonが入っていないところから始めると以下のようになります。
numpyが入っていないと、OpenCVのインストールが失敗することがあるので先に入れています。

ffmpeg周りはやや過剰かもしれません。とりあえずOpenCVについては、後でエラーが出ると嫌なのでオプション全部載せにしています。

$ brew tap homebrew/science
$ brew install python
$ pip install numpy
$ brew install cmake automake celt faac fdk-aac git lame libass libtool libvorbis libvpx libvo-aacenc opencore-amr openjpeg opus sdl schroedinger shtool speex texi2html theora wget x264 xvid yasm
$ brew install ffmpeg --with-fdk-aac --with-libvo-aacenc --with-libvorbis --with-libvpx --with-openjpeg --with-theora --with-opencore-amr
$ brew install eigen
$ brew install jasper
$ brew install tbb
$ brew install qt
$ brew install opencv --with-eigen --with-jasper --with-libtiff --with-qt --with-tbb --with-ffmpeg

OpenCVのコンパイルにやたら時間がかかりますが(MacBookAir環境で10分ぐらい)、気長に待ちましょう。

動画(AVIファイル)を表示する

詳解OpenCVのサンプルで、AVIファイルを読んで画面にスライダー(トラックバー)付きで表示する例がありますので、これをPythonで実装します。

example2-3.py
# coding: UTF-8
import numpy as np
import cv2

# 実装の参考 http://www.beechtreetech.com/opencv-exercises-in-python
# cv2を使うように変更

updatelock = False # トラックバー処理中のロックフラグ
windowname = 'frame' # Windowの名前
trackbarname = 'Position' # トラックバーの名前

# AVIファイルを読む
# aviは適当な長さのサンプルをインターネットから拾ってくる
# 参考:http://www.engr.colostate.edu/me/facil/dynamics/avis.htm
cap = cv2.VideoCapture('drop.avi')

# トラックバーを動かしたときに呼び出されるコールバック関数の定義
def onTrackbarSlide(pos):
    updatelock = True
    cap.set(cv2.cv.CV_CAP_PROP_POS_FRAMES, pos)
    updatelock = False

# 名前付きWindowを定義する
cv2.namedWindow(windowname, cv2.WINDOW_NORMAL)

# AVIファイルのフレーム数を取得する
frames = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))

# フレーム数が1以上ならトラックバーにセットする
if (frames > 0):
    cv2.createTrackbar(trackbarname, windowname, 0, frames, onTrackbarSlide)

# AVIファイルを開いている間は繰り返し(最後のフレームまで読んだら終わる)
while(cap.isOpened()):

    # トラックバー更新中は描画しない
    if (updatelock):
        continue

    # 1フレーム読む
    ret, frame = cap.read()

    # 読めなかったら抜ける
    if ret == False:
        break

    # 画面に表示
    cv2.imshow(windowname,frame)

    # 現在のフレーム番号を取得
    curpos = int(cap.get(cv2.cv.CV_CAP_PROP_POS_FRAMES))

    # トラックバーにセットする(コールバック関数が呼ばれる)
    cv2.setTrackbarPos(trackbarname, windowname, curpos)

    # qを押したら抜ける
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# AVIファイルを解放
cap.release()

# Windowを閉じる
cv2.destroyAllWindows()

OpenCVのインストールが正常であれば、実行時にエラーが出ずに、Windowが開いて動画が表示されます。
最後まで行くと自動的に終わります。トラックバーを操作するとその場面から続きが再生されます。

example2-3.png

カメラの映像を動画(AVIファイル)で保存する

次は、Mac内蔵のカメラを使って、カメラ映像をそのまま動画保存するサンプルです。

example_cam.py
# coding: UTF-8
import numpy as np
import cv2

# カメラからのキャプチャ指定
cap = cv2.VideoCapture(0)

# コーデックの指定
fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v') 

# 保存ファイルとフレームレートとサイズの指定
out = cv2.VideoWriter('output.m4v',fourcc, 30, (640,480))

# カメラオープン中はずっと処理する
while(cap.isOpened()):

    # キャプチャ画像を取り出す
    ret, frame = cap.read()

    # データがなければ抜ける
    if ret==False:
        break

    # 画像をファイルに書き込む
    out.write(frame)

    # 画像を画面に出力する
    cv2.imshow('frame',frame)

    # "q"が押されたら抜ける
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 後始末
cap.release()
out.release()
cv2.destroyAllWindows()

画面上に、カメラからの映像が出力されます。また、同時にファイルに書き込みも行われています。
出力ファイルは、m4v形式でmacから直接読めるので、再生されるかどうか試してみましょう。

動画にフィルタをかける

最後はOpenCVらしく、読み込んだ動画にフィルタをかけてみましょう。元のaviファイルを入力、処理結果後の画像を出力情報として、どちらも画面上に表示されるようにしています。

example2-6.py
# coding: UTF-8
import numpy as np
import cv2
import cv2.cv as cv

updatelock = False # トラックバー処理中のロックフラグ
windowname_in = 'inframe' # Window(元画像)の名前
windowname_out = 'outframe' # Window(変換画像)の名前
trackbarname = 'Position' # トラックバーの名前

# AVIファイルを読む
cap = cv2.VideoCapture('drop.avi')

# トラックバーを動かしたときに呼び出されるコールバック関数の定義
def onTrackbarSlide(pos):
    updatelock = True
    cap.set(cv.CV_CAP_PROP_POS_FRAMES, pos)
    updatelock = False

# Cannyエッジ検出
def doCanny(img):
    # カラー画像をグレー画像に変換
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    return cv2.Canny(gray, 100, 200)


# 名前付きWindowを定義する
cv2.namedWindow(windowname_in, cv2.WINDOW_NORMAL)
cv2.namedWindow(windowname_out, cv2.CV_WINDOW_AUTOSIZE)

# AVIファイルのフレーム数を取得する
frames = int(cap.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))

# フレーム数が1以上ならトラックバーにセットする
if (frames > 0):
    cv2.createTrackbar(trackbarname, windowname_in, 0, frames, onTrackbarSlide)

# AVIファイルを開いている間は繰り返し
while(cap.isOpened()):

    # トラックバー更新中は描画しない
    if (updatelock):
        continue

    # 1フレーム読む
    ret, frame = cap.read()

    # 読めなかったら抜ける
    if ret == False:
        break

    # 画面に表示
    cv2.imshow(windowname_in,frame)
    cv2.imshow(windowname_out,doCanny(frame))

    # 現在のフレーム番号を取得
    curpos = int(cap.get(cv.CV_CAP_PROP_POS_FRAMES))

    # トラックバーにセットする(コールバック関数が呼ばれる)
    cv2.setTrackbarPos(trackbarname, windowname_in, curpos)

    # qを押したら抜ける
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# AVIファイルを解放
cap.release()

# Windowを閉じる
cv2.destroyAllWindows()

動画のエッジを検出して、outframeのWindowに表示します。

example2-6.png

まとめ

  • OpenCV + Pythonは気軽に静止画、動画を表示、加工できるのでちょっと試すのに便利です。
  • 動画の入出力の最初で詰まると面白さ半減なので、ちゃんと動く事を確認しましょう。
  • インターネット上には、OpenCV1 + Pythonのサンプルと、OpenCV2 + Pythonのサンプルがごちゃごちゃ(前者が多い印象)なので、間違えないようにしましょう。