Visual StudioでOpenCV3.0開発環境を準備する

# OpenCVのインストール

以下の環境で説明する．

* Windows 8.1
* Visual Studio Community 2013
* OpenCV 3.0 (2015/06/06時点の最新版です)

主に参考にしたのは次のウェブページである．
<http://docs.opencv.org/3.0-beta/doc/tutorials/introduction/windows_install/windows_install.html>

## パッケージのダウンロード

まず <http://opencv.org/> から，パッケージをダウンロードする．

ウェブページの右の方，LATEST DOWNLOADS とある箇所の下にある，OpenCV for Windows リンクをクリックする．
![opencv-download-01.png](https://qiita-image-store.s3.amazonaws.com/0/53034/fcd4bb3f-f6ab-f318-8229-907010691c41.png)

sourceforge に移動して，自動的にダウンロードが開始される．開始されない場合は，ウェブページの指示に従って direct link をクリックする．

## パッケージの展開

ダウンロードした opencv-3.0.0.exe を実行する．
パッケージの展開(解凍)先を尋ねられるので，C:\\ を指定し，Extract をクリックする．
![opencv-download-02.png](https://qiita-image-store.s3.amazonaws.com/0/53034/fbeaa49b-1176-1b49-42d9-8b91a17aecb5.png)

C:\opencv 以下にパッケージの内容が展開される．

## 環境の設定

展開したフォルダには，Visual Studio ですぐ使用できるように，コンパイル済みのライブラリが何種類か用意されている．Visual Studioのバージョンと，対応プラットフォーム(x86: 32ビットバイナリ か x64: 64ビットバイナリ)によって，どれを選択するべきかが決まる．Visual Studio 2013 を使用するのであれば，vc12を選択する．またプラットフォームは適切なものを指定する．32ビット用の方が安定している場合もある一方，64ビット用でなければならない場合もあり，どちらを選択すべきかは一概には言えない．ここでは主に32ビット用(x86)で説明する．64ビット用を使用するならば，x86 を x64 に読み替える．

以下では，Visual Studio 2013を用いて，32ビットバイナリと，64ビットバイナリの，両方の開発を行えるように設定を行う．

## DLLファイルのコピー

64ビット版Windowsでは，ややこしいことであるが，32ビット用DLLは `C:\Windows\SysWOW64` に，64ビット用DLLは `C:\Windows\System32` に置かれる．したがって，

* 32ビット用: `C:\OpenCV\build\x86\vc12\lib\*.dll` は `C:\Windows\SysWOW64` にコピー
* 64ビット用: `C:\OpenCV\build\x64\vc12\lib\*.dll` は `C:\Windows\System32` にコピー

することで，適切なDLLが実行時に使用される．

## Visual Studio 2013 の設定

開発環境である Visual Studio に，OpenCV を利用するための設定を行う．

設定方法には，プロジェクトを作成するたびに設定する方法と，Visual Studio 共通の環境として設定する方法の2種類がある．
後者の方が後々の手間が省けるので，こちらを解説する．

### 32ビットバイナリ(x86プラットフォーム)の場合

まず，適当な名前(ここでは例としてdummy)のWin32コンソールアプリケーションを作成する．作成方法については，<http://qiita.com/imura/items/62fe7e09740666a5ea8e>を参照．

メニューバーの 表示 > その他のウィンドウ > プロパティマネージャー を選択すると，右側に「プロパティマネージャー」が表示されるので，適宜ツリーを展開(右向き三角形をクリック)して，Microsoft.Cpp.Win32.user を表示させる(DebugとReleaseの両方の中にありますが，片方のみでよいです)．
![opencv-setting-05.png](https://qiita-image-store.s3.amazonaws.com/0/53034/cb1a8b19-35fd-d463-8e17-a3bb3d3eae6e.png)

Microsoft.Cpp.Win32.user を右クリックし「プロパティ」を選択すると，Microsoft.Cpp.Win32.user プロパティページ が開く．
![opencv-setting-06.png](https://qiita-image-store.s3.amazonaws.com/0/53034/bd9efc56-06d8-7f2f-b36d-71750a2b028b.png)

共通プロパティ > C/C++ > 全般 にある「追加のインクルードディレクトリ」に `C:\OpenCV\build\include` を入力する．
もし既に何か入力されている場合は，古いバージョンのOpenCVの設定であれば削除し，そうでなければセミコロン(;)で区切って追加する．

同様にして，共通プロパティ > リンカー > 全般 にある「追加のライブラリディレクトリ」に `C:\OpenCV\build\x86\vc12\lib` を設定する．

両方の設定が終わったら，OKをクリックしてダイアログを閉じる．

Releaseの方にも Microsoft.Cpp.Win32.user という項目(プロパティシート)があるが，こちらはDebugの方を変更すると自動的に設定される(同じプロパティシートを参照している)．気になる人は確認．

プロパティシートを変更したら，プロパティマネージャーの上の方にある青いディスクのアイコンをクリックして，変更を保存する．
![opencv-setting-09.png](https://qiita-image-store.s3.amazonaws.com/0/53034/b7ae7484-558c-e3fc-83bc-9a76c603e2b0.png)

以下余談:
3.5インチフロッピーディスクを見たことの無い人も多いこの御時世でも，保存のアイコンはフロッピーディスクなのか．
(余談ここまで)

Visual Studio を終了する．
プロジェクト dummy はもう使わないので，フォルダごと削除してよい．

### 64ビットバイナリ(x64プラットフォーム)の場合

32ビットの場合と同様に，Win32コンソールアプリケーションを新規作成する．
x64プラットフォームの設定は http://qiita.com/imura/items/076196b50f105c3138f7 を参照．設定を行うと，プロパティマネージャーの中に Debug | x64 と Release | x64 が現れる．
適宜ツリーを展開し，Microsoft.Cpp.x64.userを表示させる．

インクルードディレクトリの方は，32ビットバイナリの設定と同じである．
共通プロパティ > C/C++ > 全般 にある「追加のインクルードディレクトリ」に `C:\OpenCV\build\include` を入力する．
もし既に何か入力されている場合は，古いバージョンのOpenCVの設定であれば削除し，そうでなければセミコロン(;)で区切って追加する．

リンカーの方は異なる．共通プロパティ > リンカー > 全般 にある「追加のライブラリディレクトリ」に `C:\OpenCV\build\x64\vc12\lib` を設定する．

プロパティシートの変更を保存するのは32ビットバイナリの場合と同じである．

# カメラからの画像取得

最初のプログラムとして，カメラから画像を取得して表示してみる．

## プロジェクトの作成

まず Visual Studio を起動し，先程と同じく，適当な名前(ここではcamera)のWin32コンソールアプリケーションを作成する．

## ソースコードの入力

最初に，起動するとパネルがプロパティマネージャーのままになっている場合は，タブをクリックし，ソリューションエクスプローラーに変更しておく．
![opencv-first-01.png](https://qiita-image-store.s3.amazonaws.com/0/53034/baef6825-64d6-4ab7-22ea-c36407b57d5e.png)

ソリューションエクスプローラーが表示されたら，ソースファイルの上で右クリックし，追加 > 新しい項目 を選択すると「新しい項目の追加」ダイアログが開く．
![opencv-first-02.png](https://qiita-image-store.s3.amazonaws.com/0/53034/fe8e2470-a3be-7f20-2b61-25639e2c3177.png)

「C++ファイル (.cpp)」を選択し，適当な名前(ここではMain.cpp)を入力し，「追加」をクリックする．
![opencv-first-03.png](https://qiita-image-store.s3.amazonaws.com/0/53034/4905f299-9349-9d1a-b057-dd8cc6a8d210.png)

Main.cpp を編集できる状態になるので，ソースコードを入力する．

```cpp:Main.cpp
// Main.cpp

#include <iostream>
#include <opencv2/opencv.hpp>

int main(int argc, char **argv)
{
    char *window_input = "input";
    cv::namedWindow(window_input, CV_WINDOW_AUTOSIZE);

    char *window_output = "output";
    cv::namedWindow(window_output, CV_WINDOW_AUTOSIZE);

    cv::VideoCapture cap;
    cap.open(0);
    if (!cap.isOpened()) {
        std::cerr << "cannot find camera" << std::endl;
        return -1;
    }

    while (1) {
        cv::Mat frame;
        cap >> frame;
        cv::Mat gray;
        cv::cvtColor(frame, gray, CV_BGR2GRAY);

        cv::imshow(window_input, frame);
        cv::imshow(window_output, gray);

        int key = cv::waitKey(10);
        if (key == 3 || key == 27 || key == 'q') {
            break;
         }
    }

    return 0;
}
```

## ライブラリの設定

OpenCVを使う場合には，ライブラリを指定する必要がある．

ソリューションエクスプローラーのプロジェクト名(ここではcamera)の上で右クリックし，一番下のプロパティを選択すると，cameraプロパティページが開く．
![opencv-first-04.png](https://qiita-image-store.s3.amazonaws.com/0/53034/853f0f5d-bb7d-b908-29bf-2950180ab512.png)

左上の構成を Debug に変えて，左側のツリービューで構成プロパティ > リンカー > 入力 を選択する．追加の依存ファイル を選択すると，右側に下向き矢印が現れる．これを左クリックして <編集> を選択する．
![opencv-first-05.png](https://qiita-image-store.s3.amazonaws.com/0/53034/dad8e8e6-26c1-b558-1204-1ab485ee5bec.png)

ダイアログ「追加の依存ファイル」が現れるので，上のテキストエリアにopencv\_world300d.lib と入力し，OKをクリックする．プロパティページに戻ったら，「適用」をクリックする．
![opencv-first-06.png](https://qiita-image-store.s3.amazonaws.com/0/53034/e42f7386-c34f-4149-0a80-0420441acc2a.png)

ついでなので，左上の構成を Release に変える．同じく 構成プロパティ > リンカー > 入力 の 追加の依存ファイル の項目に，今度は opencv\_world300.lib を追加する．ファイル名の末尾は 300d ではなく 300 であることに注意する．プロパティページに戻ったら，「OK」で設定を反映させる．

## 実行

Visual Studio でのプログラムの実行については，いくつか方法がある．

* メニューから ビルド > ソリューションのビルド を選択し，その後，
  やはりメニューから デバッグ > デバッグ開始 を選択．
* メニューバーの 「ローカルWindowsデバッガー」をクリック．
* ソリューションエクスプローラーのプロジェクト名(camera)の上で右クリックし，
  デバック > 新しいインスタンスを開始 を選択．

いずれでもよい．
64ビットバイナリを作成する場合には，http://qiita.com/imura/items/076196b50f105c3138f7 を参照して，プラットフォームの設定を変更しておくこと．

カメラを接続して(ノートPCの内蔵カメラでもよい)実行すると，入力ミスなどがなければ，ウィンドウが2枚開き，一方ではカラーの，もう一方ではモノクロの映像が開く．
![opencv-first-07.png](https://qiita-image-store.s3.amazonaws.com/0/53034/8a6d0f02-97d4-e8f0-3421-401a1e133c16.png)

## ライブラリ名のバージョン依存性解消マクロ

OpenCVのライブラリ名は，バージョンとdebug/releaseの情報に基づいて決まっているため，ライブラリのバージョンが上がるとライブラリ名の指定を変える必要があり，またdebugとreleaseで別々のライブラリを指定しなければならない．面倒である．

この手間を軽減するために，OpenCVのヘッダファイルで定義されているバージョン情報を参照して，ライブラリのバージョンに合わせてリンクするライブラリ名を自動で決定するマクロ cv\_lib\_macro.h を準備する．Visual Studio でのみ動作する．

```cpp:cv_lib_macro.h
// cv_lib_macro.h

#ifndef CV_LIB_MACRO_H_
#define CV_LIB_MACRO_H_

#define CV_LIB_PREFIX comment(lib, "opencv_"

#define CV_LIB_VERSION CVAUX_STR(CV_MAJOR_VERSION)\
    CVAUX_STR(CV_MINOR_VERSION)\
    CVAUX_STR(CV_SUBMINOR_VERSION)

#ifdef _DEBUG
#define CV_LIB_SUFFIX CV_LIB_VERSION "d.lib")
#else
#define CV_LIB_SUFFIX CV_LIB_VERSION ".lib")
#endif
    
#define CV_LIBRARY(lib_name) CV_LIB_PREFIX CVAUX_STR(lib_name) CV_LIB_SUFFIX

#endif // CV_LIB_MACRO_H_
```

使い方は以下の通り．

* プロジェクトのフォルダに cv\_lib\_macro.h を置く．
* ソリューションエクスプローラーで，ヘッダーファイルの上で右クリックし，追加 > 既存の項目 を選択して，cv\_lib\_macro.h を追加する．
* ソースファイル中で cv\_lib\_macro.h をインクルードする．また追加のライブラリの指定はソースファイル中で行う．

```cpp:
#pragma CV_LIBRARY(world)
```
* 最初のプロジェクトのプロパティで，追加の依存ファイルとして設定した opencv\_world300.lib (Release) と opencv\_world300d.lib (Debug) は，いずれも設定が必要なくなるため，削除する．

ソースファイルの冒頭部分は以下のようになる．

```cpp:Main.cpp
// Main.cpp

#include <iostream>
#include <opencv2/opencv.hpp>
#include "cv_lib_macro.h"

#pragma CV_LIBRARY(world)

int main(int argc, char **argv)
{
    :
```

これで，ライブラリのバージョンが変わっても，ソースコードやVisual Studioのプロジェクトのプロパティに修正を加える必要が無くなる．