[C++] 27 FLTKとOpenCV併用時のトラブル対応 M1 Mac

[M1 Mac, Big Sur 11.6.5, FLTK 1.3.8, OpenCV 4.5.5]

FLTKアプリにOpenCVの画像リサイズ機能を導入する際、トラブルが発生しました。何とか解決できたので、記録として残しておきます。OpenCVはHomebrewからインストールしています。

タイムリーなことに英語版Stack Overflowに本日付で解決例が投稿されていました。この内容と他の記事との合わせ技で解決できました。

Apple Silicon MacでOpenCVをフルに使えなくて困っていた方々には朗報でしょう。

トラブル1:
コンパイル時にFLTKのmath.hが存在しない/usr/include/math.hを読み込もうとしてfile not foundエラー発生。

原因:以下の流れです。
1.OpenCVがmath.hにアクセスしようとしている。
2.-Iオプションで指定されているFLディレクトリのmath.hに優先アクセスする。
3.FL/math.hは/usr/include/math.hをインクルードしようとする。
4.ファイルがないのでエラー発生。

解決策:
以前のXCodeは/usr/includeディレクトリにヘッダファイルを置いていました。FL/math.hのインクルード先を標準のmath.hに書き換えても、FL/math.hの内容が古いためエラーになります。私自身はFLTKのmath.hを使っていないので荒技ですが適当なディレクトリに隔離しました。仮にFL/math.hが使用可能だとしてもどう改変されているか分からないので使いたくないですね。この問題、エラーにならなかったら気付かないうちにFL/math.hを使わされていることになります。

トラブル2:
リサイズ機能を記述したソースのビルド時に以下のエラーが発生した。

Undefined symbols for architecture arm64:
  "cv::Mat::Mat()", referenced from:
      resize() in ImageInspector.o
  "cv::Mat::~Mat()", referenced from:
      resize() in ImageInspector.o
  "cv::Mat::operator=(cv::Mat&&)", referenced from:
      resize() in ImageInspector.o
  "cv::imread(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int)", referenced from:
      resize() in ImageInspector.o
  "cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)", referenced from:
      resize() in ImageInspector.o
  "cv::imwrite(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cv::_InputArray const&, std::__1::vector<int, std::__1::allocator<int> > const&)", referenced from:
      resize() in ImageInspector.o
ld: symbol(s) not found for architecture arm64

原因:
ライブラリの参照先が不十分。今回は当てはまりませんが、makefileのオブジェクトファイル作成部分が抜けていても同種のエラーが出ます。

解決策:
コンパイルおよびビルド時に以下のオプションを追加しました。”pkg-config –cflags –libs opencv4″コマンドでも出てこないオプションです。

<コンパイル>
-lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_imgproc

<ビルド>
-L/opt/homebrew/Cellar/opencv/4.5.5/lib

参考サイト1
参考サイト2