mieki256's diary



2023/05/29(月) [n年前の日記]

#1 [cg_tools] MiDaSの動かし方が分かったのでメモ

1枚の静止画像から奥行きを推測してデプスマップ(深度マップ、z map)を作れる MiDaS というアルゴリズム? AI? が気になった。

_MiDaS | PyTorch
_GitHub - isl-org/MiDaS

ローカル環境で動かせるようにするための手順が分かったので一応メモ。

環境は以下。
AI関係のプログラムだから動かすためにはGPUが必要なのかなと思っていたけど、CPUだけでも処理できるっぽい。その分処理時間は増えてしまうのだろうけど、数秒で結果が得られてるようなので、その程度の処理時間で済むならCPUで処理しても問題無いかなと…。まあ、リアルタイムに処理したいとか、膨大な枚数を処理したい場合は、GPUが必要になるのかも。

導入手順をざっくりと列挙すると、以下のような感じ。
  1. github から MiDaS関連のファイル群を git clone で入手。
  2. Pythonの仮想環境を作成。
  3. MiDaSの動作に必要なPythonモジュールをインストール。
  4. 学習モデルデータを入手して weights フォルダに入れる。
  5. run.py を実行して動作確認。

githubからクローン :

以下のページから、git を使ってプロジェクトファイル?一式をクローンする。

_GitHub - isl-org/MiDaS

今回は、D:\aiwork\midas\ というフォルダを作成して、その中で作業してみた。

git clone https://github.com/isl-org/MiDaS.git

MiDaS というフォルダが作られて、ファイル一式がダウンロードされた。

Pythonの仮想環境を作成 :

MiDaS を動かすためには、Pyhonの色々なモジュールが必要になる。普段利用してるPython環境にそれらのモジュールをインストールしてしまうと、各モジュールのバージョン管理が面倒になるので、仮想環境を作成して、その中で作業することにしたい。

MiDaSフォルダの中に入って、venv を使って仮想環境を作成。
cd MiDaS
python -m venv venv
  • -m venv : venv というモジュールを使え、と指示してる。
  • 最後の venv はフォルダ名(ディレクトリ名)。venv というフォルダの中に仮想環境を作れ、と指示してる。フォルダが無かったら自動でフォルダ作成してくれる。

venv というフォルダが作成されて、その中にPythonの環境が入った。

仮想環境のPythonに切り替える。
venv\Scripts\activate

インストールされているモジュールの一覧を表示する。
pip list
(venv) D:\aiwork\midas\MiDaS> pip list
Package    Version
---------- -------
pip        22.2.1
setuptools 63.2.0

[notice] A new release of pip available: 22.2.1 -> 23.1.2
[notice] To update, run: python.exe -m pip install --upgrade pip

pip と setuptools、2つのモジュールしか入ってない奇麗な状態。

ところで、「pipの新しいバージョンがあるよ」「python.exe -m pip install --upgrade pip を実行して更新できるよ」と表示されてるので、一応更新しておく。
python.exe -m pip install --upgrade pip

必要なモジュールをインストール :

githubから入手したファイル群の中に environment.yaml というファイルがある。この中に、使っているモジュールのバージョンが記録されていた。引用してみる。

environment.yaml
name: midas-py310
channels:
  - pytorch
  - defaults
dependencies:
  - nvidia::cudatoolkit=11.7
  - python=3.10.8
  - pytorch::pytorch=1.13.0
  - torchvision=0.14.0
  - pip=22.3.1
  - numpy=1.23.4
  - pip:
    - opencv-python==4.6.0.66
    - imutils==0.5.4
    - timm==0.6.12
    - einops==0.6.0

試したところ、これらのバージョンを使わないと、よく分からないエラーがバンバン出てしまったので…。バージョンを指定しつつモジュールをインストールしていく。

ちなみに、MiDaS を動かすにあたって重要なのは timm というモジュールっぽい。このモジュールをインストールすれば、MiDaS を動かすために必要なモジュールのほとんどがインストールできてしまう模様。ただ、依存してるモジュールのバージョンまで合わせてくれるわけではないらしい…。最新版のモジュールが入ってしまう…。

pip を使ってインストールしていく。
pip install timm==0.6.12
pip install torchvision==0.14.0
pip install torch==1.13.0
pip install numpy==1.23.4
pip install einops==0.6.0
pip install imutils==0.5.4
pip install opencv-python==4.6.0.66

