OpenCVをwindowsで使うメモ（CMake)

OpenCVをwindowsで使用したので、その備忘録です。
エディタはvisual studio codeで、cmakeでbuildしています。
今回は、3rd party のライブラリは一か所にまとめたかったので、dependencyフォルダを別途作成し、そのなかにさらにopencvフォルダを作りました。
また、ChARUcoを使ってみたかったので、sourceからbuildしています。
```bash:プロジェクトのファイル構造
│   
├─dependencies
│  └─opencv
│      ├─bin
│      ├─etc
│      ├─include
│      ├─java
│      │  ├─x64
│      │  └─x86
│      ├─python
│      └─x64
│          ├─vc14
│          └─vc15
└─src
    ├─lib
    └─main.cpp
```

# source codeのダウンロード
OpenCVのソースコードは下記にあります。

https://github.com/opencv/opencv/releases

OpenCVのRelease欄にある、〇〇windows.exe(古いバージョンだと、opencv-x.y.z-vc14_vc15.exeとか)をダウンロードします。
実行すると、ファイルの生成が始まります。
終了すると、sourcesとbuildができるので、buildにはこちらの"source"を使用します。

(assetsからダウンロードできるsource code.zipを使ってもbuildできると思いますが、試していません。)

参考:

https://swallow-incubate.com/archives/blog/20200508/

ChArUcoを使わない場合、buildフォルダがそのまま使えるので、再度buildをする必要はありません。
ですが、ChArUcoなどを認識したい場合、別途OpenCV_contribをダウンロードし、再度buildする必要があります。

https://github.com/opencv/opencv_contrib/tags

これをダウンロードし、適当な場所で解凍します。
1点注意することがあり、**OpenCVのバージョンと、contribのバージョンを一致させておきましょう。**(OpenCV-4.5.4なら、opencv_contrib-4.5.4を使う。)
そして、cmake guiを起動し、下記の変数を編集します。
generatorはvisual studioを選択します。
```bash
-DOPENCV_EXTRA_MODULES_PATH = path\to\opencv_contrib-4.x\opencv_contrib-4.x\modules
-DWITH_CUDA=OFF # cudaがある方はON
-DBUILD_TESTS=OFF
-DINSTALL_TESTS=OFF
-DBUILD_opencv_dnn=OFF # 自分の環境ではdnn関連のbuildが通らなかったため、OFF
```
それ以外の変数は基本デフォルトでOKでした。



# build
visual studioを起動し、DebugもしくはReleaseを選択し、buildします。
自分のプロジェクトをdebug buildをしたいなら、OpenCVのほうも、debug buildしたものが必要です。

buildできたら、"INSTALL"をbuildして、installディレクトリに必要なファイルをコピーします。
installディレクトリは、-DCMAKE_INSTALL_PREFIXで指定できます。

すると、デフォルトではbuildしたディレクトリ内のinstallディレクトリにインストールされるので、それをコピーしてほしい場所に設置すればよいです。
今は、dependencies/opencv内に、buildの中身をコピーしました。
OpenCVConfig.cmakeもその中にあります。
このパスをCMake側で設定し、find packageします。


# CMakeLists.txt
OpenCV_INCLUDE_DIRSにOpenCVのincludeディレクトリのパスが、OpenCV_LIBRARIESにリンクするファイルのリストが入っています。dllファイルなどのランタイムライブラリは、cmake --installでbuildディレクトリにコピーされる設定にしています。正規表現でdllのみが選択されるようにしています。


```bash:CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED true)

project ("OpenCVTest" VERSION 0.0)

set (OpenCV_DIR "${PROJECT_SOURCE_DIR}/dependencies/opencv")
find_package(OpenCV CONFIG REQUIRED)

add_executable (${CMAKE_PROJECT_NAME} "${PROJECT_SOURCE_DIR}/src/main.cpp")
target_include_directories(${CMAKE_PROJECT_NAME} PUBLIC ${OpenCV_INCLUDE_DIRS})
target_link_libraries(${CMAKE_PROJECT_NAME} ${OpenCV_LIBRARIES})

if (MSVC)
    install(DIRECTORY "${PROJECT_SOURCE_DIR}/dependencies/opencv/x64/vc15/bin/" DESTINATION ${CMAKE_BINARY_DIR}/Debug
        FILES_MATCHING PATTERN "*.dll")
else()
    # install(FILES ${RUN_TIME_LIBS} DESTINATION ${CMAKE_BINARY_DIR})
endif()
```

# buildする
以下のコマンドをそれぞれ実行していきます。
```bash
mkdir build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 17 2022"
cmake --build build --config Debug --parallel コア数
cmake --install build --config Debug
```
# pre buildされたものを使う場合
今回はChARUcoを使うためにbuildしましたが、基本的な画像処理をしたいだけならすでにbuild済みのファイルを使うだけで充分です。
releaseのopencv-x.y.z-windows.exeを実行したのちにできるbuildフォルダに必要なファイルが入っています。

大抵のライブラリはlibとbinのファイルを適宜好きな場所にコピーしても問題なく使えますが、ことOpenCVにおいては、フォルダの階層関係が決まっているらしく、**ダウンロードしたフォルダをそのままコピーしました。**
OpenCVConfig.cmakeはopencvフォルダ直下と、x64/vc15/libにありましたが、どちらをCMakeに設定してもうまく動作しました。