LoginSignup
7
7

More than 3 years have passed since last update.

PIFuHDをWindows + Anaconda + Git Bash環境で実行する

Last updated at Posted at 2020-08-21

概要

PIFuHDという、1枚(or 複数枚)の写真から立体的なメッシュを生成するというDeep Learningのモデルを試したのでそのメモです。
それを、Windows環境で実行するのに色々ハマりどころがあったのでそのメモです。

GitHubに上がっている動画を引用すると、以下のようなことができるものです。

PIFuHD demo

環境構築

今回の環境はAnacondaを利用しています。(PIFuHDではPythonを利用しているのでPython環境が必要)

通常はAnacondaをインストールするとGUIもついてくるのでそこで環境の設定を行うことができます。
またそこから、Anacondaの環境が設定された状態のターミナルを起動することもできるので、コマンドラインからPythonスクリプトを実行するだけであればそれで事足ります。

しかし、色々なDeep Learningなモデルを試していると必ずShellスクリプトを扱う瞬間があります。
当然、Windowsのコマンドプロンプトでは実行できません。

ということで今回はGit for WindowsのBash環境でもAnaconda(condaコマンド)を利用するようにセットアップしたいと思います。
(PIFuHDのデモを試すだけなら.sh内のいくつかのコマンドを自分で叩けばいいだけなので必要ないと言えばないのですが)

Anacondaのインストール後、Git for Windows上でcondaコマンドが使えるように設定します。

Anacondaをインストール

まずはAnacondaをインストールします。
Anacondaのページの「Get Started」ボタンをクリックし、Install Anaconda Individual Editionをクリックしてダウンロードページに飛びます。

ダウンロードページにDownloadボタンがあるのでそれをクリックすると、ページ下部にあるダウンロードリンクの箇所までスクロールするので、そこから64-Bit Graphical Installerを選んでインストーラをダウンロードし、Anacondaをインストールします。

Pathを通す

インストールが終わったら、Bashが認識するようにはPathを通します。
するとcondaコマンド自体は認識してくれるようになります。

自分の環境では.basahrcに以下を追記しました。

export PATH=$PATH:/c/Users/[USER_NAME]/anaconda3
export PATH=$PATH:/c/Users/[USER_NAME]/anaconda3/Scripts

インストールした場所に応じて適宜書き換えてください。
デフォルトのままであれば上と同じで大丈夫だと思います。

conda activate でエラーが出る

Pathを通したあと、Anacondaの環境をActivateしようと$ conda activateを実行すると以下のようなエラーが発生しました。

$ conda activate

CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
If using 'conda activate' from a batch script, change your
invocation to 'CALL conda.bat activate'.

To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - cmd.exe
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.

以下の記事を参考に解決しました。

どうやらconda initを実行すると自動的に書き込まれるものが書き込まれないための問題のようです。
なので手動で.bashrcに以下を追記することで無事、Git for WindowsのBash上でもcondaが認識され、利用することができるようになりました。

# >>> conda init >>>
__conda_setup="$(CONDA_REPORT_ERRORS=false '$HOME/anaconda3/bin/conda' shell.bash hook 2> /dev/null)"
if [ $? -eq 0 ]; then
    \eval "$__conda_setup"
else
    if [ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]; then
        . "$HOME/anaconda3/etc/profile.d/conda.sh"
        CONDA_CHANGEPS1=false conda activate base
    else
        \export PATH="$PATH:$HOME/anaconda3/bin"
    fi
fi

unset __conda_setup
# <<< conda init <<<

これを追記してから$ source ~/.bashrcをするか、ターミナルを再起動すると無事、$ conda activate [ENV_NAME]を実行することができるようになります。
うまく環境が適用されれば、プロンプトに環境名が表示されると思います。

PIFuHD向けのセットアップ

Anacondaの環境構築が終わったら、次にPIFUHD向けのセットアップをしていきます。
GitHubのREADMEには以下のように記述されているので、これらが利用可能なようにセットアップしていきます。