他に、opencv-contrib-python も必要っぽい。これを入れないとエラーが出てしまった。また、サンプルスクリプトを眺めると、matplotlib も必要になりそう。インストールしておく。
pip install opencv-contrib-python==4.6.0.66
pip install matplotlib

インストールされたモジュール一覧を確認。environment.yaml に記述されたバージョンと一致してるか確認しておく。
> pip list
Package               Version
--------------------- --------
certifi               2023.5.7
charset-normalizer    3.1.0
colorama              0.4.6
contourpy             1.0.7
cycler                0.11.0
einops                0.6.0
filelock              3.12.0
fonttools             4.39.4
fsspec                2023.5.0
huggingface-hub       0.14.1
idna                  3.4
imutils               0.5.4
Jinja2                3.1.2
kiwisolver            1.4.4
MarkupSafe            2.1.2
matplotlib            3.7.1
mpmath                1.3.0
networkx              3.1
numpy                 1.23.4
opencv-contrib-python 4.6.0.66
opencv-python         4.6.0.66
packaging             23.1
Pillow                9.5.0
pip                   23.1.2
pyparsing             3.0.9
python-dateutil       2.8.2
PyYAML                6.0
requests              2.31.0
setuptools            63.2.0
six                   1.16.0
sympy                 1.12
timm                  0.6.12
torch                 1.13.0
torchvision           0.14.0
tqdm                  4.65.0
typing_extensions     4.6.2
urllib3               2.0.2

学習モデルデータを入手 :

MiDaS を動かすためには学習モデルデータも必要。この学習モデルデータは、精度が高いけど容量が大きいもの、精度は低いけど容量が少なくて済むもの ―― 色々な種類がある。

_GitHub - isl-org/MiDaS
_Release MiDaS 3.1 - isl-org/MiDaS - GitHub
_Release MiDaS v3 (DPT) - isl-org/MiDaS - GitHub

上記ページから、dpt_beit_large_512, dpt_hybrid_384 等々の学習モデルデータを入手する。ファイルの拡張子は .pt。

今回は以下のファイルを入手してみた。
dpt_beit_large_512.pt (1.5GB)
dpt_hybrid_384.pt (470MB)
dpt_large_384.pt (1.3GB)
dpt_levit_224.pt (196MB)
dpt_swin2_large_384.pt (840MB)
dpt_swin2_tiny_256.pt (165MB)

各 .pt を入手できたら、weights というフォルダの中にコピーする。

余談。各ファイル名についている 512, 384, 256, 224 という数字は、512x512, 384x384, 256x256, 224x224 で学習したよ、という意味らしい。

余談その2。画像生成AI Stable Diffusion web UI の ControlNet で使っているのは、dpt_hybrid_384.pt だった。

余談その3。学習モデルデータも含めて、全体のファイル群は、5.55GBになった。

テスト画像を入手 :

テストする画像を入手して、inputフォルダの中に入れておく。おそらく、pngの他にjpgもイケそう。公式サイトのサンプルでは犬の写真画像を使ってたので、それに倣ってみる。以下から入手。

_hub/dog.jpg at master - pytorch/hub - GitHub

dog.jpg をダウンロードして、inputフォルダに入れた。

サンプルスクリプトを実行 :

githubから入手したファイル群の中に、run.py というPythonスクリプトがある。このスクリプトを実行することで MiDaS の動作確認ができるらしい。

python run.py --model_type dpt_hybrid_384 --input_path input --output_path output
  • --model_type dpt_hybrid_384 : 学習モデルデータとして dpt_hybrid_384 を指定。別の学習モデルデータを使いたい時は変更する。
  • --input_path input : 画像が入ってるフォルダを指定。inputフォルダを指定してる。
  • --output_path output : 結果画像の保存先フォルダを指定。outputフォルダを指定してる。

実行すると、こうなった。
(venv) D:\aiwork\midas\MiDaS> python run.py --model_type dpt_hybrid_384 --input_path input --output_path output
Initialize
Device: cpu
Model loaded, number of parameters = 123M
Start processing
  Processing input\dog.jpg (1/1)
    Input resized to 480x384 before entering the encoder
