Amazon Linux 2023 で OpenCV + opencv_contrib をソースビルドする
EC2 や ECS、Lambda のコンテナイメージで画像処理を動かすとき、ベース OS に Amazon Linux 2023(以下 AL2023)を選ぶ場面は多くあります。ところが AL2023 は Fedora 系(/etc/os-release の ID_LIKE は fedora のみ)で、Amazon 独自のリポジトリ構成を持っています。そのため Ubuntu 向けの手順も、Rocky Linux 向けの手順も、そのままでは通りません。
この記事では AL2023(aarch64)のコンテナ上で実際に OpenCV 4.10.0 + opencv_contrib をビルドし、動作確認まで行った結果をそのまま手順にしています。
先に結論: AL2023 で詰まるのは次の3点です
| 詰まる箇所 | 実際に起きること |
|---|---|
| EPEL が使えない | dnf install epel-release が No 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_LIST に highgui も足してください。サーバー用途では不要です。
⚠️ 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_PATH も ldconfig の設定も、こちらを指定してください。
まとめ
- 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)を開発しています。顔認証システムへの組み込み実績多数。

