OpenCV + opencv_contrib を Amazon Linux 2023 でビルドする完全ガイド【C++】

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

Amazon Linux 2023 で OpenCV + opencv_contrib をソースビルドする

EC2 や ECS、Lambda のコンテナイメージで画像処理を動かすとき、ベース OS に Amazon Linux 2023(以下 AL2023)を選ぶ場面は多くあります。ところが AL2023 は Fedora 系(/etc/os-releaseID_LIKEfedora のみ)で、Amazon 独自のリポジトリ構成を持っています。そのため Ubuntu 向けの手順も、Rocky Linux 向けの手順も、そのままでは通りません

この記事では AL2023(aarch64)のコンテナ上で実際に OpenCV 4.10.0 + opencv_contrib をビルドし、動作確認まで行った結果をそのまま手順にしています。

先に結論: AL2023 で詰まるのは次の3点です

詰まる箇所 実際に起きること
EPEL が使えない dnf install epel-releaseNo match for argument: epel-release で失敗する
FFmpeg の開発パッケージが無い ffmpeg-devel が存在せず、ビルドした OpenCV で動画ファイルが開けない
pkg-config ファイルが生成されない OpenCV 4 系はデフォルトで opencv4.pc を作らないため pkg-config --cflags opencv4 が通らない

いずれも「ビルドは成功したのに、使おうとした段階で気づく」種類の問題です。順に見ていきます。


前提環境

実際に検証した環境は次のとおりです。

