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 さんより下記のようなご助言をいただき、
https://t.co/W4jD2OaKtO を読むとわかりますがbuild_framework.pyの--contribオプションでopencv_contribのパス指定するだけでいけますね. https://t.co/XO371cnHnf
— dandelion (@dandelion1124) 2015, 5月 10
次のようにビルドスクリプトを実行してみました。
$ 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 利用方法
単体で利用するとエラーになるので、
@shu223 どうも公式側でopencv_contribを有効にした形でのiOS向けframeworkにバグがあることを認識出来ていない可能性があるのでticket発行したいと思います!(私もframeworkがビルドできたので安心してました・・・)
— dandelion (@dandelion1124) 2015, 5月 10
諦めて前述の力技でビルドした方を使うか、と思っていたところ、dandelion さんより以下のツイート。
@shu223 よくよく考えるとcontribオプションありなしでビルドした2つのフレームワークをインポートするという使い方な気がしてきました。帰ってから試してみます。
— dandelion (@dandelion1124) 2015, 5月 10
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生成方法について まとめました. opencv_contribを有効にしたopencv2.framework(for iOS)生成方法 https://t.co/SO0hs8xODW
— dandelion (@dandelion1124) 2015, 8月 23
opencv_contribを有効にしたopencv2.framework(for iOS)生成方法 · atinfinity/lab Wiki