Finished
「Device: cpu」と表示されてるので、GPUではなくCPUで処理してるのだろう…。また、「入力された画像を 480x384 にリサイズしてから処理してるよ」とも表示されてる。

outputフォルダ内に、以下の2つのファイルが生成された。
dog-dpt_hybrid_384.pfm
dog-dpt_hybrid_384.png

.png はPNG画像だろうけど、.pfm とは何ぞや。

_画像フォーマット

PFM = Portable Float Map、らしい。Float…? それはつまり、各ドットの情報を浮動小数点数で持ってるということだろうか。1チャンネル8bitしか情報を持ってないPNGと比べたら、めっちゃ豊かな情報を持ってそう。

さておき。.png はフツーに表示できる。

dog-dpt_hybrid_384.png

たしかにデプスマップを得られた。これで MiDaS をローカル環境で動かすことができた…。


ところで、run.py に渡す --model_type で学習モデルデータを指定できるのだけど、公式ページのドキュメントでは以下が指定できると書いてあった。もちろん、学習モデルデータ(.pt)を入手して weightsフォルダに入れてあればの話。
dpt_beit_large_512
dpt_beit_large_384
dpt_beit_base_384
dpt_swin2_large_384
dpt_swin2_base_384
dpt_swin2_tiny_256
dpt_swin_large_384
dpt_next_vit_large_384
dpt_levit_224
dpt_large_384
dpt_hybrid_384
midas_v21_384
midas_v21_small_256
openvino_midas_v21_small_256

謎の警告が少し気になる :

学習モデルデータとして dpt_beit_large_512 を指定すると、何故かエラーが、というか警告が出る…。一応、結果画像は得られるのだけど…。
(venv) D:\aiwork\midas\MiDaS> python run.py --model_type dpt_beit_large_512 --input_path input --output_path output
Initialize
Device: cpu
D:\aiwork\midas\MiDaS\venv\lib\site-packages\torch\functional.py:504: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at ..\aten\src\ATen\native\TensorShape.cpp:3191.)
  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]
Model loaded, number of parameters = 345M
Start processing
  Processing input\dog.jpg (1/1)
    Input resized to 640x512 before entering the encoder
Finished

「今後のリリースではインデックス引数が必要になりますよ」と言ってるようだけど…。コレ、どうすればいいんだろう…?

MiDaS 3.0 の学習モデルデータを使うとこの警告は出てこないけど、MiDaS 3.1 の学習モデルデータを使うと出てくるようではあるなと…。

グレイスケール画像で出力したい :

現状の run.py は、人間が目で見て分かりやすくするために、デプスマップを色付きの画像で出力しているけれど。他の何かに渡して処理したい場合、グレースケール画像で出力してくれたほうが嬉しいわけで…。

そんな時は、--grayscale をつければいいらしい。
python run.py --model_type dpt_large_384 --input_path input --output_path output --grayscale

dog-dpt_large_384.png

たしかにグレースケールになった。

その他のオプション :

run.py に --help をつければ、ヘルプが表示される。
> python run.py --help
usage: run.py [-h] [-i INPUT_PATH] [-o OUTPUT_PATH] [-m MODEL_WEIGHTS] [-t MODEL_TYPE] [-s]
              [--optimize] [--height HEIGHT] [--square] [--grayscale]

options:
  -h, --help            show this help message and exit
  -i INPUT_PATH, --input_path INPUT_PATH
                        Folder with input images (if no input path is specified, images are tried
                        to be grabbed from camera)
  -o OUTPUT_PATH, --output_path OUTPUT_PATH
                        Folder for output images
  -m MODEL_WEIGHTS, --model_weights MODEL_WEIGHTS
                        Path to the trained weights of model
  -t MODEL_TYPE, --model_type MODEL_TYPE
                        Model type: dpt_beit_large_512, dpt_beit_large_384, dpt_beit_base_384,
                        dpt_swin2_large_384, dpt_swin2_base_384, dpt_swin2_tiny_256,
                        dpt_swin_large_384, dpt_next_vit_large_384, dpt_levit_224, dpt_large_384,
                        dpt_hybrid_384, midas_v21_384, midas_v21_small_256 or
                        openvino_midas_v21_small_256
  -s, --side            Output images contain RGB and depth images side by side
  --optimize            Use half-float optimization
  --height HEIGHT       Preferred height of images feed into the encoder during inference. Note
                        that the preferred height may differ from the actual height, because an
                        alignment to multiples of 32 takes place. Many models support only the
                        height chosen during training, which is used automatically if this
                        parameter is not set.
  --square              Option to resize images to a square resolution by changing their widths
                        when images are fed into the encoder during inference. If this parameter
                        is not set, the aspect ratio of images is tried to be preserved if
                        supported by the model.
  --grayscale           Use a grayscale colormap instead of the inferno one. Although the inferno
                        colormap, which is used by default, is better for visibility, it does not
                        allow storing 16-bit depth values in PNGs but only 8-bit ones due to the
                        precision limitation of this colormap.

