この記事はOpenCV Advent Calendar 2024の8日目の記事です。
他の記事は目次にまとめられています。
■ TL;DR
- OpenCVにvcpkg提供ライブラリを組み込む事ができるよ!これで、比較的最新コードがいつでも試せるよ!
- だけど、デフォルトだとライブラリはstatic linkだから、依存関係解決に手を加えないといけない事も・・・できなくはない。
■ 本題
〇 (背景・モチベ)最新版ライブラリをもっと手軽にOpenCVに組み込みたい!
OpenCVにJPEG XL Encoder/Decoder追加のpull requestが出ていた。Great Job! なのだが、ちょっとOpenCVの詳細は分からないから助けてーとあったので、手助けしてみた。
その際に、vcpkg提供のlibjxl(JPEG XLライブラリ)使えば最新版のが簡単にインストールできるよ!と言われていた。言われていたのだけど…。
"OpenCV vcpkg"で検索すると、大体「vcpkg提供OpenCVの使い方」が引っ掛かる。
しかし、vcpkg提供ライブラリを、OpenCVのbuildで使う、という情報が少ない!
@UnaNancyOwen さんのこちらの記事とかですね。
https://qiita.com/UnaNancyOwen/items/54c6334f269d03646cad
〇(現状分析)ライブラリインストール方法と、手軽さ・最新追従できるか
雑に分析すると、下記の通り。vcpkg
を使えば、簡単にライブラリをインストールでき、メジャーなものであればそこそこ最新になっている!!
(※インストールできるとは言っているが、OpenCVに組み込めるとはいっていない)。
手段 | 手軽さ | 最新追従 |
---|---|---|
sourceからbuild | ライブラリ提供に依存(cmakeがあれば...) | 常に最新版。 |
OpenCVにbuild-in | 実績あるコードが最初から! | 若干、古い事も。 |
system library |
apt コマンドで簡単に入る! |
Distributor任せ。若干、古い事も |
vcpkg |
vcpkg コマンドで簡単に入る! |
最新版試せることが多い |
今回はOpenCVにvcpkg提供ライブラリを繋げる手順をまとめておく。
誰得?私得だよ!ボロ儲けだよ!
〇 (Step.1) OpenCV開発環境整備
Ubuntu 24.04環境をベースにOpenCV 開発環境を整備する。
sudo apt update -y && sudo apt install -y build-essential git cmake ccache cmake-curses-gui ninja-build curl zip unzip tar pkg-config
cd && mkdir work && cd work && git clone --depth=1 https://github.com/opencv/opencv.git opencv4
cd && cd work && cmake -S opencv4 -B build4-main -GNinja
この時のCMake出力はこんな感じ。
-- Media I/O:
-- ZLib: zlib (ver 1.3.1)
-- JPEG: build-libjpeg-turbo (ver 3.0.3-70)
-- SIMD Support Request: YES
-- SIMD Support: NO
-- WEBP: build (ver encoder: 0x020f)
-- AVIF: NO
-- PNG: build (ver 1.6.43)
-- TIFF: build (ver 42 - 4.6.0)
-- JPEG 2000: build (ver 2.5.0)
-- OpenEXR: build (ver 2.3.0)
-- HDR: YES
-- SUNRASTER: YES
-- PXM: YES
-- PFM: YES
〇(Step2) vcpkg環境にライブラリをインストール
大まかな手順は、Microsoftさんの https://learn.microsoft.com/ja-jp/vcpkg/get_started/get-started?pivots=shell-bash を参考に。
cd && git clone https://github.com/microsoft/vcpkg.git
cd && cd vcpkg && ./bootstrap-vcpkg.sh
bashrcに環境変数もセット
export VCPKG_ROOT=/home/kmtr/vcpkg
export PATH=$VCPKG_ROOT:$PATH
手始めに、libjpeg-turboを入れてみる。
vcpkg libjpeg-turbo[jpeg7]
インストールできたかの確認。善哉善哉。
$ vcpkg list
libjpeg-turbo:x64-linux 3.0.4 libjpeg-turbo is a JPEG image codec that uses SI...
libjpeg-turbo[jpeg7]:x64-linux Emulate libjpeg v7 API/ABI (this makes libjpeg-t...
vcpkg-cmake-config:x64-linux 2024-05-23
vcpkg-cmake:x64-linux 2024-04-23
〇(Step3) OpenCVをvcpkg提供ライブラリ指定してbuild
-DCMAKE_TOOLCHAIN_FILE
指定をしてcmakeすると、vcpkg提供ライブラリを参照するようになっている
cd && cd work && cmake -S opencv4 -B build4-main.vckpkg -GNinja -DCMAKE_TOOLCHAIN_FILE=/home/kmtr/vcpkg/scripts/buildsystems/vcpkg.cmake
この時の出力はこんな感じ。JPEGの行が変わっている。
-- Media I/O:
-- ZLib: zlib (ver 1.3.1)
-- JPEG: /home/kmtr/vcpkg/installed/x64-linux/lib/libjpeg.a (ver 70)
-- WEBP: build (ver encoder: 0x020f)
-- AVIF: NO
-- PNG: build (ver 1.6.43)
-- TIFF: build (ver 42 - 4.6.0)
-- JPEG 2000: build (ver 2.5.0)
-- OpenEXR: build (ver 2.3.0)
-- HDR: YES
-- SUNRASTER: YES
-- PXM: YES
-- PFM: YES
これで、OpenCV with vcpkg提供ライブラリは成功だ!
〇 まとめ
- vcpkgを使う事で、最新に近いライブラリを手軽に組み込む事ができます!
■ (Appendix)JPEG以外も繋いでみよう
〇(Step4) もーっといっぱい他ライブラリも繋ぎたい!
私の中のハンチョウが囁くのです。
???「フフ…… へただなあ、熊太郎くん。へたっぴさ……!
欲望の解放のさせ方がへた....。
熊太郎くん…… 贅沢ってやつはさ…… 小出しはダメなんだ……! やる時はきっちりやった方がいい……!
それでこそ次の節制の励みになるってもんさ……! 違うかい……?」
はっ!!! 私は、libjpeg turboだけじゃ足らん・・・そうだ!アレもコレもみんなやってこそ、vcpkg提供ライブラリの活用だあああああ(目ギラギラ)
vcpkg install zlib-ng libwebp tiff libpng libavif openexr
結果:ライブラリ不足でbuildは失敗。とほほほほほ・・・
-- Media I/O:
-- ZLib: optimized /home/kmtr/vcpkg/installed/x64-linux/lib/libz.a debug /home/kmtr/vcpkg/installed/x64-linux/debug/lib/libz.a (ver 1.3.1)
-- JPEG: /home/kmtr/vcpkg/installed/x64-linux/lib/libjpeg.a (ver 70)
-- WEBP: /home/kmtr/vcpkg/installed/x64-linux/lib/libwebp.a (ver encoder: 0x020f)
-- AVIF: /home/kmtr/vcpkg/installed/x64-linux/debug/lib/libavif.a (ver 1.1.1)
-- PNG: optimized /home/kmtr/vcpkg/installed/x64-linux/lib/libpng16.a debug /home/kmtr/vcpkg/installed/x64-linux/debug/lib/libpng16d.a (ver 1.6.43)
-- TIFF: optimized /home/kmtr/vcpkg/installed/x64-linux/lib/libtiff.a debug /home/kmtr/vcpkg/installed/x64-linux/debug/lib/libtiffd.a (ver 42 / 4.7.0)
-- JPEG 2000: OpenJPEG (ver 2.5.2)
-- OpenEXR: OpenEXR::OpenEXR (ver 3.3.1)
-- HDR: YES
-- SUNRASTER: YES
-- PXM: YES
-- PFM: YES
Dynamic linkするときは依存性が解決できるけど、static linkする時はそうもいかない。
よし、強引にパッチを書こう(非純正)
ということで、もし試す方がいれば参考になるだろうということで、これもおまけで残しておきます。
修正パッチ本体
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c8e4ef0..b584658 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -310,6 +310,12 @@ OCV_OPTION(WITH_WEBP "Include WebP support" ON
OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ((WIN32 OR ANDROID OR APPLE) OR BUILD_OPENEXR) OR NOT CMAKE_CROSSCOMPILING
VISIBLE_IF NOT APPLE_FRAMEWORK AND NOT WINRT
VERIFY HAVE_OPENEXR)
+OCV_OPTION(WITH_LZMA "Include LZMA support" OFF
+ VISIBLE_IF TRUE
+ VERIFY HAVE_LZMA)
+OCV_OPTION(WITH_LIBYUV "Include LibYUV support" OFF
+ VISIBLE_IF TRUE
+ VERIFY HAVE_LIBYUV)
OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF
VISIBLE_IF NOT ANDROID AND NOT WINRT
VERIFY HAVE_OPENGL)
@@ -1442,6 +1448,12 @@ if(WITH_ZLIB_NG OR HAVE_ZLIB_NG)
else()
status(" ZLib:" ZLIB_FOUND THEN "${ZLIB_LIBRARIES} (ver ${ZLIB_VERSION_STRING})" ELSE "build (ver ${ZLIB_VERSION_STRING})")
endif()
+if(WITH_LZMA OR HAVE_LZMA)
+ status(" LZMA" LIBLZMA_FOUND THEN "${LIBLZMA_LIBRARIES} (ver ${LIBLZMA_VERSION}) " ELSE "NO")
+endif()
+if(WITH_LIBYUV OR HAVE_LIBYUV)
+ status(" LibYUV" LIBYUV_FOUND THEN "${LIBYUV_LIBRARIES}" ELSE "NO")
+endif()
if(WITH_JPEG OR HAVE_JPEG)
if(NOT HAVE_JPEG)
diff --git a/cmake/OpenCVFindLibsGrfmt.cmake b/cmake/OpenCVFindLibsGrfmt.cmake
index e059305..4061929 100644
--- a/cmake/OpenCVFindLibsGrfmt.cmake
+++ b/cmake/OpenCVFindLibsGrfmt.cmake
@@ -57,6 +57,25 @@ else()
endif()
endif()
+# --- liblzma (optional for libtiff) ---
+if(WITH_LZMA)
+ find_package(LibLZMA REQUIRED)
+ if(LibLZMA_FOUND)
+ set(HAVE_LZMA TRUE)
+ endif()
+endif()
+
+# --- libyuv (optional for AVIF) ---
+if(WITH_LIBYUV)
+ find_package(libyuv CONFIG REQUIRED)
+ if(libyuv_FOUND)
+ set(LIBYUV_INCLUDE_DIRS ${libyuv_INCLUDE_DIRS})
+ find_file(LIBYUV_LIBRARIES NAME libyuv.a PATHS "${libyuv_DIR}/../../lib")
+ set(LIBYUV_FOUND TRUE)
+ set(HAVE_LIBYUV TRUE)
+ endif()
+endif()
+
# --- libavif (optional) ---
if(WITH_AVIF)
diff --git a/cmake/OpenCVFindWebP.cmake b/cmake/OpenCVFindWebP.cmake
index 24f4f93..161b46f 100644
--- a/cmake/OpenCVFindWebP.cmake
+++ b/cmake/OpenCVFindWebP.cmake
@@ -23,11 +23,16 @@ else()
FIND_LIBRARY(WEBP_LIBRARY NAMES webp)
MARK_AS_ADVANCED(WEBP_LIBRARY)
+ FIND_LIBRARY(SHARPYUV_LIBRARY NAMES sharpyuv)
+ MARK_AS_ADVANCED(SHARPYUV_LIBRARY)
+
# handle the QUIETLY and REQUIRED arguments and set WEBP_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(WebP DEFAULT_MSG WEBP_LIBRARY WEBP_INCLUDE_DIR)
SET(WEBP_LIBRARIES ${WEBP_LIBRARY})
+ SET(SHARPYUV_LIBRARIES ${SHARPYUV_LIBRARY})
SET(WEBP_INCLUDE_DIRS ${WEBP_INCLUDE_DIR})
+
endif()
diff --git a/modules/imgcodecs/CMakeLists.txt b/modules/imgcodecs/CMakeLists.txt
index 1468d4d..7a78a68 100644
--- a/modules/imgcodecs/CMakeLists.txt
+++ b/modules/imgcodecs/CMakeLists.txt
@@ -27,6 +27,7 @@ if(HAVE_WEBP)
add_definitions(-DHAVE_WEBP)
ocv_include_directories(${WEBP_INCLUDE_DIR})
list(APPEND GRFMT_LIBS ${WEBP_LIBRARIES})
+ list(APPEND GRFMT_LIBS ${SHARPYUV_LIBRARIES})
endif()
if(HAVE_SPNG)
@@ -78,6 +79,16 @@ if(HAVE_OPENEXR)
endif()
endif()
+if(HAVE_LIBYUV)
+ ocv_include_directories(${LIBYUV_INCLUDE_DIRS})
+ list(APPEND GRFMT_LIBS ${LIBYUV_LIBRARIES})
+endif()
+
+if(HAVE_LZMA)
+ ocv_include_directories(${LIBLZMA_INCLUDE_DIRS})
+ list(APPEND GRFMT_LIBS ${LIBLZMA_LIBRARIES})
+endif()
+
if(HAVE_PNG OR HAVE_TIFF OR HAVE_OPENEXR OR HAVE_SPNG)
ocv_include_directories(${ZLIB_INCLUDE_DIRS})
list(APPEND GRFMT_LIBS ${ZLIB_LIBRARIES})
kmtr@kmtr-VMware-Virtual-Platform:~/work/opencv4$
これでばっちぐーなのです!!
kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main.vckpkg$ nm lib/libopencv_imgcodecs.so | c++filt | grep "cv\:\:AvifDecoder::readHeader"
0000000000116b60 t cv::AvifDecoder::readHeader()
00000000000e299e t cv::AvifDecoder::readHeader() [clone .cold]
kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main.vckpkg$ nm lib/libopencv_imgcodecs.so | c++filt | grep "cv\:\:WebPDecoder::readHeader"
0000000000143350 t cv::WebPDecoder::readHeader()
00000000000e7a20 t cv::WebPDecoder::readHeader() [clone .cold]
000000000084ce60 d cv::WebPDecoder::readHeader()::__cv_check__113
000000000084ce20 d cv::WebPDecoder::readHeader()::__cv_check__114
000000000084cde0 d cv::WebPDecoder::readHeader()::__cv_check__121
000000000084cda0 d cv::WebPDecoder::readHeader()::__cv_check__129
kmtr@kmtr-VMware-Virtual-Platform:~/work/build4-main.vckpkg$ nm lib/libopencv_imgcodecs.so | c++filt | grep "cv\:\:TiffDecoder::readHeader"
0000000000135e70 t cv::TiffDecoder::readHeader()
00000000000e618a t cv::TiffDecoder::readHeader() [clone .cold]
000000000084cae0 d cv::TiffDecoder::readHeader()::__cv_check__303
000000000084caa0 d cv::TiffDecoder::readHeader()::__cv_check__313
000000000084ca60 d cv::TiffDecoder::readHeader()::__cv_check__325
000000000084ca20 d cv::TiffDecoder::readHeader()::__cv_check__339
000000000084c9e0 d cv::TiffDecoder::readHeader()::__cv_check__347
000000000084c9a0 d cv::TiffDecoder::readHeader()::__cv_check__354