PythonでOpenCVからGStreamerを使うためのOpenCV4.6.0のBuildについて

## 概要
GStreamerはデータの送受信をパイプライン的に処理できる仕組みで、映像送受信に使うと便利です。さらに映像送受信時に合わせてOpenCVで映像処理することも可能です。
GStreamerとOpenCVを組み合わせるにはOpenCVからGStreamerを呼び出す方法が一般的です。しかしOpenCVからGStreamerを呼び出すためににはOpenCVをソースコードからビルドする必要があり、加えてWindows環境で使用できるようにするまでに苦労したのでその手順を記載したいと思います。

## 実行環境
- Windows11
- CMake 3.24.2
- Visual studio communication 2019
- GStreamer 1.16.2
- OpenCV 4.6.0
- Python 3.10

## 前提
以下のサイトを参考に進めていきますが、Versionが古いものは新しくしています

https://towardsdatascience.com/opencv-with-gstreamer-and-qt-on-windows-6f0fdb075993

### CMakeのインストール
- [以下](https://cmake.org/download/)よりインストール下さい

https://cmake.org/download/

- Pathを通してコマンドプロンプトで実行できるようにして下さい
- 確認コマンド
```
> cmake --version
cmake version 3.24.2

CMake suite maintained and supported by Kitware (kitware.com/cmake).
```

### GStreamerのインストール
- 以下より`runtime installer`と`development installer`をインストールしてください 
   + [1.16.2 runtime installer](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-msvc-x86_64-1.16.2.msi)
   +  [1.16.2 development installer](https://gstreamer.freedesktop.org/data/pkg/windows/1.16.2/gstreamer-1.0-devel-msvc-x86_64-1.16.2.msi)

- Pathを通して使用可能にします
- Version確認
```
> gst-inspect-1.0 --version
gst-inspect-1.0 version 1.16.2
GStreamer 1.16.2
Unknown package origin
```
- 動作確認
```
> gst-launch-1.0 videotestsrc ! autovideosink
```
以下のようにテスト画像が表示されます
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/4df7f317-cf68-746e-563e-87c61c348298.png)

## Pythonの必要パッケージのインストール
- Pythonのインストール自体は解説しません
- Numpyのインストール
```
> pip install numpy
> pip list
# numpyがあることを確認
```
　- 既存のopen cvのアンインストール
```
> pip uninstall opencv-python
> pip uninstall opencv-contrib-python
> pip list
# opencv-pythonがopencv-contrib-pythonが無いことを確認
```
## Visual Studio Communication のインストール
- Version2019を使用してください
- ダウンロードサイトは以下です

https://visualstudio.microsoft.com/ja/vs/older-downloads/

## OpeCVのソースコードダウンロード
- `opencv`と`opencv_contrib`のソースコードが必要です
- 以下より`opencv`を

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

- 以下より`opencv_contrib`を

https://github.com/opencv/opencv_contrib/releases/tag/4.6.0

- zipのダウンロードか`git clone`でソースコードを展開してください

## OpenCVのBuild設定
### buildフォルダの作成
```
>cd opencv-4.6.0
> mkdir build
```
### CMakeの起動
- **OpenCVのコンパイルの設定**を行います。
- この中で使用する**GStreamerやPython等の設定**を行います。
- インストールしたCMakeアプリを起動してください
- `source codeフォルダ`に展開した`opencv`のフォルダを指定ください
- `buildフォルダ`に作成した`build`フォルダを指定ください
- まずは`Configure`を実行してください。
- 今後、`Configure`はこまめに実行ください。新たな設定等が現れたりします。
- 起動画面
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/cd74edd9-5925-eef3-c2b0-ac88cf775e0a.png)

## GStreamerの設定
- 以下の画像を参考にしてください
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/eb5aa982-ad9d-8233-3037-d3c60197f70b.png)


## Pythonの設定
- 以下の画像を参考にしてください
- ’PYTHON_NUMPY_INCLUDE_DIRS’の設定は必要です。
- Python2の設定は不要です
![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/e0f2fb06-f888-08a7-1cf7-19eacbc32507.png)


## FFMpegの無効化
- GStreamerと相性が悪いとの話もあり、できれば無効化してください。必項ではありません

