2011/04/03

Nintendo 3DSのARカードを認識させる

Youtubeに3DSのARゲームズのプレイ動画が載っていました。
ARゲームズは、ARカードをテーブルなどの上において、それを3DSで撮影して遊ぶものです。

面白そうだったので、OpenCVとWebカメラを使って真似してみようと思いました。

まずはARカードを任天堂のサポートサイトからダウンロード。6MBのPDFでした。
「カラープリンタで印刷してください」とPDFに記載されていましたが、我が家にはカラープリンタが無いのでセブンイレブンのネットプリントで印刷。ひとまずA4とA3のサイズで印刷しておきました。

ARゲームズ風のものを作るには、いろいろと必要な処理がありそうですが、
まずは撮影した画像からARカードの位置と中身を検出することからはじめます。

処理の流れ
1.テンプレートの画像(ARカード6枚分)から、SURF特徴量を計算してどこかに保存しておく
2.撮影した画像から四角形を検索。小さすぎる四角形は省いてしまう
3.検出した四角形(たいていは台形になっている)を、cvWarpPerspectiveを使用して長方形に投影する。
4.投影後のARカードの中身のSURF特徴量を計算。
5.6枚のテンプレート画像のSURF特徴量と比較して、一致するものが多いテンプレート画像を選ぶ。
6.画面右上に、テンプレート画像を表示する。



四角形を検出するところなどは、QRコード検出器とほとんど同じだったのでそれを再利用しました。
SURF特徴量の部分は、サンプルのfind_obj.cppを参考(というかほぼコピペ)にしました。

画像から四角形を検出するのは15ms程度でできるようなのですが、SURF特徴量の検出と比較の処理で60ms程度かかってしまいます。

ただ、一度ARカードを判別してしまえばあとはそのARカードの位置を追跡するだけなので、
SURF特徴量の処理は毎回行わなくてもよさそうです。10フレームごとでもよいかもしれません。

あとはcvFindExtrinsicCameraParams2とcvProjectPoints2を使って回転ベクトルと移動ベクトルを算出できれば、ほかの物体をARカード上に表示することもできる・・・かな?

ではまた。

#2011-11-26 追記
使ってない関数の削除・エラー処理追加。
ソースは別館に置いてあります。(20111125_ar.zip)

8 件のコメント:

  1. コードが見たいです!感動しました

    返信削除
  2. >>匿名さん
    ソースコードを下記サイトに置きました。
    https://sites.google.com/site/playwithopencv/other
    かなり適当なプログラムですが、ご自由にお使いください。

    返信削除
  3. ありがとうございました!

    fatal error C1083: include ファイルを開けません。'opencv2/imgproc/imgproc.hpp': No such file or directory
    というよくわからないエラーがでてきちゃいました><、頑張って消してみます!

    返信削除
  4. とても勉強になります。
    コードを拝見させていただきました。

    不躾ですが、少々質問させていただけますでしょうか
    まだYoutubeのようには動かせていないのですが、
    cvWarpPerspective が、コード上見当たりません。
    検出した四角形のうち小さいものを除いて、
    一枚ずつcvWarpPerspective した上でprocessSURF2を呼べばいいんでしょうか?

    返信削除
  5. >>匿名さん

    Youtubeの動画にある右上の画像は、テンプレートの画像(3DS_ARCards.png)からcvSetROIなどを使ってそのままコピーしただけのものです。

    processSURF2は、渡された画像からSURF特徴量を抽出し、テンプレートの画像のSURF特徴量と比較して、どの画像が一番近いかを判断する関数となってます。そのため、processSURF2に渡す画像は、検出した四角形を内包する長方形で切り取ったものにしてください(傾いたままの画像を放り込んでも大丈夫です)。

    実はYoutubeにアップしているバージョンのソースコードはどこかにいってしまい、アップしてあるのはいろいろといじったバージョンのものです。cvWarpPerspectiveは使わなくても検出に影響はあまり無いと思います。

    ソースを見直してみると非常に見づらいコードになってるので、少し整理したものを今度アップしたいと思います。

    返信削除
  6. 匿名(2番目の)です。
    いろいろと教えていただきありがとうございました。
    お蔭様で、カードの認識ができるようになりました。
    SURFを作るときに時間がかかっているのもわかったので、
    矩形をリサイズしてからSURFを作ればもっと早くなるだろうということも予想できます。
    矩形抽出のやり方を変えればいろいろなカードデザインにも対応できそうですね、
    OpenCVも矩形抽出もROIという概念もわからないまま始めましたが、なんとなくわかるようになってきました。

    返信削除
  7. 初めまして今SURF認識について学んでします
    このプログラムは大変参考になりますが、
    ソースコードからひらき、ビルドしても
    数多くのエラーが出てしまいます
    開発環境は
    OpenCV2.2 C++2010
    ですか?

    返信削除
  8. >>匿名さん
    ソースコードを修正したものをアップしておきました。
    開発環境はOpenCV2.3+Eclipse、OSはMacOSXとUbuntu11.10です。

    返信削除