117
116

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2014-06-22

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のサンプルがごちゃごちゃ(前者が多い印象)なので、間違えないようにしましょう。
117
116
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
117
116

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?