【C++】Visual Studio C++でOpenCVおよびLibtorchの始め方

今回はVisual Studio C++でのOpenCVおよびtorchのC++版Libtorchの始め方を紹介する

## Visual Studioのインストール

1. Visual Studio のインストーラーをダウンロードする
    https://visualstudio.microsoft.com/ja/downloads/
    
1. ダウンロードした次のいずれかのエディションのインストーラーをダブルクリックする
    - Visual Studio Community の場合は vs_community.exe (無料)
    - Visual Studio Professional の場合は vs_professional.exe (有料)
       無料試用版の利用は下記リンクの下部からダウンロード
        https://visualstudio.microsoft.com/ja/vs/professional/
    - Visual Studio Enterprise の場合は vs_enterprise.exe (有料)
    それぞれの違いは下記公式リンク参照
    https://visualstudio.microsoft.com/ja/vs/compare/
    また、特定用途専用のVersion Visual Studio Expressもある。
1. Microsoft のライセンス条項とプライバシーに関する声明の確認を求められるため、続行を押す
    ![privacy-and-license-terms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/d14a26ab-7296-71a1-1a0e-ce400cfc76d9.png)

1. C++ によるデスクトップ開発を選択して、インストールをクリックする
    ![vs-installer-workloads.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9851e16a-bbd1-4a39-0ffe-474c2cb9c19d.png)
1. 諸々オプションの設定をして、Installを押す

## OPenCVをダウンロードして展開する
1. 以下のサイトからWindowsを選択して、OpenCVのソースコードのインストーラーをダウンロードする

    https://opencv.org/releases/

1. ダウンロードしたファイルをクリックして、C:/を選択し、C:/にファイルを展開する

## C++用torchライブラリをダウンロードして展開する
C++用torchライブラリであるLibtorchをダウンロードして展開する
1. 下記リンクからLibtorchをCPU版かGPU版のDebug/release用それぞれダウンロードする
  https://pytorch.org/
1. ダウンロードしたzipを任意のフォルダに展開する

## NVIDIAのインストールする※GPU使用の場合

1. CUDA Toolkitのインストーラーをダウンロードする
https://developer.nvidia.com/cuda-downloads
1. インストーラーを実行して、インストールする
1. cuDNNをインストールする
https://developer.nvidia.com/rdp/cudnn-archive


## Visual Studioの設定・ビルド

1. Visual Studio を起動し、新しいプロジェクトを作成する
1. プロジェクト->モジュールの追加から.cppファイルを追加する
    ![Visual_Studio_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/247cba6c-059b-e2ba-da2d-f07a2297c94d.png)
    ![Visual_Studio_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/582e8f47-620f-62c1-5896-e91f055290c4.png)
1. プロジェクト->プロパティを押して、現在表示しているプロジェクトの設定ページを表示する
    ![Visual_Studio_3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/9f5ccc36-6b8d-f7e2-feb5-942ac6938c2d.png)
1. 左上の構成からデバックかリリースを選択する
   デバック環境とリリース環境を分けて設定できる
1. C/C++->全般を押して、追加のインクルードディレクトリをクリックして、編集を押す
    ![Visual_Studio_4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/e1fdaba9-afa1-90f2-5243-db305b77fb94.png)
1. 空いているところをクリックして、追加したいヘッダーのパスをコピペして、OKを押す
    ```
    C:\Program Files (x86)\OpenCV\opencv\build\include
    ```
1. リンカー->全般を押して、追加のライブラリディレクトリをクリックして、編集を押す
    ![Visual_Studio_5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/8186436d-b685-4059-d239-0aa9e3a75e38.png)
1. 空いているところをクリックして、追加したいライブラリのパスをコピペして、OKを押す
    ```
    C:\Program Files (x86)\OpenCV\opencv\build\x64\vc16\lib
    ```
1. 構成プロパティ->デバッグを押して、環境に下記の動的リンクライブラリのパスをコピペして、OKを押す。もしくはPCのシステムの環境変数に下記を追加
    ```
    C:\Program Files (x86)\OpenCV\opencv\build\x64\vc16\bin
    ```
    ![Visual_Studio_6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/7e1bd45c-6c0d-0d6b-25fc-bede8e2b959e.png)
1. 下記のOpenCVのコードを編集画面にコピペする
1. 緑色の三角ボタンを押して、デバックモードでビルドする
1. モードをDebugからreleaseに変更して、ビルド->ソリューションのビルド押して、リリース用exeファイルを作成する

下記のような画面が表示されたら、正常にビルドできている。
![Visual_Studio_7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/6581420a-9767-c5eb-c6d1-545b4432805a.png)

## OpenCVのC++コード
引数に入力動画を渡して、ただoutput.mp4という名前で保存するだけのプログラム。