Requirements

  • Python 3
  • PyTorch tested on 1.4.0, 1.5.0
  • json
  • PIL
  • skimage
  • tqdm
  • cv2

    For visualization

  • trimesh with pyembree

  • PyOpenGL

  • freeglut (use sudo apt-get install freeglut3-dev for ubuntu users)

  • ffmpeg

ちなみに手動によるセットアップについては、HDがつかないバージョンのリポジトリのREADMEに以下のように書かれているので、これを参考にセットアップしました。
(参考にしたのはOR manually setup environmentの部分です。それより上の部分はminicondaを使っていたりするので今回は参考にしていません

Windows demo installation instuction

  • Install miniconda
  • Add conda to PATH
  • Install git bash
  • Launch Git\bin\bash.exe
  • eval "$(conda shell.bash hook)" then conda activate my_env because of this
  • Automatic env create -f environment.yml (look this)
  • OR manually setup environment
    • conda create —name pifu python where pifu is name of your environment
    • conda activate
    • conda install pytorch torchvision cudatoolkit=10.1 -c pytorch
    • conda install pillow
    • conda install scikit-image
    • conda install tqdm
    • conda install -c menpo opencv
  • Download wget.exe
  • Place it into Git\mingw64\bin
  • sh ./scripts/download_trained_model.sh
  • Remove background from your image (this, for example)
  • Create black-white mask .png
  • Replace original from sample_images/
  • Try it out - sh ./scripts/test.sh
  • Download Meshlab because of this
  • Open .obj file in Meshlab

追加で必要なモジュールをインストールする

上記以外に、追加で以下のものもインストールしました。(PIFuHDのREADMEには書いてある)

それぞれ以下のようにインストールします。

$ conda install -c conda-forge trimesh
$ conda install -c anaconda pyopengl

WindowsにGLUTをインストールする

GLUTをインストールしないままにサンプルを試しに実行してみると以下のエラーが発生しました。

OpenGL.error.NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling

GLUTがないためのエラーです。
が、インストール方法が分からず、こちらの記事に助けられました。

この記事内では、さらに別の記事を参考に解消したと書かれています。
別の記事はこちら(WindowsのPythonでOpenGLを使う - TadaoYamaokaの日記

そちらから引用させていただくと、

FreeGLUTのインストール

PyOpenGLとは別に、GLUTをインストールする必要がある。
GLUTは、OpenGLをプラットフォーム非依存で扱うためのライブラリのようだ。

本家のGLUTは、Windowsの64bitのバイナリがダウンロードできない。
代わりに、64bitのバイナリが提供されているFreeGLUTを導入する。

FreeGLUTのページから
Martin Payne's Windows binaries (MSVC and MinGW)
のリンクをたどり、
Download freeglut 3.0.0 for MSVC
からfreeglut-MSVC-3.0.0-2.mp.zipをダウンロードする。

zipファイル内のfreeglut\bin\x64\にあるfreeglut.dllをC:\Windows\System32にコピーする。

これで、GLUTが使用できるようになる。

ffmpegのインストール

ffmpegのインストールについてはこちらの記事を参考にさせていただきました。

基本的にはexeファイルを落としてきて、それを保存しPathに追加して認識させるだけです。
上記記事はコマンドプロンプトで使う例ですが、今回はGit Bashを利用しているので、.bashrcに以下のようにパスを追加しました。

export PATH=$PATH:/path/to/bin/ffmpeg

Pythonファイルを修正

参考にしたこちらの記事にも書かれていますが、上記までのセットアップを終えてもなおエラーが出ました。
発生したエラーは以下。

Traceback (most recent call last):
  File "C:\Users\[USER_NAME]\anaconda3\envs\pifu\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Users\[USER_NAME]\anaconda3\envs\pifu\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "D:\MyDesktop\Python-Projects\pifuhd\apps\render_turntable.py", line 69, in <module>
    renderer = ColorRender(width=args.width, height=args.height)
  File "D:\MyDesktop\Python-Projects\pifuhd\lib\render\gl\color_render.py", line 34, in __init__
    CamRender.__init__(self, width, height, name, program_files=program_files)
  File "D:\MyDesktop\Python-Projects\pifuhd\lib\render\gl\cam_render.py", line 32, in __init__
    Render.__init__(self, width, height, name, program_files, color_size, ms_rate)
  File "D:\MyDesktop\Python-Projects\pifuhd\lib\render\gl\render.py", line 45, in __init__
    _glut_window = glutCreateWindow("My Render.")
  File "C:\Users\[USER_NAME]\anaconda3\envs\pifu\lib\site-packages\OpenGL\GLUT\special.py", line 73, in glutCreateWindow
    return __glutCreateWindowWithExit(title, _exitfunc)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

上記の記事を参考にさせてもらうと、lib/render/gl/render.py内の以下の箇所を書き換えることで解決するようです。

class Render:
    def __init__(self, width=1600, height=1200, name='GL Renderer',
                 program_files=['simple.fs', 'simple.vs'], color_size=1, ms_rate=1):
        self.width = width
        self.height = height
        self.name = name
        self.display_mode = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH
        self.use_inverse_depth = False

        global _glut_window
        if _glut_window is None:
            glutInit()
            glutInitDisplayMode(self.display_mode)
            glutInitWindowSize(self.width, self.height)
            glutInitWindowPosition(0, 0)
            # 引数の文字列の指定に`b`を加える
            #_glut_window = glutCreateWindow("My Render.")
            _glut_window = glutCreateWindow(b"My Render.")

デモを実行して結果を出力する

さて、これで本当にセットアップが完了しました。
あとは、用意されているデモ用のスクリプトを走らせるだけです。

bash ./scripts/demo.sh

これを実行すると以下のように、サンプル写真から出力された動画が表示されます。

result_test_512.gif

ちなみにこのモデルを生成する元になった写真はこちら↓

test.png

独自の写真でメッシュを生成する

まず、メッシュを生成するのに使ったShellスクリプトを見てみましょう。

# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.

python -m apps.simple_test
# python apps/clean_mesh.py -f ./results/pifuhd_final/recon
python -m apps.render_turntable -f ./results/pifuhd_final/recon -ww 512 -hh 512

内容はたったこれだけです。
ひとつコメントアウトされていますが、これは多分、前に生成したメッシュなどをクリアするかどうかでしょう。

最初の処理(apps/simple_test.py)を見てみるといくつかのパラメータを設定していました。

# Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.


from .recon import reconWrapper
import argparse


###############################################################################################
##                   Setting
###############################################################################################
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--input_path', type=str, default='./sample_images')
parser.add_argument('-o', '--out_path', type=str, default='./results')
parser.add_argument('-c', '--ckpt_path', type=str, default='./checkpoints/pifuhd.pt')
parser.add_argument('-r', '--resolution', type=int, default=512)
parser.add_argument('--use_rect', action='store_true', help='use rectangle for cropping')
args = parser.parse_args()
###############################################################################################
##                   Upper PIFu
###############################################################################################

resolution = str(args.resolution)

start_id = -1
end_id = -1
cmd = ['--dataroot', args.input_path, '--results_path', args.out_path,\
       '--loadSize', '1024', '--resolution', resolution, '--load_netMR_checkpoint_path', \
       args.ckpt_path,\
       '--start_id', '%d' % start_id, '--end_id', '%d' % end_id]
reconWrapper(cmd, args.use_rect)

設定項目は入力データの場所、出力データの場所、解像度、などですね。

入力について見てみると./sample_imagesフォルダの画像を使うようですね。
ということで、そこにメッシュを生成したい画像を配置して実行してみました。

結果はこちら。

result_test_512.gif

正常に生成できてますね。
(元画像は拾ってきたものなのでここでは載せません)

元々入っているもの以外でも正常に生成できることが確認できました。

Out of Memoryでメッシュが生成されない

数回しか遭遇しなかった問題ですが、いくつかメッシュを生成しようと試していたところ、CUDAのOut of Memoryエラーでメッシュの生成が中断するという問題がありました。

正常なメモリ解放の方法があるのかもしれませんが、いったん、$ conda deactivateをすることで解消できました。
(一度やってからはそのあとはメモリエラー出ず・・謎)

もし遭遇した場合は試してみてください。

生成に成功した環境

こちらの記事を参考に、PIFuHDの出力に成功したAnacondaの環境を貼っておきます。

Anacondaのインストールリスト
# This file may be used to create an environment using:
# $ conda create --name --file
# platform: win-64
@EXPLICIT
https://repo.anaconda.com/pkgs/main/win-64/blas-1.0-mkl.conda
https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2020.6.20-hecda079_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/icc_rt-2019.0.0-h0cc432a_1.conda
https://repo.anaconda.com/pkgs/main/win-64/intel-openmp-2020.1-216.conda
https://repo.anaconda.com/pkgs/main/win-64/vs2015_runtime-14.16.27012-hf0eaf9b_3.conda
https://repo.anaconda.com/pkgs/main/win-64/mkl-2020.1-216.conda
https://repo.anaconda.com/pkgs/main/win-64/vc-14.1-h0510ff6_4.conda
https://repo.anaconda.com/pkgs/main/win-64/cudatoolkit-10.1.243-h74a9793_0.conda
https://repo.anaconda.com/pkgs/main/win-64/icu-58.2-ha925a31_3.conda
https://repo.anaconda.com/pkgs/main/win-64/jpeg-9b-hb83a4c4_2.conda
https://repo.anaconda.com/pkgs/main/win-64/lz4-c-1.9.2-h62dcd97_1.conda
https://conda.anaconda.org/conda-forge/win-64/openssl-1.1.1g-he774522_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/tk-8.6.10-he774522_0.conda
https://repo.anaconda.com/pkgs/main/win-64/xz-5.2.5-h62dcd97_0.conda
https://repo.anaconda.com/pkgs/main/win-64/yaml-0.2.5-he774522_0.conda
https://repo.anaconda.com/pkgs/main/win-64/zlib-1.2.11-h62dcd97_4.conda
https://repo.anaconda.com/pkgs/main/win-64/hdf5-1.8.20-hac2f561_1.conda
https://repo.anaconda.com/pkgs/main/win-64/libpng-1.6.37-h2a8f88b_0.conda
https://repo.anaconda.com/pkgs/main/win-64/sqlite-3.33.0-h2a8f88b_0.conda
https://repo.anaconda.com/pkgs/main/win-64/zstd-1.4.5-h04227a9_0.conda
https://repo.anaconda.com/pkgs/main/win-64/freetype-2.10.2-hd328e21_0.conda
https://repo.anaconda.com/pkgs/main/win-64/libtiff-4.1.0-h56a325e_1.conda
https://repo.anaconda.com/pkgs/main/win-64/python-3.7.7-h81c818b_4.conda
https://repo.anaconda.com/pkgs/main/win-64/qt-5.9.7-vc14h73c81de_0.conda
https://repo.anaconda.com/pkgs/main/noarch/cloudpickle-1.5.0-py_0.conda
https://repo.anaconda.com/pkgs/main/noarch/decorator-4.4.2-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/kiwisolver-1.2.0-py37h74a9793_0.conda
https://repo.anaconda.com/pkgs/main/win-64/libopencv-3.4.2-h20b85fd_0.conda
https://repo.anaconda.com/pkgs/main/win-64/ninja-1.10.0-py37h7ef1ec2_0.conda
https://repo.anaconda.com/pkgs/main/win-64/olefile-0.46-py37_0.conda
https://conda.anaconda.org/anaconda/win-64/pyopengl-3.1.1a1-py37_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/pyparsing-2.4.7-py_0.conda
https://conda.anaconda.org/conda-forge/win-64/python_abi-3.7-1_cp37m.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyyaml-5.3.1-py37he774522_1.conda
https://repo.anaconda.com/pkgs/main/win-64/sip-4.19.8-py37h6538335_0.conda
https://repo.anaconda.com/pkgs/main/noarch/six-1.15.0-py_0.conda
https://repo.anaconda.com/pkgs/main/noarch/toolz-0.10.0-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/tornado-6.0.4-py37he774522_1.conda
https://repo.anaconda.com/pkgs/main/noarch/tqdm-4.48.2-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/wincertstore-0.2-py37_0.conda
https://conda.anaconda.org/conda-forge/win-64/certifi-2020.6.20-py37hc8dfbb8_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cycler-0.10.0-py37_0.conda
https://repo.anaconda.com/pkgs/main/win-64/cytoolz-0.10.1-py37he774522_0.conda
https://repo.anaconda.com/pkgs/main/noarch/dask-core-2.23.0-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/mkl-service-2.3.0-py37hb782905_0.conda
https://repo.anaconda.com/pkgs/main/win-64/pillow-7.2.0-py37hcc1f983_0.conda
https://repo.anaconda.com/pkgs/main/win-64/pyqt-5.9.2-py37h6538335_2.conda
https://repo.anaconda.com/pkgs/main/noarch/python-dateutil-2.8.1-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/numpy-base-1.19.1-py37ha3acd2a_0.conda
https://repo.anaconda.com/pkgs/main/win-64/setuptools-49.6.0-py37_0.conda
https://repo.anaconda.com/pkgs/main/noarch/networkx-2.4-py_1.conda
https://repo.anaconda.com/pkgs/main/win-64/wheel-0.34.2-py37_0.conda
https://repo.anaconda.com/pkgs/main/win-64/pip-20.2.2-py37_0.conda
https://conda.anaconda.org/conda-forge/noarch/trimesh-3.8.1-pyh9f0ad1d_0.tar.bz2
https://repo.anaconda.com/pkgs/main/noarch/imageio-2.9.0-py_0.conda
https://repo.anaconda.com/pkgs/main/win-64/matplotlib-3.3.1-0.conda
https://repo.anaconda.com/pkgs/main/win-64/matplotlib-base-3.3.1-py37hba9282a_0.conda
https://repo.anaconda.com/pkgs/main/win-64/mkl_fft-1.1.0-py37h45dec08_0.conda
https://repo.anaconda.com/pkgs/main/win-64/mkl_random-1.1.1-py37h47e9c7a_0.conda
https://repo.anaconda.com/pkgs/main/win-64/numpy-1.19.1-py37h5510c5b_0.conda
https://repo.anaconda.com/pkgs/main/win-64/py-opencv-3.4.2-py37hc319ecb_0.conda
https://conda.anaconda.org/pytorch/win-64/pytorch-1.6.0-py3.7_cuda101_cudnn7_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pywavelets-1.1.1-py37he774522_0.conda
https://repo.anaconda.com/pkgs/main/win-64/scipy-1.5.0-py37h9439919_0.conda
https://repo.anaconda.com/pkgs/main/win-64/opencv-3.4.2-py37h40b0b35_0.conda
https://repo.anaconda.com/pkgs/main/win-64/scikit-image-0.16.2-py37h47e9c7a_0.conda
https://conda.anaconda.org/pytorch/win-64/torchvision-0.7.0-py37_cu101.tar.bz2
```

上記は以下のコマンドで書き出したものです。

$ conda list --explicit > env_name.txt

上記リストをコピペして、以下のコマンドで環境が構築できます。

$ conda create -n [env_name] --file env_name.txt

最後に

1枚の写真からこれだけのメッシュが生成されるのは驚きですね。
しかも複数枚の写真から生成させるとさらに精度が高くなるようです。
(しかも動画からも生成できるみたい)

近い将来、今までは写真でシェアしていたものをこうした3Dモデルの形でシェアする時代が来るのでしょうね。
AR時代においては立体的にデータがシェアされるのは間違いないでしょうから、今からそういう時代が来るのが楽しみです。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7