iPhoneでOpenCVを使う方法

Posted by Yoshimasa Niwa on 03/14, 2009

OpenCVはIntelが開発したコンピュータビジョンのライブラリで、例えば顔検出などを簡単に行うことができます。 覚え書きとして、OpenCVをiPhone SDKをつかってiPhone上で使う方法を、ビルドスクリプトとデモアプリケーションつきでメモしておきます。 これらのサムネイルはデモアプリケーションのスクリーンショットです。

ひとまず使ってみる

すべてのソースコードとリソースはgithubのレポジトリに公開されています。 簡単に使えるように、事前にコンパイルしたOpenCVのライブラリとヘッダファイルを入れてあります。 すでにgitがあるなら、githubからレポジトリをcloneしてください。ない場合は、githubのdownloadリンクからzipかtarをダウンロードして解凍してください。

% git clone git://github.com/niw/iphone_opencv_test.git

ソースコードを手に入れたら、OpenCVTest.xcodeprojをXcodeで開いてビルドします。 デモアプリケーションがシミュレータと実機両方で動くことが確認できると思います。

OpenCVのライブラリをソースからビルドする

もちろんOpenCVのライブラリをソースからgccでクロスコンパイルすることもできます。 そのための補助スクリプトを追加してあります。 重要なことは、iPhone SDKはダイナミックリンク(.frameworkのような)に対応していない点です。 コンパイルするときには静的なライブラリを作成し、アプリケーションに静的にリンクする必要があります。

  1. OpenCVのソースコードをSourceForgeからダウンロードしてください。opencv-1.1pre1.tar.gzでテストしてあります。現状、その他のソースパッケージや、SVNのソースコードとは、この補助スクリプトはうまく動きません。

  2. OpenCVのソースコードをこのデモアプリケーションのディレクトリで展開してください。

    % tar xzvf opencv-1.1pre1.tar.gz
    
  3. 必要があれば、–prefixなどopencv_build_scripts/configure_*.shを自分の環境に合わせて編集してください。通常は必要ありません。

  4. iPhoneの実機むけにarmv6, iPhoneシミュレータむけにsimを指定して、以下の手順でビルドしてください。

    % cd opencv-1.1.0
    % mkdir build_(armv6またはsim)
    % pushd build_(armv6またはsim)
    % ../../opencv_build_scripts/configure_(armv6またはsim).sh
    % make
    % make install
    % popd
    

UIImageとIplImageの相互変換

OpenCVはIplImage構造体を処理に使いますが、iPhone SDKはUIImageオブジェクトを描画に使います。 つまり、これらのそうぞ変換が必要になるわけですが、ありがたい事にiPhone SDKのAPIで可能です。

IplImageをUIImageから作成するには、このようにします。

// NOTE 戻り値は利用後cvReleaseImage()で解放してください
- (IplImage *)CreateIplImageFromUIImage:(UIImage *)image {
  // CGImageをUIImageから取得
  CGImageRef imageRef = image.CGImage;

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  // 一時的なIplImageを作成
  IplImage *iplimage = cvCreateImage(
    cvSize(image.size.width,image.size.height), IPL_DEPTH_8U, 4
  );
  // CGContextを一時的なIplImageから作成
  CGContextRef contextRef = CGBitmapContextCreate(
    iplimage->imageData, iplimage->width, iplimage->height,
    iplimage->depth, iplimage->widthStep,
    colorSpace, kCGImageAlphaPremultipliedLast|kCGBitmapByteOrderDefault
  );
  // CGImageをCGContextに描画
  CGContextDrawImage(
    contextRef,
    CGRectMake(0, 0, image.size.width, image.size.height),
    imageRef
  );
  CGContextRelease(contextRef);
  CGColorSpaceRelease(colorSpace);

  // 最終的なIplImageを作成
  IplImage *ret = cvCreateImage(cvGetSize(iplimage), IPL_DEPTH_8U, 3);
  cvCvtColor(iplimage, ret, CV_RGBA2BGR);
  cvReleaseImage(&iplimage);

  return ret;
}

戻り値のIplImageは利用後にcvReleaseImageで解放することを忘れないでください!