```C++:output.cpp
#if _DEBUG
#pragma comment(lib, "opencv_world470d.lib")
#else
#pragma comment(lib, "opencv_world470")
#endif

#include <iostream>
#include <thread>
#include <memory>
using namespace std;

#include <opencv2/opencv.hpp>
using namespace cv;

#include "opencv2/highgui/highgui.hpp" //動画を表示する際に必要

constexpr int TIME_TO_SLEEP = 10000;

int main(int argc, const char* argv[])
{
    Mat img(Size(640, 360), CV_8UC3);
    Mat gray_img(Size(640, 360), CV_8UC1);
    Mat gaussian_img(Size(640, 360), CV_8UC1);
    Mat bin_img(Size(640, 360), CV_8UC1);
    Mat canny_img(Size(640, 360), CV_8UC1);

    if (argc != 2)
    {
        cout << "" << endl;
        cout << " Error" << endl;
        cout << "" << endl;
        cout << " How to use : cout.exe sample.mp4" << endl;
        cout << "" << endl;
        cout << " argv:" << endl;
        cout << " cout.exe   : this program name" << endl;
        cout << " sample.mp4 : input movie file path" << endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(TIME_TO_SLEEP));
        return 0;
    }

    std::string VideoFile = argv[argc - 1];

    VideoCapture cap;
    cap.open(VideoFile);

    if (!cap.isOpened())
    {
        std::cerr << "cannot open this movie file!" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(TIME_TO_SLEEP));
        return -1;
    }

    int    fourcc, width, height;
    double fps;
    width = (int)cap.get(cv::CAP_PROP_FRAME_WIDTH);	// フレーム横幅を取得
    height = (int)cap.get(cv::CAP_PROP_FRAME_HEIGHT);	// フレーム縦幅を取得
    fps = cap.get(cv::CAP_PROP_FPS);					// フレームレートを取得
    double max_frame = cap.get(CAP_PROP_FRAME_COUNT);
    fourcc = cv::VideoWriter::fourcc('m', 'p', '4', 'v');	// AVI形式を指定
    VideoWriter Videowriter("output.mp4", fourcc, fps * 2, cv::Size(width, height), true);

    
    cv::Mat frame;
    for (int i = 0; i < int(max_frame); i++)
    {
        cap >> frame;

        if (frame.empty() == true) {
            continue;
        }

        int n = (int)cap.get(cv::CAP_PROP_POS_FRAMES);
        cout << n << endl;

        cv::imshow("再生中", frame);
        Videowriter << frame;
        cv::waitKey(1);
    }

    std::this_thread::sleep_for(std::chrono::milliseconds(TIME_TO_SLEEP));
    return 0;

}
```

## 実行
生成された.exeに入力動画をドラッグ&ドロップをクリックする
もしくは、以下のように実行する
```
output.exe input.mp4
```

## Visual Studioの拡張機能でC++版Torchをビルドする
:::note warn
Visual Studio 拡張機能のlibtorchはversion 2019と2022のみ対応している。
:::

1. 適当なプロジェクトを開き、上部の拡張機能->拡張機能の管理を押す
1. libtorchを検索して、libtorchの拡張機能をインストールする
1. インストールするため、一旦すべて閉じる
1. 新しいプロジェクトの作成を押す
1. TorchProjectを選択する
1. 作成を押して、先ほどダウンロードしたlibtorchのパスを追加する
    ![Visual_Studio_8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/2bf1b751-2de0-1e10-bbb2-4f6ffa18b9ee.png)
1. 作成を押す
1. プロジェクト->プロパティを押して、構成プロパティ -> 全般のWindowsSDKバージョンを「10.0 (最新のインストールされているバージョン)」に変更する。
    ![Visual_Studio_8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/3bd901fe-a042-22f3-6b23-e7a9b1a1fa90.png)
1. サンプルが表示された状態で出てくるので、ビルドする。
1. 実行すると以下のように表示される
```
CUDA is not available! Training on CPU
 0.0290  0.8719  0.2656
 0.1600  0.4686  0.1587
[ CPUFloatType{2,3} ]
```

## GPU利用版

1. 下記サイトに従い、NVIDIA Driver, CUDA ToolKit, cuDNN(コピペ)をインストールする
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html

https://www.nvidia.com/Download/index.aspx?lang=en-us

https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html

https://developer.nvidia.com/cuda-toolkit-archive

1. Windows SDK バージョン 10.*****がないといわれるので、下記を実行し、Windows SDKをインストールする。
"C:\Program Files (x86)\Microsoft Visual Studio\Installer\setup.exe"
![VSversion.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483556/32d4cf4f-a879-bcfd-7a0f-630607e66dd8.png)


## まとめ
今回は、Visual Studio C++でOpenCVおよびC++用torchライブラリLibtorchの始め方を紹介した。


### 参考文献

https://imagingsolution.net/program/opencv/opencv3-1visual-studio-2015-64bitos/

http://cvwww.ee.ous.ac.jp/opencv_practice/

https://qiita.com/yasuaki_sassa/items/7524fbfbf142a92e3586