論文を実装しようとしたらOSの違いに苦しんだ話

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288125/f73d102a-b6af-ac7e-ed2c-6533ce691728.png)


　[色々な体形やポーズの人体を自由に生成する研究](https://smpl.is.tue.mpg.de/)というものがありまして、（登録制ですが）Pythonで動くプログラムを配布しております。

　READMEには、

```
System Requirements:
====================
Operating system: OSX, Linux
```

　とあるので、Windowsは想定されていません。とはいってもまあ動くやろタハハと思って、結局は私の環境（Windows10 64bit）で動かせたのですが、色々と苦労したという話です。

#トラップ1　パスを通す必要がある

　これは個人的にはノートラップでしたが一応。独自のモジュールをローカルに保存しているので、そこにPATHを通す必要があります。READMEに書かれている通り、Macではホームディレクトリにある`.bash_profile`の末尾に

```
SMPL_LOCATION=~/smpl
export PYTHONPATH=$PYTHONPATH:$SMPL_LOCATION
```

　という文字を付け加えます。

　Windowsでは`コントロール パネル＞ユーザー アカウント＞ユーザー アカウント`と進んだところにある（なんでこんな変な場所に……）「環境変数の変更」で独自に設定する必要があります。

#トラップ2　Python系列が2

　これは一瞬で解決できましたが一応トラップ。プログラムの文がPython2系列なので使用する実行するPython環境も2系列にする必要があります。バージョンが違う場合、そもそも`print`文の形式が違うし、そういう些末な問題以前にモジュールが揃わなかったりするので、そのまま実行できることは極めて稀です。

```
SyntaxError: Missing parentheses in call to 'print'. Did you mean print(…)?
```

　というエラーが出る場合は2系列のプログラムを3系列のPythonで動かしている可能性が高いでしょう。

#トラップ3　モジュールの名前が微妙に違う

　READMEに`Numpy`、`Scipy`、`Chumpy`、`OpenCV`が必要とあって、当然`pip`でインストールすることになるのですが、最後の`OpenCV`はヒットしません。そのまま実行すると`cv2`というモジュールがないとダメと言われるので、`cv2`で打ってみてもダメ。結果的には、

```Python
pip install opencv-python
```

　と打つのが正解でした。まあ、界隈では常識なのかもしれないですが……。

#トラップ4　EOFError

　今までのは前哨戦みたいなものでしたが、**これからが本当のトラップ**です。無事環境をそろえてさあ実行……と思ったら以下のようなエラーが出ます。

```Python
Traceback (most recent call last):
  File "hello_smpl.py", line 48, in <module>
    m = load_model( '../../models/basicModel_f_lbs_10_207_0_v1.0.0.pkl' )
  File "C:\Users\~~~\smpl\smpl_webuser\serialization.py", line 116, in load_model
    dd = ready_arguments(fname_or_dict)
  File "C:\Users\~~~\smpl\smpl_webuser\serialization.py", line 80, in ready_arguments
    dd = pickle.load(open(fname_or_dict))
EOFError
```

　`EOFError`でググると空のファイルを読み込んだ時に出てくる警告とありますが、ファイルはちゃんと指定できています。またエラーメッセージも症例に出てくるものとは微妙に異なっています。どうやらファイルが空かどうかはあまり関係がなさそうです。これはどういうことかと暫く悩んでおりましたが、その後調査を進めると、

Windowsでは、pickleモジュールでバイナリファイルを扱う時には、文字を入れてそのように指定する必要がある、

　ということらしいです。[（参考記事）](https://ja.stackoverflow.com/questions/18992/python-pickle%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89-%E3%83%90%E3%82%A4%E3%83%8A%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AE%E5%BF%85%E7%84%B6%E6%80%A7)
　具体的には、同梱されている`serialization.py`中にある

```Python
dd = pickle.load(open(fname_or_dict))
```

　という文を

```Python
dd = pickle.load(open(fname_or_dict,`rb`))
```

　にする必要があります。これでやっと実行できます。少なくとも私の環境では。

　後日MacBookProで検証したところ、MacOSXではこのような問題は起こりませんでした。OSの違い……。

#解けなかったトラップ　opendr

　別のサンプルプログラムを実行しようとすると`opendr`というモジュールがないと言われます。じゃあ`pip`するぜ……と思ったけれどもエラー。エラーメッセージを読むと[C++のコンパイラ](https://www.microsoft.com/en-us/download/details.aspx?id=44266)を入れてねと言われたので入れてリトライ。しかし、

```Python
    LINK : warning LNK4044: オプション '/lstdc++' は無効です。無視されます。
    LINK : fatal error LNK1181: 入力ファイル 'OSMesa.lib' を開けません。
    error: command 'C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Community\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX86\\x64\\link.exe' failed with exit status 1181
```

　検索すると[似たような症例](https://teratail.com/questions/54131)はあるのですが、問題となっているファイル（`OSMesa.lib`）が違うので流用はできなさそう。そしてこの`OSMesa`というものを調べるとLinuxには搭載されているライブラリであるということがわかる。

　MacBookProでやってみたところノーエラー。3D上のビューワーを表示するためのモジュールだったようです。しかしここでもOSの違い……。

# 思ったこと

　もうバージョンやOSの違いはたくさんだ……。