UIImageをIplImageから作成するには、このようにします。

// NOTE IplImageは事前にRGBモードにしておいてください。
- (UIImage *)UIImageFromIplImage:(IplImage *)image {
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  // CGImageのためのバッファを確保
  NSData *data =
    [NSData dataWithBytes:image->imageData length:image->imageSize];
  CGDataProviderRef provider =
    CGDataProviderCreateWithCFData((CFDataRef)data);
  // IplImageのデータからCGImageを作成
  CGImageRef imageRef = CGImageCreate(
    image->width, image->height,
    image->depth, image->depth * image->nChannels, image->widthStep,
    colorSpace, kCGImageAlphaNone|kCGBitmapByteOrderDefault,
    provider, NULL, false, kCGRenderingIntentDefault
  );
  // UIImageをCGImageから取得
  UIImage *ret = [UIImage imageWithCGImage:imageRef];
  CGImageRelease(imageRef);
  CGDataProviderRelease(provider);
  CGColorSpaceRelease(colorSpace);
  return ret;
}

これでOpenCVをiPhoneで使うことができます!

よくある質問と答え

  • iPhoneシミュレータでは動くに、実機むけにビルドすると次のようなエラーがでてビルドできません。どうしたよいでしょう?

    ld warning: in /usr/local/lib/libcv.dylib, file is not of required architecture
    ld warning: in /usr/local/lib/libcxcore.dylib, file is not of required architecture
    Undefined symbols:
      "_cvCreateMemStorage", referenced from:
          -[OpenCVTestViewController opencvFaceDetect:] in OpenCVTestViewController.o
      "_cvGetSeqElem", referenced from:
          -[OpenCVTestViewController opencvFaceDetect:] in ......
    
    • すでにMacOS XむけのOpenCVをインストールしていませんか? このエラーはiPhone実機むけにコンパイルしたライブラリを使わずに既にインストールされているMacOSむけのライブラリを使おうとしてでるエラーです。 この問題を解決したバージョンをgithubにpushしました。既にダウンロードしている場合は更新してください。

最後に一言

OpenCVの顔検出はけっこう時間がかかります。 たとえば、iPhoneの画面サイズくらいの画像で、10秒かそれ以上かかってしまいます…う〜ん

ライセンス

このサンプルMIT Licenseで公開しています。

Meta

digg it! | b.hatena it!

Comments

  • bluestone007さんのコメント 06/21, 2009
    Good!
    Same paper here:

    http://www.computer-vision-software.com/blog/2009/04/opencv-vs-apple-iphone/comment-page-1/#comment-106
  • イグナチオさんのコメント 07/05, 2009
    この情報があると大変助かります、ありがとうございます!。opencvをダウンロードし解凍するとエラーがでますので、恐らく違うopencvのファイルだと思います。
    opencv-1.1pre1.tar.gz の具体的なリンクを教えていただけないでしょうか?
  • Yoshimasa Niwaさんのコメント 07/05, 2009
    > イグナチオ さん
    数日前のSourceforgeの改変で、ダウンロードリンクが変更になっており、Safariではダウンロードできなくなっています。opendv-1.1pre1.tar.gzはopencv-linuxの下にありますが、Firefoxを使うなどしてダウンロードしてください。
  • Keoさんのコメント 07/29, 2009
    Hi, Great stuff here. I was wondering if you got openCV's video capture api to work?
  • Dongpyo Hongさんのコメント 07/29, 2009
    It would be great if you share your sample code
  • Dongpyo Hongさんのコメント 07/29, 2009
    Whoops! You did ;-) I didn't realize the bottom link.
  • Yoshimasa Niwaさんのコメント 07/31, 2009
    > Keo san
    Hi, unfortunately OpenCV stuff doesn't support any iPhone specific functions includes Camera operations so far.

    > Dongpyo san
    Right! You can grab the sample from my github repository!
  • Tedさんのコメント 08/12, 2009
    助かったよ!

    Thanks for providing an example project for this! This is a big help.
お名前
メールアドレス
(任意)
ウェブサイト
(任意)
コメント