Developer's Blog

OpenCV 3.2 を Swift のプロジェクトで使って簡単な画像処理をしてみよう!

アプリケーション共同開発部のオスカルです。 iOS エンジニアをやっています。

「次の iOS のため Apple が AR と VR の研究をしている」という噂を聞いたことがあります。みなさんもデジタル世界と現実世界の壁を壊す技術に興味があるのではないでしょうか。理由と関わらずコンピュータビジョンがこれからもっと大事になると考えられます。

現在、たくさんの AR と VR のフレームワークが存在しています。このブログにもこのような記事が投稿されています。

次世代の AR を体験! Tango をはじめよう

Amazon Rekognition の実力を試す

の技術の裏で実際何が起こっているか興味がある方は OpenCV (Open Computer Vision) を使って見てください!

OpenCV は C/C++ で書いているライブラリですが C++, C, Python と Java のインタフェースもあります。これは直接 Swift で使えないということです。Swift のプロジェクトで使えるように C++ を Objective-C++ にラップして Bridging-Header を使わないといけないです。

 

今日はこの使い方を紹介します。

実装:

  • 最初に公式サイトから “OpenCV iOS Pack” をダウンロードしてください。この記事では 3.2 版を使うけど 3.x ならどれでも使えると思います。2.x を使う場合は、ヘッダーパスが変わるので気をつけてください。

    OpenCV Official Site

  • “opencv2.framework” のファイルをプロジェクトフォルダにドラッグして、

  • “Copy items if needed” をチェックしてください。

 

  • OpenCV の C++ を書くための “Cocoa Touch Class” のラッパーを作りましょう。(必ず Objective-C の言語を選択してください)

    File → New → File ( ⌘ N)

    次の画面:

    このタイミングで Xcode から「Objective-C のブリッジヘッダーも作りたい?」を聞かれています。“Create Bridging Header” のボタンを押してください。


    ∗ “Bridging Header” は特別なファイルです。このファイルで書いている Objective-C ヘッダーに定義されているクラスなどを Swift で使うことができます。

  • この前作った “OpenCVWrapper.h” をブリッジヘッダーに追加してください。
  • Objective-C++ を使いたい場合はただファイルを “.mm” に変更しないといけないです。

    “OpenCVWrapper.m”→ “OpenCVWrapper.mm”

    ∗ Objective-C++ のファイルで Objective-C と C++ を使えます。

  • “OpenCVWrapper.mm” に OpenCV のヘッダーを追加してください。

    重点) “<opnecv2/opencv.hpp>” のヘッダーは他の Apple のヘッダーの前に追加する必要があります。この例では “OpenCVWrapper.h” に Apple のヘッダーが含まれています。そうしないとこのメッセージが出てきます。

使い方:

Objective-C で書いているメソッド:

Swift で使いたい時:

画像処理:

iOS のカメラから OpenCV の処理まで二つの方法があります。

1)自分で AVFoundation と AVCaptureVideoDataOutputSampleBufferDelegate を実装して、データを OpenCV が使えるフォーマットに変換します。

      + 細かいことを設定できる。

      – 難しい

2) OpenCV のカメララッパー (videoio) を使います。

∗ 自分で実装するのは簡単なことではないので今回は 2) の OpenCV のカメララッパーを使う方法を紹介します。もし絶対に自分で実装しないといけない要件があったら OpenCV の Github リポジトリの例を見ることができます。

画像処理の実装:

  • UIImageView を作って IBOutlet で View Controller につなげてください。


    ∗ カメラを使うのでアプリの “info.plist” に “Privacy – Camera Usage Description” の追加を忘れないでください。

  • 次のフレームワークをプロジェクトに追加してください。
    – Accelerate
    – AssetsLibrary
    – AVFoundation
    – CoreGraphics
    – CoreImage
    – CoreMedia
    – CoreVideo
    – QuartzCore
    – UIKit
    – Foundation
  • “<opencv2/videoio/cap_ios.h>” ヘッダーを “OpenCVWrapper.mm” に import してください。
  • “CvVideoCamera” 型のメンバー変数を作って、“CvVideoCameraDelegate” プロトコルを implement してください。

    ∗ “namespace” を使っているので “cv::CvVIdeoCamera” を書かなくていいです。
  • “CvVideoCamera” を初期化するためのメソッドを作ってください。

    ここで書いている設定を自由に変えて見てください。
    大事なポイントは:
    – Session Preset を大きい値にすると画像処理が遅くなります。
    – Grayscale Mode を YES にするとデリゲートが渡す “Mat” のフォーマットも変わります。
  • View Controller で今作ったメソッドを使ってください。
  • カメラをスタートするためのメソッドを作って、View Controller で呼び出します。

    OpenCVWrapper.h:

    OpenCVWrapper.mm:
  • 実際の画像処理は “- (void) processImage: (cv::Mat&) image” で行なっています。

    – Mat は画像の情報と画像のピクセルを持っています。
    – 自前で iOS のカメラ画像を OpenCV で処理する場合、カメラ画像のピクセル形式 (RGB) と OpenCV のピクセル形式 (GBR) とのあいだに違いがあるので変換する必要がありますが、今回のように CvVideoCamera と CvVideoCameraDelegate を使用すればピクセル形式は自動的に変換されます。
    – この例では、単純なビット反転を実行しています。
  • 結果はこのようになります:

ついに Swift のプロジェクトで OpenCV を使えるようになりました。OpenCV を使って色々を試してみてください!

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.