IkaLogの裏側~「スプラトゥーン」のリアルタイム画像解析はどのように行われているのか

第3回 「ニコ生主でもつかえるIkaLog」を目指してのWindows対応

この記事を読むのに必要な時間:およそ 5.5 分

前回は,IkaLogの画像処理の基本的な考え方,また,その背景などについて紹介しました。今回は,IkaLogの公開に向けてどのような取り組みを行ったかについて紹介します。

Windows環境では「コンパイル済みのOpenCV,NumPy配布物」を活用

当初から今まで,IkaLogの開発はMacOS X環境で行っています。しかし,Wii Uの画面をキャプチャできるHDMIキャプチャデバイスの多くはWindows向けの製品です。私自身も,当初はWindows向けのHDMIキャプチャデバイスしか持っておらず,Windows環境で録画したスプラトゥーンのビデオファイルやスクリーンショットを使って開発していました。このため,まずは「書いたコードをWindowsで動かす」という課題に取り組むことにしました。

OpenCVのコンパイルは,とくにWindows上では大変な作業になります。PythonからOpenCVを使いたいだけなのに,OpenCVをコンパイルする過程でVisual Studioの特定バージョンも必要になります。IkaLogを使うためにそこまで準備の手間はかけられません。

私自身もOpenCVのコンパイルに時間を費やしたくはないのに,IkaLogのユーザーとして想定される方(ゲーム好きな人々)がPythonやOpenCVを自前でコンパイルできることは想定しづらいです。このため,Windows上でIkaLogの実行できる環境は,Python本家のバイナリ配布物,および有志の方が公開しているWindows向けOpenCVバイナリなどを利用して構築できるようにしようと考えました。

調べていたところ,下記サイトでさまざまなPython向けのライブラリをコンパイルしたものが用意されているので,こちらから必要なコンパイル済みファイルを取得してもらうことにしました。私が使っているWindows版IkaLogの開発/ビルド環境でも,このサイトで提供されているモジュールを用いています。

こちらのサイトで配布されているNumPyは,大量の演算処理を高速に行えるIntel Math Kernel Library(MKL)とリンクされています。このIntel MKLがNumPyを高速化しており,IkaLogの認識アルゴリズムが原始的で計算量が最適化されていなくても,今時のコンピュータではさくさくっと動いてしまう理由だったりします。

映像のキャプチャはどうやって実現する?

先の配布サイトなどからPython,OpenCV,そしてNumPyをそろえてIkaLogのコードを実行したところ,それまでに開発したコードはあっけないほどかんたんに,そのまま期待どおり動作しました。開発当初から使用していたビデオファイルも無事に処理でき,IkaLogがWindows環境でも利用できることが確認できました。

しかし,この時点ではHDMIキャプチャデバイスとの連携については考慮しておらず,使えるのは事前に録画されたビデオファイルのみでした。IkaLog開発をはじめてから数週間は「画像認識」というコンセプトで機能の実装に取り込んできたわけですが,それらがひと段落したため,実際のユースケースとして「Wii Uからのビデオ信号をリアルタイムに処理する」ためにはどうしたらいいか,検討を始めました。

当初の作戦は,FFmpegなど,DirectShowの入力デバイスからビデオストリームを拾えるソフトウェアからパイプなどの仕組みで映像データをもらうことを想定していました。こうすれば,面倒そうなビデオキャプチャデバイスのハンドリングを,実績がある既存のソフトウェアに任せられるだろうと考えたからです。「この作戦がダメな場合には,PythonからDirectShowなどを直接制御する必要があるかもしれない」ということは考えていました。

OpenCVでビデオキャプチャに成功

そんなことをぼんやり考えながら,OpenCVにもビデオキャプチャを行うVideoCapture機能があることを思い出し,これが利用できるか検討をはじめました。OpenCVは映像処理に使われるさまざまな機能を持ったライブラリですが,その中にWebカメラなどから映像をキャプチャ入力する機能としてVideoCaptureが含まれています。

「動いたらラッキー」ぐらいの気持ちで,VideoCaptureの機能を使ってHDMIキャプチャデバイスを操作してみたところ,手元HDMIキャプチャデバイスは以下のようなシンプルなコードで画像を間欠的に取得できることがわかりました。

#!/usr/bin python
# -*- coding: utf-8 -*-

import cv2

# キャプチャデバイスの番号(1つ目のデバイス=0,2つ目=1, ...)
source_device = 0

# OpenCVライブラリのVideoCaptureを初期化し,
# 入力フォーマットを1280x720に設定
cap = cv2.VideoCapture(source_device)
cap.set(3, 1280)
cap.set(4, 720)

# ESC キーが押下されるまで,入力されたキャプチャ映像を表示
while cv2.waitKey(1) != 27:
    r, img = cap.read()

    if not r:
        continue

    cv2.imshow('img', img)

 OpenCVによるキャプチャの例

図 OpenCVによるキャプチャの例

OpenCVのVideoCaptureは,コンピュータビジョンの研究開発において,USBカメラなどからの映像入力を目的として利用されることがほとんどでしょう。しかし,USBカメラもHDMIキャプチャデバイスも,OpenCVからすればカメラデバイスの実装の1つにすぎないので,究極的にはそのまま使えるわけです。

実際には,OpenCVのビデオキャプチャ機能がデバイスと相性問題を起こしやすいこともわかっており,この方法では動作しないHDMIキャプチャデバイスがいくつも存在します(この件については,今後の回で触れたいと思います)。しかし,IkaLogの最初のバージョンとしては「少なくとも動く構成がある!!」というだけでも十分だと判断し,最初のバージョンではOpenCVのVideoCaptureを介した入力のみをサポートすることにしました。もし,手元のHDMIキャプチャデバイスとOpenCV VideoCaptureの相性がよくなければ,IkaLogは手元でコンセプト止まりになり,公開まで至っていなかったかもしれません。

この実装上の制約により,「IkaLogで使用できるHDMIビデオキャプチャデバイスは少数に限られるだろう」と考えていました。しかし,IkaLog公開後,実際に試してくださったユーザーの方が,アマレコTVというソフトウェアと組み合わせられる」ことに気づき,その旨を教えていただきました。これは,「特定のビデオキャプチャデバイスしか使えない」と思っていたIkaLogが「アマレコTVを併用すれば,ほとんどのキャプチャデバイスで利用できる」ということであり,私の当初想定より広い環境でIkaLogを動作しうる,ということを意味します。このアマレコTVという優れたソフトウェアが存在していなければ,IkaLogはここまで使ってもらえるようにはならなかったでしょう。

著者プロフィール

長谷川猛(はせがわたけし)

(株)SRAで7年間のシステム構築&提案を経験したのち,Fusion-ioのセールスエンジニアを経て,フリーランスエンジニアとして活動中。『LDAP Super Expert』(技術評論社)に寄稿したほか,『Xen 徹底入門』(翔泳社)および『萌え萌えうにっくす!UNIX ネットワーク管理ガイド』(毎日コミュニケーションズ)の共著者のひとりである。

スノーボード,ごまラーメン,飼い犬のミニチュアシュナウザー「ラピス君」が大好き。

コメント

コメントの記入