SfMのOSS:Bundlerを動かしてみる in Windows 10 (動きませんでした)

最初に結論を述べておくと、Windows 10でBundlerは動きませんでした。ごめんなさい。

動かないまま力尽きたものの、結構頑張って動かそうとしたので、その軌跡をまとめました。


 

SfMのOSSであるBundlerは、Linuxで動かすことを前提としています。
なので、Windowsで動かすには昔はCygwin等が必要だったのですが、Windows 10のBash on Windows(BoW)を使えば簡単に動かせるんじゃないかと思ったので、挑戦してみます。
(一応Visual Studio用のプロジェクトファイルもあるのですが、VS上で動かすのは果てしなく手間がかかりそうなので、今回は見送ります)

最新バージョンのv0.4でさえ2010年4月にリリースされたものなので今更感は否めませんが、大規模なSfMの礎となった偉大なOSSなので、動かしてみる価値はあるでしょう。

Bundlerの入手

何はともあれ、まずはBundlerのソースコードを持ってきます。
せっかくなので、公式サイトのv0.4ではなくGitHubから最新のコードを持ってきましょう。

これからの処理は全部Bash on Windows上で行っています。

$ git clone https://github.com/snavely/bundler_sfm.git # Bundlerのソースコードを入手

Bundlerには特徴点検出器は含まれていないので、検出器のOSSもダウンロードします。
今回はREADMEにしたがって、このサイトのSIFT検出器を使います。

Demo Software: SIFT Keypoint Detector

$ wget http://www.cs.ubc.ca/~lowe/keypoints/siftDemoV4.zip # SIFT検出器をダウンロード
$ unzip siftDemoV4.zip # zipを展開
$ cp siftDemoV4/sift bundler_sfm/bin/ # 必要なファイルをBundlerにコピー

ちなみに、このSIFT検出器の出力フォーマットに合わせて特徴点を記述してやれば、SIFT検出器以外も使えるみたいです。

Bundlerのビルド

このままでは色々と足りなくてビルドできないので、必要なパッケージをインストールしてやります。

JPEG画像のメタ情報、EXIFを扱うために、jheadというコマンドもインストールします。Bundlerでは焦点距離をEXIFからとってきたりしているので、そのために使用するツールです。
またプログラム内から画像の操作をするためにImageMagicもインストールします。

$ sudo apt install jhead # jheadのインストール
$ sudo apt install imagemagick # ImageMagicのインストール

最後に、makeするときに必要な実行ファイルを見つけられるように、パスを通してやります。

$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:Bundlerのパス/bin # 環境変数を設定

これでREADMEに書いてある準備は一通り行ったはずなのですが、実はこれではビルドに失敗してしてしまします。
BoWはデフォルトでインストールされてるパッケージが少ないせいですかね。。。
なので、その他必要な諸々をインストールしてやります。

$ sudo apt install gfortran       # 実はFortranのコンパイラが必要みたいなのでインストール
$ sudo apt install zlib1g-dev     # 圧縮ファイルを扱うライブラリ
$ sudo apt install libjpeg-dev    # JPEG画像を扱うライブラリ
$ sudo apt install liblapacke-dev # 数値計算ライブラリ

これで準備が整ったので、ビルドしてやりましょう!

$ make # ビルド実行!

Errorが出なければ、ビルド成功です!!(warningはたくさん出ますが無視してください。)

Bundlerの実行

ビルドが成功したら、Bundlerを実行してみましょう!!
今回はリポジトリ内にあるサンプル画像を使って動かしてみます。

まずは、画像のあるディレクトリに移動してやります。

$ mkdir image
$ cp examples/ET/*.jpg image/ # 既存のファイル構造を汚したくないので、サンプル画像を新しいディレクトリにコピー
$ ls image/
et000.jpg  et001.jpg  et002.jpg  et003.jpg  et004.jpg  et005.jpg  et006.jpg  et007.jpg  et008.jpg

あとは、スクリプトを起動するだけ!!なはずなのですが・・・

$ ../RunBundler.sh
Using default config options
[extract_focal] Error: jhead not found.  Please install jhead to ../bin

怒られました。。。
jheadはさっきインストールしましたが、どうやらbin以下に置かないといけないみたいなので、シンボリックを貼ってやります。

$ cd .. # Bundler直下のディレクトリに移動
$ ln -s `which jhead` bin/ # binの下にシンボリックリンクを貼る
$ cd image # 画像のあるディレクトリに戻る

そして、再度実行

$ ../RunBundler.sh
Using default config options
0
Image list is list_tmp.txt
[Extracting exif tags from image ./et000.jpg]
  [Focal length = 5.400mm]
[Couldn't find CCD width for camera Canon Canon PowerShot A10]
[Found in EXIF tags]
  [CCD width = 5.230mm]
  [Resolution = 640 x 480]
  [Focal length (pixels) = 660.803

...

[- Extracting keypoints -]
../bin/sift: 1: ../bin/sift: Syntax error: "(" unexpected

...

[- Matching keypoints (this can take a while) -]
../bin/KeyMatchFull list_keys.txt matches.init.txt -1
Invalid keypoint file.

...

[KeyMatchFull] Reading keys took 0.016s
[- Running Bundler -]
bundler: BaseApp.h:271: std::vector<KeypointMatch>& MatchTable::GetMatchList(MatchIndex): Assertion `p.first != p.second' failed.
../RunBundler.sh: line 148: 24563 Aborted                 (core dumped) $BUNDLER $IMAGE_LIST --options_file options.txt > bundle/bundle.log
[- Done -]

うーむ、今度は画像は読み込めてるけど特徴点検出に失敗しまくってます。。。
はい、ここで挫折してBundlerを実行することはできませんでした。

結論

Syntax error: “(” unexpected というエラーメッセージ的に、どうにもSIFT検出器のバイナリが32bitしか対応していないっぽいです。
今回使用したこのSIFT検出器は、2005年が最終更新でソースコードもすべては公開されておらず自分の環境用にビルドできないため、64bit環境で動かないのはもうどうしようもありません。

Demo Software: SIFT Keypoint Detector

この辺を見る限りBoWも64bitしかサポートしてないないようなので、違う特徴点検出器を使うしかないみたいですね。OpenCVとかを使えばできないことはないんでしょうけど、今回はここで力尽きたので見送りたいと思います。

Please enable WSL to run 32 bit ELF binaries
It seems that executing 32bit ELF binaries results in "Exec format error" - guessing the kernel doesn't have 32 bit emulation support (compilation is fine, but ...

 

コメント