OpenCV + opencv_contrib を iOS 向けにビルドする完全ガイド【opencv2.framework】【C++】

OpenCV for C++
📌 準備: OpenCV の環境構築がまだの方はこちら → C++ 環境構築ガイドC#(OpenCvSharp)セットアップ

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 プロジェクトへの組み込み

  1. opencv2.framework を Xcode プロジェクトにドラッグ&ドロップ
  2. Build PhasesLink Binary With Libraries に追加されていることを確認
  3. Build SettingsC++ Language DialectC++17 に設定
  4. Build SettingsC++ Standard Librarylibc++ に設定

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 SettingsExcluded 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)を開発しています。顔認証システムへの組み込み実績多数。

→ なりすまし判定SDK/APIの詳細を見る
→ API仕様書・サンプルコード

タイトルとURLをコピーしました