OpenCV + opencv_contrib を iOS 向けにビルドする完全ガイド【opencv2.framework】
iOS アプリに OpenCV の拡張モジュール(opencv_contrib)を組み込みたいとき、CocoaPods で配布されている opencv2.framework には contrib モジュールが含まれていません。そのため、自前でビルドして opencv2.framework を生成する必要があります。
この記事では、Mac 上で OpenCV + opencv_contrib を iOS 向けにビルドし、Xcode プロジェクトに組み込むまでの手順を解説します。到達状態は次のとおりです。
opencv2.framework(contrib モジュール入り)がローカルに生成されている- Xcode の C++ ブリッジングコードから
cv::imread等を呼び出せる
前提環境
| 項目 | バージョン・備考 |
|---|---|
| macOS | 現行安定版(Apple Silicon / Intel 両対応) |
| Xcode | 現行安定版(App Store より取得) |
| Python | 3.x(ビルドスクリプトの実行に使用・システム Python 可) |
| CMake | 3.20 以上推奨(brew install cmake) |
| OpenCV | 4.x 最新安定版 |
| opencv_contrib | OpenCV と同一タグ |
⚠️ OpenCV 本体と opencv_contrib のタグ(バージョン)は必ず揃えてください。バージョン違いはビルドエラーの最大原因です。
手順
1. ソースコードの取得
OpenCV 公式 GitHub からソースを clone します。タグは OpenCV 本体と contrib で同じものを指定します。以下は 4.10.0 を例にしていますが、実際には公式リポジトリで現行の最新安定版タグを確認してください。
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git
cd opencv
git checkout 4.10.0
cd ../opencv_contrib
git checkout 4.10.0
cd ..
2. iOS 向けビルドスクリプトの確認
OpenCV リポジトリには iOS 向けのビルドスクリプトが同梱されています。
ls opencv/platforms/ios/
# build_framework.py が存在することを確認
build_framework.py が iOS 向け opencv2.framework を生成する公式スクリプトです。
3. ビルドの実行
build_framework.py に --contrib オプションで opencv_contrib のパスを渡します。
python3 opencv/platforms/ios/build_framework.py \
--contrib opencv_contrib \
--without dnn \
ios_build
主なオプション:
| オプション | 説明 |
|---|---|
--contrib <path> |
opencv_contrib のパスを指定(必須) |
--without <module> |
不要モジュールを除外してサイズ削減 |
--iphoneos_archs |
ターゲットアーキテクチャ(デフォルト: arm64) |
--iphonesimulator_archs |
シミュレータ向けアーキテクチャ(デフォルト: x86_64,arm64) |
--dynamic |
動的フレームワークとして生成(デフォルトは静的) |
⚠️
dnnモジュールはサイズが大きく、不要な場合は--without dnnで除外することを推奨します。自社 SDK でも contrib の必要モジュールに絞ることでビルド時間とバイナリサイズを抑えています。
ビルドには環境によって 30〜90 分程度 かかります。
4. 出力の確認
ビルドが完了すると、指定ディレクトリ(上記例では ios_build/)に以下が生成されます。
ios_build/
└── opencv2.framework/
├── opencv2 ← 静的ライブラリ本体(fat binary)
├── Headers/ ← C++ ヘッダー群
└── Info.plist
contrib モジュールのヘッダーが含まれているか確認します。例として aruco モジュールを確認する場合:
ls ios_build/opencv2.framework/Headers/ | grep aruco
5. Xcode プロジェクトへの組み込み
opencv2.frameworkを Xcode プロジェクトにドラッグ&ドロップBuild Phases→Link Binary With Librariesに追加されていることを確認Build Settings→C++ Language DialectをC++17に設定Build Settings→C++ Standard Libraryをlibc++に設定
Objective-C++ ブリッジングファイル(.mm 拡張子)から OpenCV を呼び出します。Swift プロジェクトの場合は Bridging Header 経由で .mm ファイルを用意します。
動作確認
ビルドが成功したことを確かめる最小の C++ コードを .mm ファイルに記述します。
#include <opencv2/opencv.hpp>
#include <iostream>
// iOS の Bundle からファイルパスを取得して imread を実行する例
// Objective-C++ (.mm) 内で呼び出す前提
bool testOpenCV() {
// 動作確認用: 100x100 の黒画像を生成してグレースケール変換
cv::Mat colorImg(100, 100, CV_8UC3, cv::Scalar(0, 128, 255));
if (colorImg.empty()) {
std::cerr << "[ERROR] Mat の生成に失敗しました" << std::endl;
return false;
}
cv::Mat grayImg;
cv::cvtColor(colorImg, grayImg, cv::COLOR_BGR2GRAY);
// グレースケール変換後のサイズ・チャンネル確認
std::cout << "rows: " << grayImg.rows
<< " cols: " << grayImg.cols
<< " channels: " << grayImg.channels()
<< std::endl;
// 期待出力: rows: 100 cols: 100 channels: 1
cv::Mat threshImg;
cv::threshold(grayImg, threshImg, 127, 255, cv::THRESH_BINARY);
std::cout << "[OK] OpenCV (contrib build) 動作確認完了" << std::endl;
return true;
}
Xcode でビルドし、コンソールに以下が出力されれば成功です。
rows: 100 cols: 100 channels: 1
[OK] OpenCV (contrib build) 動作確認完了
contrib モジュール(例: aruco)を使う場合は、同ファイルに #include <opencv2/aruco.hpp> を追加してコンパイルが通ることを確認します。
つまずきポイント
⚠️ OpenCV 本体と opencv_contrib のバージョンが一致していない
最も多いエラーです。clone 直後はデフォルトブランチ(main/4.x 等)の先端を指しているため、タグを明示的に checkout しないと両者のバージョンがずれます。ビルド途中に以下のようなエラーが出たらバージョン不一致を疑ってください。
CMake Error: The following variables are used in this project, but they are set to NOTFOUND
対処: 両リポジトリで git checkout <同一タグ> を実行してからビルドし直します。
⚠️ Apple Silicon Mac でシミュレータビルドが失敗する
Apple Silicon (M シリーズ) の Mac では、シミュレータが arm64 と x86_64 の両アーキテクチャを要求するケースがあります。Rosetta 2 を経由した x86_64 シミュレータが必要な場合は --iphonesimulator_archs x86_64,arm64 を明示します。また、Xcode の Build Settings → Excluded Architectures の設定と合わせる必要があります。
python3 opencv/platforms/ios/build_framework.py \
--contrib opencv_contrib \
--iphoneos_archs arm64 \
--iphonesimulator_archs x86_64,arm64 \
ios_build
⚠️ imread が iOS 実機で空 Mat を返す
iOS ではファイルシステムのパス規則が macOS と異なります。cv::imread に渡すパスは NSBundle.mainBundle.resourcePath 等で取得した絶対パスでなければなりません。相対パスや ~/ を含むパスは動作しません。
// NG: cv::imread("image.png")
// OK: cv::imread([bundle pathForResource:@"image" ofType:@"png"].UTF8String)
imread 直後に mat.empty() で必ずチェックし、空の場合はパスをログ出力して確認してください。
まとめ
| 作業 | コマンド・ポイント |
|---|---|
| ソース取得 | git checkout で本体・contrib のタグを揃える |
| ビルド実行 | build_framework.py --contrib でフレームワーク生成 |
| サイズ削減 | --without dnn 等で不要モジュールを除外 |
| Xcode 設定 | C++17 / libc++ を明示・.mm 拡張子で C++ を使用 |
| パス注意 | iOS での imread は Bundle 絶対パスを使用 |
contrib モジュールを含む opencv2.framework を自前でビルドすることで、ArUco マーカー検出や SIFT/SURF といった拡張機能を iOS アプリに組み込めます。Ubuntu 向けの contrib ビルド手順は OpenCV + opencv_contrib を Ubuntu でビルドする完全ガイド【C++】 も参考にしてください。
🛠 画像処理のプロが開発するSDK/API
本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