![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/d6c8e243-826b-eafa-77ad-373e15ddc8d6.png)

## `Generate`の実行
- 上記設定が終了したら、 `Generate`ボタンを押して `Generate`してください
- 出力を結果について以下を参考に問題ないか確認ください
- GStreamerが`YES`になっている
- PythonのPathがただしい

```
General configuration for OpenCV 4.6.0 =====================================
  Version control:               unknown

  Extra modules:
    Location (extra):            C:/Users/tigri/work/opencv_contrib-4.6.0/modules
    Version control (extra):     unknown

# 省略

  Platform:
    Timestamp:                   2022-10-14T07:30:18Z
    Host:                        Windows 10.0.22000 AMD64
    CMake:                       3.24.2
    CMake generator:             Visual Studio 16 2019
    CMake build tool:            C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe

# 省略

  Video I/O:
    DC1394:                      NO
    GStreamer:                   YES (1.16.2)
    DirectShow:                  YES
    Media Foundation:            YES
      DXVA:                      YES

# 省略


  Python 3:
    Interpreter:                 C:/Python310/python.exe (ver 3.10.4)
    Libraries:                   C:/Python310/libs/python310.lib (ver 3.10.4)
    numpy:                       C:/Python310/Lib/site-packages/numpy/core/include (ver 1.23.3)
    install path:                C:/Python310/Lib/site-packages/cv2/python-3.10

  Python (for build):            C:/Python310/python.exe

# 省略
-----------------------------------------------------------------

```

## OpenCVのBuild
- 以下を参考に`VisualStudioComunication2019`にて実行ください

https://towardsdatascience.com/opencv-with-gstreamer-and-qt-on-windows-6f0fdb075993

- インストールをビルドするとPythonにOpenCVがライプラリとしてインストールされます
- Pythonのフォルダ内に`{your_python_paht}\Lib\site-packages\cv2`が作成されていることを確認ください

## Pythonでの確認
- 以下を実行し`GStreamer: YES (1.16.2)`がある事を確認ください

:::note info
**GStreamerのDLL**を`import cv2`前に
`os.add_dll_directory('{your_gstreamer_path}/1.0/x86_64/bin')`
にて設定しないと`「ImportError: DLL load failed while importing cv2: The specified module could not be found.」`エラーが発生する場合があります。環境によっては出ない場合があります。
:::



```
>　python
Python 3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.add_dll_directory('C:/gstreamer/1.0/x86_64/bin') ## DLLファイルを指定
<AddedDllDirectory('C:/gstreamer/1.0/x86_64/bin')>
>>> import cv2　## OpenCVの読み込み
>>> print(cv2.getBuildInformation())

General configuration for OpenCV 4.6.0 =====================================

# 省略

  Video I/O:
    DC1394:                      NO
    GStreamer:                   YES (1.16.2)
    DirectShow:                  YES
    Media Foundation:            YES
      DXVA:                      YES

# 省略
>>>

```

## PythonでOpenCVからGStreamerを使う
- Pythonの実行コード
```py
## GStreamerのDLLを’import cv2’前にセットします
import os
## GStreamerのインストールに合わせてpathをセットしてください
os.add_dll_directory('C:/gstreamer/1.0/x86_64/bin')

## OpenCV読み込み
import cv2

## GStreamerデータのキャプチャ作成
cap = cv2.VideoCapture("videotestsrc ! videoconvert ! appsink")

while True:
     ## GStreamerデータのキャプチャ読み込み
    ret, img = cap.read()
    if not ret:
        break

    ## ここに画像処理を書く
    

    ## キャプチャイメージの表示
    cv2.imshow("img",img)
    
    ## ブレーク処理
    key = cv2.waitKey(1)
    if key==27: #[esc] key
        break
```
- 実行結果
以下のようなTest映像が表示されます

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852908/efe66493-5aed-9bb0-b35a-002d45431bf6.png)

## 最後に
最後の**PythonでOpenCVからGStreamerを使う**事態は非常に簡単ですが、Buildに時間がかるのと、Windows環境でGStreamerの使用時には事前にDLLファイルの場所の設定が必要なことが判明するまで大変時間がかかりました。