項目 内容
OS Amazon Linux 2023(コンテナイメージ amazonlinux:2023
アーキテクチャ aarch64
実行環境 Apple M2 上の Docker Desktop(コンテナに 8 CPU を割り当て)
gcc-c++ 11.5.0
cmake 3.22.2
OpenCV / opencv_contrib 4.10.0(タグを一致させる)

本記事の実測は aarch64 のコンテナのみです。EC2(x86_64 / Graviton)では所要時間が変わります。

コマンドはコンテナ内(root)での実行例です。EC2 上で ec2-user として実行する場合は sudo を付けてください。


手順

1. 依存パッケージの導入

AL2023 の既定リポジトリは amazonlinux の1本だけです。OpenCV のビルドに必要なものは、追加リポジトリ無しで全部揃います(FFmpeg を除く)。

dnf -y install \
    gcc-c++ cmake git make pkgconf-pkg-config \
    libjpeg-turbo-devel libpng-devel libtiff-devel \
    python3-devel openblas-devel eigen3-devel \
    tar gzip

GUI 表示(cv::imshow)が必要な場合は、gtk3-devel を追加したうえで、後述の BUILD_LISThighgui も足してください。サーバー用途では不要です。

⚠️ epel-release は存在しません。 AL2023 は EPEL に対応していません。RHEL 系の記事に頻出する dnf install epel-release をそのまま実行すると、次のエラーで止まります。

No match for argument: epel-release
Error: Unable to find a match: epel-release

AL2023 のパッケージは Amazon が独自に提供しているため、「RHEL 系に近いから EPEL が使えるはず」という前提が成り立ちません。EPEL 由来のパッケージ名を含む手順書は、その時点で AL2023 向けではないと判断してください。

2. ソースコードの取得

本体と contrib は必ず同じタグを指定します。食い違っていても CMake の構成は通ってしまい、ビルドの途中でエラーになります。

cd /root
OPENCV_VERSION=4.10.0

curl -sL -o opencv.tar.gz \
  https://github.com/opencv/opencv/archive/refs/tags/${OPENCV_VERSION}.tar.gz
curl -sL -o opencv_contrib.tar.gz \
  https://github.com/opencv/opencv_contrib/archive/refs/tags/${OPENCV_VERSION}.tar.gz

tar xzf opencv.tar.gz
tar xzf opencv_contrib.tar.gz

git clone でも構いませんが、tarball のほうが転送量が小さく、コンテナのビルドでは扱いやすくなります。

3. CMake 構成

mkdir -p /root/build && cd /root/build

cmake /root/opencv-4.10.0 \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/usr/local \
  -DOPENCV_EXTRA_MODULES_PATH=/root/opencv_contrib-4.10.0/modules \
  -DOPENCV_ENABLE_NONFREE=ON \
  -DOPENCV_GENERATE_PKGCONFIG=ON \
  -DBUILD_LIST=core,imgproc,imgcodecs,videoio,features2d,calib3d,flann,xfeatures2d,ximgproc \
  -DBUILD_TESTS=OFF \
  -DBUILD_PERF_TESTS=OFF \
  -DBUILD_EXAMPLES=OFF \
  -DBUILD_opencv_python3=OFF \
  -DBUILD_opencv_apps=OFF

主要オプション

オプション 意味
OPENCV_EXTRA_MODULES_PATH contrib モジュールのパス
OPENCV_ENABLE_NONFREE=ON SURF など特許関連アルゴリズムを有効化
OPENCV_GENERATE_PKGCONFIG=ON opencv4.pc を生成する。OpenCV 4 系では既定 OFF(後述)
BUILD_LIST ビルドするモジュールを限定。サーバー用途では絞ったほうがビルド時間もサイズも大幅に減る

構成が終わったら、出力の Video I/O セクションを必ず確認してください。AL2023 では次のようになります。

--   Video I/O:
--     FFMPEG:                      NO
--       avcodec:                   NO
--       avformat:                  NO
--       avutil:                    NO
--       swscale:                   NO
--     GStreamer:                   NO
--     v4l/v4l2:                    YES (linux/videodev2.h)

FFMPEG: NO が AL2023 の既定値です。 ここを見落としたままビルドを進めると、後で動画が読めないことに気づきます。v4l/v4l2 は有効なので、/dev/video* を直接開くカメラ入力は動作します。

4. ビルドとインストール

make -j$(nproc)
make install

BUILD_LIST を上記9モジュールに絞った状態で、Apple M2 上の Docker(8 CPU 割り当て)で実測 3分59秒でした。モジュールを絞らず contrib 全部を入れると、この数倍の時間がかかります。CI やコンテナビルドに載せる場合、BUILD_LIST の絞り込みは効果が大きい部分です。

5. 共有ライブラリのパスを通す

RHEL 系・Fedora 系では /usr/local/lib64 にインストールされますが、このパスは既定では ldconfig に登録されていません(AL2023 の /etc/ld.so.conf.d/ は空です。Rocky Linux 9 / AlmaLinux 9 も同じでした)。そのまま実行すると次のエラーになります。

error while loading shared libraries: libopencv_videoio.so.410:
cannot open shared object file: No such file or directory

登録して解決します。

echo "/usr/local/lib64" > /etc/ld.so.conf.d/opencv.conf
ldconfig

EC2 上で sudo を使う場合、リダイレクトは root 権限にならないので tee を使います。

echo "/usr/local/lib64" | sudo tee /etc/ld.so.conf.d/opencv.conf
sudo ldconfig

コンテナイメージに焼き込む場合は、この2行を Dockerfile の RUN に含めておきます。


動作確認

ビルド結果が期待どおりか、4項目をまとめて確認するプログラムです。

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/ximgproc.hpp>
#include <iostream>

int main()
{
    std::cout << "OpenCV " << CV_VERSION << std::endl;

    // [1] 静止画の書き出し・読み込み
    cv::Mat img(240, 320, CV_8UC3, cv::Scalar(30, 120, 220));
    cv::imwrite("out.png", img);
    cv::Mat r = cv::imread("out.png");
    std::cout << "[1] imwrite/imread: " << (r.empty() ? "NG" : "OK") << std::endl;

    // [2] 動画ファイルが開けるか(FFmpeg バックエンドの有無がここに出る)
    cv::VideoCapture cap("test.mp4");
    std::cout << "[2] VideoCapture(mp4): "
              << (cap.isOpened() ? "OK" : "NG") << std::endl;

    // [3] contrib + NONFREE の確認
    auto surf = cv::xfeatures2d::SURF::create();
    std::cout << "[3] contrib SURF: OK" << std::endl;

    // [4] contrib の別モジュール(ximgproc)
    cv::Mat gray, thin;
    cv::cvtColor(r, gray, cv::COLOR_BGR2GRAY);
    cv::ximgproc::thinning(gray, thin, cv::ximgproc::THINNING_ZHANGSUEN);
    std::cout << "[4] contrib ximgproc: OK" << std::endl;

    return 0;
}

test.mp4 は AL2023 上では作れない(FFmpeg が無い)ので、FFmpeg のある手元の PC で作ってコンテナや EC2 に持ち込みます。

ffmpeg -f lavfi -i testsrc=duration=1:size=320x240:rate=10 -c:v mpeg4 -pix_fmt yuv420p test.mp4

コンパイルと実行はこうです。

export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
g++ -std=c++17 check.cpp -o check $(pkg-config --cflags --libs opencv4)
./check

AL2023 での実行結果は次のようになりました。

OpenCV 4.10.0
[1] imwrite/imread: OK
[2] VideoCapture(mp4): NG
[3] contrib SURF: OK
[4] contrib ximgproc: OK

静止画と contrib は問題なく動き、動画だけが開けません。 これが AL2023 でビルドした OpenCV の姿です。

コーデックの違いで結果が変わるかも確かめました。同じ映像を5種類のコーデックで作り、isOpened() と1フレーム目の read() を試した結果です。

コーデック AL2023
MPEG-4 Part 2(mpeg4 開けない
H.264(libx264 開けない
H.265 / HEVC(libx265 開けない
VP9 開けない
AV1 開けない

FFmpeg バックエンドそのものが無いため、コーデックに関係なくすべて開けません


つまずきポイント

⚠️ opencv4.pc が生成されない(OpenCV 4 系の既定は OFF)

インストール後に pkg-config を叩くと、こう返ってきます。

Package opencv4 was not found in the pkg-config search path.
Perhaps you should add the directory containing `opencv4.pc'
to the PKG_CONFIG_PATH environment variable

PKG_CONFIG_PATH の設定漏れだと思って調べ回ることになりますが、そもそも .pc ファイルが作られていません。実際、/usr/local/lib64/pkgconfig というディレクトリ自体が存在しない状態です。

OpenCV 4 系は pkg-config ファイルの生成が既定で無効になっているためで、CMake 構成に次を足すと生成されます。

-DOPENCV_GENERATE_PKGCONFIG=ON

一方、CMake の find_package(OpenCV) 用のファイル(OpenCVConfig.cmake)は既定で生成されます/usr/local/lib64/cmake/opencv4/ に入っているので、CMake プロジェクトから使う分にはこのフラグは要りません。ビルドシステムが CMake なら、pkg-config を経由せず find_package を使うほうが素直です。

⚠️ 動画を扱う必要がある場合の選択肢

FFMPEG: NO のままでは cv::VideoCapture で mp4 も avi も開けません。要件に動画が含まれるなら、次のどれかを選ぶことになります。

選択肢 判断材料
設計を静止画に寄せる 動画のデコードを OpenCV の外(別プロセス・別サービス)で行い、OpenCV にはフレーム画像を渡す。最も素直で、当社もこの方針を採っています
FFmpeg を自前ビルドする AL2023 上で FFmpeg をソースからビルドし、それに対して OpenCV をリンクする。実現はできますが、ライセンス(LGPL/GPL のどちらでビルドするか)と保守の負担が増えます
ベース OS を変える Rocky Linux 9 / AlmaLinux 9 なら EPEL から ffmpeg-free-devel が入り、FFMPEG: YES でビルドできます
カメラ直結で済ませる v4l/v4l2 は有効なので、/dev/video* からの取得だけなら AL2023 のままで動きます

「AL2023 を選んだ時点で動画デコードは別の層の仕事になる」と捉えるのが、結果的に一番手戻りが少ない判断だと考えています。

⚠️ lib ではなく lib64

Ubuntu 向けの手順をそのまま持ち込むと /usr/local/lib を探して見つからず混乱します。RHEL 系は 64bit ライブラリを /usr/local/lib64 に置きます。PKG_CONFIG_PATHldconfig の設定も、こちらを指定してください。


まとめ

  • AL2023 は Fedora 系で、EPEL は使えません。EPEL 前提の手順書は AL2023 向けではありません
  • FFmpeg の開発パッケージが無いため、ビルドした OpenCV は動画ファイルを開けませんFFMPEG: NO)。静止画と contrib は問題なく動きます
  • opencv4.pc は既定で生成されません。pkg-config を使うなら -DOPENCV_GENERATE_PKGCONFIG=ON が必要です
  • /usr/local/lib64 を ldconfig に登録しないと実行時に .so が見つかりません
  • BUILD_LIST でモジュールを絞ると、8 CPU で 4分程度までビルド時間を落とせます

他のプラットフォームでの手順は OpenCV + opencv_contrib を Ubuntu でビルドする完全ガイド【C++】 を参照してください。インストール後に CMake プロジェクトから使う手順は CMake で OpenCV をリンクする方法【find_package 完全ガイド・C++】 にまとめています。まず動かしたいだけであれば OpenCV 環境構築 最短ガイド【C++/Windows・macOS・Linux】 から始めるのが早道です。

🛠 画像処理のプロが開発するSDK/API

本ブログを運営するスワローインキュベートは、OpenCV ベースのなりすまし判定SDK/API(C++製・OpenCV 4.10)を開発しています。顔認証システムへの組み込み実績多数。

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

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