Edited at

OpenCV 3.0 の拡張モジュール群 opencv_contrib を iOS で利用する

More than 3 years have passed since last update.

OpenCV 3.0 で、SIFT / SURFといった局所特長量抽出アルゴリズムを利用したくて、

公式チュートリアルのここを見てたら、

#include "opencv2/xfeatures2d.hpp"

とあるものの、そんなヘッダは手元の opencv2.framework にはない。。

調べてみると、OpenCV 3.0 では SIFT/SURF などのモジュールは "extra modules" として以下の別リポジトリで管理されてる模様。


公式に説明されている opencv_contrib のビルド方法

opencv_contrib リポジトリの README では、"How to build" として次のような方法が書いてありました。

$ cd <opencv_build_directory>

$ cmake -DOPENCV_EXTRA_MODULES_PATH=<opencv_contrib>/modules <opencv_source_directory>
$ make -j5

cmake の引数にオプションで opencv_contrib のパスを渡してビルドしましょう、とのこと。


iOS で用いるにあたっての問題

ただ、iOS向けフレームワークをビルドする場合、直接 cmake コマンドをたたいてたわけじゃなくて、次のようにあらかじめ用意されている python スクリプトを実行してたわけです。

python opencv/platforms/ios/build_framework.py ios

じゃあこのスクリプトをいじって cmake 実行時にオプション渡すようにするかー、と思って中身を見てみたけどけっこう複雑。。

cmake の勉強とかはまたの機会でいいので、今は手っ取り早くビルドしたい・・・どうしたものか・・・


解決方法その1: 全部入りフレームワーク作成

こういう記事が見つかりました。


You can just copy the wanted modules to the modules folder inside opencv source folder, and then run build_framework.py as usual. If everything is OK, this will produce the customized framework after a few minutes.


使いたい contrib モジュールのソースを opencv/modules フォルダにコピーしてビルドスクリプトを実行する という力技。

さすがにもうちょいスマートな方法はないものか、と探してみると OpenCV のフォーラムでも同様の回答。


But inferring from the cmake file, you can copy the module you want (ximgproc in your case) to opencv/modules. Then run build_framework.py as usual.


じゃあこれでいいか、ということで opencv_contrib/modules 配下のソースを全部 opencv/modules にコピーし、スクリプト実行 → 無事 全部入りフレームワーク が生成されました。


解決方法その2 contrib オプションを利用

本記事を書いてから『OpenCVプログラミングブック』の著者である @dandelion1124 さんより下記のようなご助言をいただき、

次のようにビルドスクリプトを実行してみました。

$ python opencv/platforms/ios/build_framework.py --contrib ./opencv_contrib ios

すると、

CMake Error at cmake/OpenCVUtils.cmake:764 (add_library):

Cannot find source file:

{実行パス}/ios/build/iPhoneOS-armv7/modules/xfeatures2d/opencl_kernels_xfeatures2d.cpp

というエラーが出てスクリプトが止まります。

同様のエラーで困っている人はいるようですが、

ここに書かれているように -DBUILD_opencv_contrib_world オプションをOFFにしてみたり削除してみたりしてみてもダメ、そもそも opencl_kernels_xfeatures2d.cpp なんてファイルは GitHub どころか web のどこにもない。。

諦めようかと思った矢先、ふと思いついて出力先である ios フォルダを削除して再度ビルドスクリプトを実行してみたところ・・・うまくいきました!

build フォルダに生成されるファイル群がキャッシュとして使われていたようです。

ちなみに contrib オプションを利用すると、生成されるフレームワーク名は "opencv2_contrib.framework" になります。


opencv2_contrib.framework 利用方法

単体で利用するとエラーになるので、

諦めて前述の力技でビルドした方を使うか、と思っていたところ、dandelion さんより以下のツイート。

contrib オプションありなしの2つのフレームワークを用意して下記のように試してみると、

#import <opencv2/opencv.hpp>

#import <opencv2/videoio/cap_ios.h>
#import <opencv2_contrib/xfeatures2d.hpp>
using namespace cv;
using namespace cv::xfeatures2d;

ビルドが通って処理もうまくいきました!

が、実は xfeatures2d.hpp の

#include "opencv2/xfeatures2d/nonfree.hpp"

というところでエラーが出たので、手動で

#include "opencv2_contrib/xfeatures2d/nonfree.hpp"

と修正して使用しました。結局、これを自動化するようにビルドスクリプトを修正する必要はありそうです。


解決方法その3

またも @dandelion1124 に情報提供いただきました。(2015.8.23)

opencv_contribを有効にしたopencv2.framework(for iOS)生成方法 · atinfinity/lab Wiki