macでOpenCVの環境構築(C++)

## はじめに
大学の授業でC++環境のOpencvを扱う場面があったのですがMacでの環境構築に戸惑ったので備忘録として書いておきます。

この記事ではVScodeのデバック機能を使ったビルドから実行まで自動化する手順と、CMakeを使う2つの方法を解説します。

私の環境ではカスケードフィルターや一部のフィルターがVScodeのデバック機能だと落ちてしまう現象が発生したので、VScodeで出来ない場合はCMakeを使うことでビルド・実行していました。

# VScode標準のデバック機能を使うための設定。
VScode標準のデバック機能を使ったビルド・実行のメリットは現在アクティブのファイルをワンクリックでビルドから実行まで行えることです。
## Step1 Opencvのインストール
```
brew install opencv
```

## Step2 Pathを調べる
OpencvがインストールされたPathを調べます。
調べ方は、以下のコマンドです。
```
brew info opencv
```

## Step3 設定ファイルの構成
```
.vscode
├── c_cpp_properties.json
├── launch.json
├── settings.json
└── tasks.json
```
このように設定ファイルを用意します。すでにある場合はそのまま次のステップに進みます。

## Step4 各ファイルの中身

```c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Mac",
            "includePath": [
                "${workspaceFolder}/**",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/include",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/include/opencv4/opencv2",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/include/opencv4"
            ],
            "defines": [],
            "macFrameworkPath": [],
            "compilerPath": "/usr/bin/clang",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "${default}",
            "browse": {
                "path": [
                    "/opt/homebrew/Cellar/opencv/4.9.0_7/include/opencv4"
                ],
                "limitSymbolsToIncludedHeaders": true
            }
        }
    ],
    "version": 4
}
```
この設定ファイルでVScodeのデバック機能に対して、コンパイラーの指定と、ビルド済みファイルの設置場所を指定しています。
```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": true,
            "MIMode": "lldb",
            "preLaunchTask": "Build"
        },
        {
            "name": "C/C++: gcc build and debug active file",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "lldb",
            "preLaunchTask": "C/C++: gcc build active file"
        }
    ]
}
```
ビルドする際にライブラリの読み込みパスを設定します。ここの記述が間違っているとincludeエラーが発生してビルド出来ません。
```tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Build",
            "type": "shell",
            "command": "clang++",
            "args": [
                "-std=c++17",
                "${file}",
                "-o",
                "${workspaceFolder}/build/${fileBasenameNoExtension}",
                "-I",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/include",
                "-I",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/include/opencv4",
                "-L",
                "/opt/homebrew/Cellar/opencv/4.9.0_7/lib",
                "-l",
                "opencv_stitching",
                "-l",
                "opencv_superres",
                "-l",
                "opencv_videostab",
                "-l",
                "opencv_aruco",
                "-l",
                "opencv_bgsegm",
                "-l",
                "opencv_bioinspired",
                "-l",
                "opencv_ccalib",
                "-l",
                "opencv_dnn_objdetect",
                "-l",
                "opencv_dpm",
                "-l",
                "opencv_face",
                "-l",
                "opencv_fuzzy",
                "-l",
                "opencv_hfs",
                "-l",
                "opencv_img_hash",
                "-l",
                "opencv_line_descriptor",
                "-l",
                "opencv_optflow",
                "-l",
                "opencv_reg",
                "-l",
                "opencv_rgbd",
                "-l",
                "opencv_saliency",
                "-l",
                "opencv_stereo",
                "-l",
                "opencv_structured_light",
                "-l",
                "opencv_phase_unwrapping",
                "-l",
                "opencv_surface_matching",
                "-l",
                "opencv_tracking",
                "-l",
                "opencv_datasets",
                "-l",
                "opencv_dnn",
                "-l",
                "opencv_plot",
                "-l",
                "opencv_xfeatures2d",
                "-l",
                "opencv_shape",
                "-l",
                "opencv_video",
                "-l",
                "opencv_ml",
                "-l",
                "opencv_ximgproc",
                "-l",
                "opencv_xobjdetect",
                "-l",
                "opencv_objdetect",
                "-l",
                "opencv_calib3d",
                "-l",
                "opencv_features2d",
                "-l",
                "opencv_highgui",
                "-l",
                "opencv_videoio",
                "-l",
                "opencv_imgcodecs",
                "-l",
                "opencv_flann",
                "-l",
                "opencv_xphoto",
                "-l",
                "opencv_photo",
                "-l",
                "opencv_imgproc",
                "-l",
                "opencv_core",
                "-g"
            ],
            "group": "build",
            "problemMatcher": [
                "$gcc"
            ]
        }
    ]
}
```
これらはVScodeの標準デバック機能を使うための設定でtasks.jsonではコンパイル済みのファイルを置く場所をbuildフォルダーに置くようにしています。
このように設定することでコンパイル済みのファイルとソースファイルがごちゃまぜになることを防いでいます。
tasks.jsonをこのまま使う場合はプロジェクトフォルダー直下にbuildフォルダーを用意してください。

# CMakeの設定方法
CMakeを使った方法では、CMake.txtの中を書き換えなければならず手間が増えます。デバック機能で実行できないときは、CMakeを使うといった使い方をしていました。

## Step1 CMakeLists.txtの設定
プロジェクトフォルダー直下に```CMakeLists.txt```を設置し、以下のようにしてください。
```CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project (c++)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall")
find_package(OpenCV REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS} )
add_executable(Main base.cpp)
target_link_libraries(Main ${OpenCV_LIBS})
```
## Step3 シェルスクリプトで自動化
プロジェクトフォルダー直下にbuild.shに以下の内容を書いてください。このスクリプトではCMakeでビルドした後に実行までしてくれるスクリプトです。

このスクリプトで一度ビルドフォルダーを消して作り直しているのは、うまくビルドが走らないときがあり、ビルドフォルダーの中身を消すとうまく行ったため、毎回ビルドフォルダーを消して作り直してからビルド済みファイルを展開するようにしました。
```build.sh
rm -rf build
mkdir -p build
cd build
cmake .. .
make
cd ..
./build/Main
```
 # 参考文献
 https://qiita.com/toshi_machine/items/908e9be57e8afa629159 
 
 https://www.tiziran.com/topics-and-projects/source-code/opencv/macos-opencv