[Docker + OpenVINO] 白黒画像に色を付けるデモを動かす

# 概要
下記のデモを実行してみたところ、ソースが古いこともありそのままでは動きませんでした。
各種修正を加えて動作させるところまでやってみます。

Ubuntuコンテナ上のOpenVINOで黒と白の写真を着色する方法
https://www.docker.com/ja-jp/blog/how-to-colorize-black-white-pictures-ubuntu-containers/

# 環境
wsl2 Ubuntu 22.04.3 LTS
docker 27.2.0
docker-compose  2.29.2

# 試す
ターミナルでwslを実行
```
wsl -d Ubuntu
```
[ここ](https://github.com/valentincanonical/colouriser-demo)からソースをクローン
```
$ git clone https://github.com/valentincanonical/colouriser-demo.git
```

colouriser-demo配下にdocker-compose.yamlがあるので今回はこれを使用する。
```
$ cd colouriser-demo
$ sudo docker-compose up
```

## frontendでエラーが発生
```
~~~
 => [frontend base 2/6] WORKDIR /app                                                                               1.1s
 => [frontend base 3/6] COPY package*.json ./                                                                      0.1s
 => ERROR [frontend base 4/6] RUN npm install                                                                     10.6s
------
 > [frontend base 4/6] RUN npm install:
9.262 npm error code 1
9.262 npm error path /app/node_modules/node-sass
9.262 npm error command failed
9.262 npm error command sh -c node scripts/build.js
~~~
9.262 npm error gyp info using node@22.8.0 | linux | x64
~~~
```
frontendのnpm installでエラーが発生している模様

エラーでググって[こちら](https://qiita.com/mitsuaki1229/items/4efe5350d18fd22dfa18)の記事を発見
どうやらnodeのバージョンが新しすぎるらしい

frontendのDockerfileを確認
```php:frontend/Dockerfile
FROM node AS base

WORKDIR /app

COPY package*.json ./
RUN npm install
~~~
```
最新版を見ていたためバージョンを指定
```php:frontend/Dockerfile
FROM node:16.0.0 AS base
```

`docker-compose up --build`実行

frontendのエラーは解消し起動はした

## backendでエラーが発生
```
backend-1      | Traceback (most recent call last):
backend-1      |   File "backend.py", line 5, in <module>
backend-1      |     from colorize import colorize_image
backend-1      |   File "/app/colorize.py", line 6, in <module>
backend-1      |     from ovmsclient import make_grpc_client, make_tensor_proto
backend-1      |   File "/opt/venv/lib/python3.8/site-packages/ovmsclient/__init__.py", line 39, in <module>
backend-1      |     from ovmsclient.tfs_compat.grpc.tensors import make_tensor_proto as make_tensor_proto
backend-1      |   File "/opt/venv/lib/python3.8/site-packages/ovmsclient/tfs_compat/grpc/tensors.py", line 26, in <module>
backend-1      |     class TensorType(NamedTuple):
backend-1      |   File "/usr/lib/python3.8/typing.py", line 1619, in __new__
backend-1      |     nm_tpl = _make_nmtuple(typename, types.items())
backend-1      |   File "/usr/lib/python3.8/typing.py", line 1593, in _make_nmtuple
backend-1      |     types = [(n, _type_check(t, msg)) for n, t in types]
backend-1      |   File "/usr/lib/python3.8/typing.py", line 1593, in <listcomp>
backend-1      |     types = [(n, _type_check(t, msg)) for n, t in types]
backend-1      |   File "/usr/lib/python3.8/typing.py", line 149, in _type_check
backend-1      |     raise TypeError(f"{msg} Got {arg!r:.100}.")
backend-1      | TypeError: NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type Got <member 'type' of 'numpy.dtype' objects>.
```

直接エラーが出ている場所は"backend.py"
で辿っていくと、
"ovmsclient"や"typing.py"がエラーに関わっていそう
最下行を見るに、NamedTupleのなんちゃらはnumpy.dtypeじゃないといけないらしい？
```
backend-1      | TypeError: NamedTuple('Name', [(f0, t0), (f1, t1), ...]); each t must be a type Got <member 'type' of 'numpy.dtype' objects>.
```

ovmsclientのソースを確認
[ovmsclientのリポジトリの該当ソース](https://github.com/openvinotoolkit/model_server/blob/main/client/python/ovmsclient/lib/ovmsclient/tfs_compat/grpc/tensors.py)
タイプの渡し方が良くなさそう
```php:tensors.py
class TensorType(NamedTuple):
    NumpyPrimaryType: np.dtype.type <= これがよくない？？
    TensorDtype: str
    TensorProtoField: str
```

この行はいつ追加されたのかコミット履歴を確認
2023/3/15に[#1703](https://github.com/openvinotoolkit/model_server/commit/486d1fafbf0c42ffb27b5236d0d6789023e238b5#diff-5a7f1864603298723b1cc2eb393e490a2244624cd16d7bbfc18db754efa70f33)で追加された模様

このデモのメインブランチの最後のコミットは2022/9/23[(コミット履歴)](https://github.com/valentincanonical/colouriser-demo/commits/main/)
なので、ovmsclientのtensors.pyにあとから追加された先ほどのコードがエラー原因くさい

ovmsclientを古いバージョンにする必要がありそう

ovmsclientのインストール可能バージョン確認
```
$ sudo apt install python3-pip
$ pip install ovmsclient==
```
```
Defaulting to user installation because normal site-packages is not writeable
ERROR: Could not find a version that satisfies the requirement ovmsclient== (from versions: 0.2, 2022.1, 2022.2, 2022.3, 2023.0, 2023.1)
ERROR: No matching distribution found for ovmsclient==
```
0.2, 2022.1, 2022.2, 2022.3, 2023.0, 2023.1の中から選べそう

バックエンドのrequirements.txtを更新
```php:backend/requirements.txt
flask
flask-cors
numpy>=1.16.6,<1.20
opencv-python==4.4.0.46
ovmsclient==2022.1
```

`docker-compose up --build`実行
```
backend-1      |  * Serving Flask app 'backend'
backend-1      |  * Debug mode: off
backend-1      | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
backend-1      |  * Running on all addresses (0.0.0.0)
backend-1      |  * Running on http://127.0.0.1:5000
backend-1      |  * Running on http://172.18.0.2:5000
backend-1      | Press CTRL+C to quit
```
エラーが解消した模様

## frontendがリスタートを繰り返す問題が発生

コンテナの状況を確認
`docker-compose up -d`
`docker-compose ps`

```
NAME                            IMAGE                         COMMAND                  SERVICE       CREATED          STATUS                          PORTS
colouriser-demo-backend-1       colouriser-demo-backend       "/opt/venv/bin/pytho…"   backend       3 minutes ago    Up 2 minutes                    0.0.0.0:8080->5000/tcp, :::8080->5000/tcp
colouriser-demo-frontend-1      colouriser-demo-frontend      "/docker-entrypoint.…"   frontend      33 minutes ago   Restarting (1) 16 seconds ago
colouriser-demo-modelserver-1   colouriser-demo-modelserver   "/ovms/bin/ovms --co…"   modelserver   33 minutes ago   Up 2 minutes                    0.0.0.0:9001->9001/tcp, :::9001->9001/tcp
```
frontendがリスタートを繰り返している…
image全部消してやり直したらうまくいった
```
NAME                            IMAGE                         COMMAND                  SERVICE       CREATED         STATUS         PORTS
colouriser-demo-backend-1       colouriser-demo-backend       "/opt/venv/bin/pytho…"   backend       8 seconds ago   Up 8 seconds   0.0.0.0:8080->5000/tcp, :::8080->5000/tcp
colouriser-demo-frontend-1      colouriser-demo-frontend      "/docker-entrypoint.…"   frontend      8 seconds ago   Up 8 seconds   80/tcp, 0.0.0.0:8000->3000/tcp, :::8000->3000/tcp
colouriser-demo-modelserver-1   colouriser-demo-modelserver   "/ovms/bin/ovms --co…"   modelserver   8 seconds ago   Up 8 seconds   0.0.0.0:9001->9001/tcp, :::9001->9001/tcp
```

## ホストからfrontendに接続
ブラウザでlocalhost:8000に接続
![Screenshot 2024-09-06 233827.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032663/f3589758-4bd8-80e6-a5b5-d8cd75f45b40.png)
どうやらいけてそう

白黒画像＝＞カラー画像への変換を試してみる
![Screenshot 2024-09-06 234745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032663/b5345e9c-8f67-6318-8595-f0cd17f3cdc5.png)

COLOURISE V1
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032663/bec09e22-2819-7675-aa9c-ffcb0c91acf0.jpeg" width="500">

COLOURISE V2
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032663/212a770f-4e5d-8ba1-3ca4-00e45516eebd.jpeg" width="500">

元画像はこちら
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032663/9a19837c-34c1-0560-8708-422904de624a.jpeg" width="500">