1枚のRGB画像に距離の情報を入れる[未完・打ち切り]
モチベーション
夏休みの自由研究として機械学習っぽいことをしてみたい。
ロボットやるときに、画像から物体までの距離を推定できれば、特に動作の計画を立てるのにかなり使い手がありそうで。
例えば、走行計画作るとか、掴むにしても掴む場所を決めたりとか。
そんなことを1枚の画像でできちゃったら素敵やん?
あとついでにせっかくtensorflow使えるようになったし練習もしたいし。
手法の概略
[1806.11430] Towards real-time unsupervised monocular depth estimation on CPU
基本的にはこれをいじっていくつもり。
教師なしCNNですね。
[1609.03677] Unsupervised Monocular Depth Estimation with Left-Right Consistency
この論文の手法で使われてるネットワークを改良したという認識。
まだ勉強中。
基本的な考え方は
「ステレオカメラで撮影した画像のペアをたくさん持っている前提があったとして、
片方の画像からもう片方の画像を生成する視差を画像パターンから推定できれば
視差は物体との距離に依存するので、物体との距離を推定できるだろう」
というもの。
(論文とは違うnotationを使います。論文のは慣習?なのかもしれないけど、自分には馴染めないので・・・)
をそれぞれ左側のカメラで撮った画像、右側で撮った画像とする。
このときは(縦のピクセル数)x(横のピクセル数)x(色の数、普通は3)次元の3階のテンソルだと思えば良い。
左右のカメラから撮った画像のズレの量は以下のように考えればいい・
・カメラが水平に揃っているならば、上下方向へのズレはない
・左右方向のズレの量は以下のように計算される
ここではカメラから被写体までの距離。
は2つのカメラ間の距離
はカメラの焦点距離。2つのカメラは同じ焦点距離を持つとする。
は一般に視差と呼ばれる量である。
参考:http://www.topic.ad.jp/sice/htdocs/papers/295/295-7.pdf
ここに、画像の上からi番目、左からj番目のピクセルに対して定義される視差を表現する2階のテンソルを、
となるようになんとか取る。
(符号に注意。dが正になるようにとった。)
注:もし、2つのが上記を満たすように取られていれば2つは独立ではない。
上の変換を2回やることで
であるから
注:ただし、を学習によってそれぞれ別に推定した場合、上述の「整合性」がとられているとは限らない。
このテンソルが推定できれば、の関係式から、各ピクセルの被写体からの距離が推定できる。
じゃあ、どちらを使えばいいかと言うと、には、逆は逆らしい。
※この点が僕にはよくわからなかった。
学習させるネットワーク
インプットとアウトプットの関係は以下の図
[1609.03677] Unsupervised Monocular Depth Estimation with Left-Right Consistencyより。
左下のからを推定して、そこから生成される画像とを比較する。(コスト関数はと生成される画像の「差」の項をもつ)
まんなかのボウリングのストライクみたいなマークはネットワークです。
ここは教師あり学習ですね。
(教師なしと論文が主張するのは、距離のデータをインプットに使っていないから)
左右両方やって、コンシステンシーを確認しながら学習するのがポイントのようです。
(コスト関数はに比例する項をもつ)
ネットワークのアーキテクチャはこんな感じ
L6はストライドが2の畳み込みを6回やったあとにさらに畳み込み層で特徴を抽出してますので、比較的広い領域の特徴に着目していることになります。
以降、上の層ほど細かい領域に着目して特徴抽出する構造になってます。
試食
[1609.03677] Unsupervised Monocular Depth Estimation with Left-Right Consistency
の方のgithubにとりあえず1枚の画像で味見する方法があったので使ってみた。
※tensorflowのrestoreはcheckpointファイルの入ったフォルダのパスを指定するのではないことに注意。
例えば、checkpointの保存先がC直下だったとして、Cを指定するのではなく
"C://<checkpointファイルの拡張子を含めない名前>”
を指定する。これで割とハマった・・・。
※学習済みモデルはここにおいてあります
http://visual.cs.ucl.ac.uk/pubs/monoDepth/models
なんらかの理由でシェルスクリプトが動かなければここから取ってきましょう。
結果
こいつを・・・
こうじゃ!
詳細は潰れてるけど障害物見つけるぐらいならできそう。
あえてゲームのSSを食わせてみると
さすがに厳しい。左下なんか完全に間違ってる。
微妙にいけてる気がするFF7。
一点透視図法っぽいのがいいんだろうか。
自分が一番期待したのはこれ。
こういう画像から缶の形状がはっきりわかれば、ロボアームで掴むときに有用かなと。
結果はだめですねー。これじゃあ三角形に並んでるのはわかるかもしれないけど、缶1つ1つはぜんぜんわからん。
それに缶の模様の影響を受けてますね。これはいかん。
推定する先に、推定した結果から推定される対象物の形状は現実的なものなのか?という指標を入れればマシになるんだろうか?
今後
pydnetもやろうかと思いましたが、一旦ここで打ち切りかなあ。
再開するかもしれないけど。
次はネットワークのアーキテクチャ考えるとこからやりたい所存。
参考文献
[1806.11430] Towards real-time unsupervised monocular depth estimation on CPU
[1609.03677] Unsupervised Monocular Depth Estimation with Left-Right Consistency