-i input, -o output, -t dpt_hybrid_384 といった記述も指定できるっぽいな…。

run.py を眺めてみたけど、--model_type を指定しない場合、dpt_beit_large_512 がデフォルトで指定される模様。

Webカメラからの入力 :

試しに python run.py だけで動かしたら、ウインドウが表示されて何かを表示し続けてるようではあった。

DOS窓には「No input path specified. Grabbing images from camera.」と表示されてたので、Webカメラの入力を処理しようとしてたっぽい。でも、自分のPC、Webカメラついてないんですけど…。ウインドウを閉じて強制終了した…。

せっかくだから、Webカメラからの入力も試してみた。USB接続Webカメラ BUFFALO BSWHD01 を部屋から発掘して接続。python run.py を実行。こんな感じになった。

midas_webcamera_ss01.png

たしかに、Webカメラからの入力に対して処理できてるようだなと…。

DOS窓上では「FPS: 0.47」と表示されていた。1フレームを数秒かけて処理して返してる状態なのだな…。もしかするとGPUで処理できたらもっと速く結果が得られるのだろうか。

ウインドウのタイトルに「ESCキーで抜けられるよ」と書いてあることに気づいた。ESCキーを数秒間ポンポンポンと連打していたら、ウインドウが閉じてくれた。

参考ページ :

余談 :

MiDaS を触っていてふと思ったことをなんとなくメモ。思考メモ。

奥行き情報を取得しようとする場合、本来であれば2台のカメラで撮影して視差情報を利用して、とかやらないといかんのだろうと思うのだけど。1枚の静止画像から「たぶんこんな感じじゃねえかなあ」とAIが奥行き情報を作ってくれるなんて、スゴイことになってるなと…。仕組みを実現してしまった方々、凄過ぎる…。

もっとも、人間だって写真やTV映像を見て、「この人は手前に立っている」「この建物は奥にある」などと無意識に推測しながら認識してるわけで。

視差情報も無いのにどうしてそんなことができるかと言えば、それはやはり学習の賜物。自分の身の回りの風景を二つの目で捉えて距離感を測る訓練を延々してきたから、単眼で捉えた視覚情報に対しても前後関係を推測することができているのだろうなと。そう考えると、人間ってなかなかスゴイことしてるなと…。

そして、「人間が学習で能力を獲得しているのだから、コンピュータだって学習すれば似たようなことができらあ!」と ―― ある種乱暴だけど楽観的な思考が根底にあるから、こういった技術がここまで発達してきたような、そんな気もする。と言っても、何をどう学習させるか、そこが閃かなかったらどうにもならないのだろうけど。

余談その2 :

妄想メモ。

1枚の静止画像から奥行き情報を推測できるなら…。別々の方向から撮影した数枚の画像があれば、色んな方向から見た深度情報を得られるよなと。その複数の深度情報を擦り合わせていったら、より正確な3D形状を得られたりしないだろうか。などと妄想。

でも、複数の方向から撮影できてる時点でそこには視差情報が含まれてるから、ソレを使って形状を構成するほうが妥当な気もしてきた。

まあ、そういう研究は既に誰かがやってるだろう…。というか、スマホで数枚撮影してそこから形状を作ってしまうサービスを結構前にどこかで見かけた気もするし…。

MiDaSのような技術は、「一枚の静止画しかないですけどコレ使ってとにかくどうにかしてください」というある種縛りプレイを強要される状況でこそ使える技術、だよな…。「もし必要なら色んな方向から撮影できますよ」と言ってもらえる恵まれた状況なら別の技術を使ったほうが…。

以上、1 日分です。

過去ログ表示

Prev - 2023/05 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project