2018年11月30日金曜日

Colmapによるカメラの内部パラメータ推定

カメラキャリブレーションをして内部パラメータが欲しいときは, OpenCVのcameraCalibration というサンプルプログラムはあまりいい選択肢ではない. マーカの検出が不安定でキャリブレーション用のパターン全体が画像内に写っていなければ, データを取得することができず画像の隅の方までマーカを写すことができないから.

Colmapという三次元復元 (SfM + MVS) ソフトは,カメラ位置や特徴点の三次元位置だけなく内部パラメータまで推定してくれるので, カメラキャリブレーションに使用することができると聞いたので早速使ってみた. 似たようなソフトにBundlerがあるが,複数の画像を入力したとき,複数の画像で内部パラメータが独立に推定されるのと, カメラモデルを選択することができずカメラキャリブレーションには向いていない. Colmapでは,OpenCVのカメラモデルやその他のモデルを選択でき,特徴点により計算できるので, キャリブレーション専用のパターンやボードを準備する必要がない上, 画像の隅々まで

入力画像と歪み補正結果

今回のキャリブレーションで左が入力画像の1枚,右がそのレンズ歪み補正結果.直線であるはずの歪んだ構造が歪み補正結果で直線に戻っていたら成功. そういう意味ではなかなかうまく補正されているように見える.

本来の使い道は三次元復元なのでその結果ももちろん得られる.

実行手順

  1. 動画(video.mp4)から連番画像(img-xxx.png)ファイルを作る
    ffmpeg -i video.mp4 -f image2 -vcodec png img-%03d.png
    
  2. COLMAP-dev-windows-legacy-cuda.zipダウンロード+解答
  3. Colmap.bat起動
  4. File → New project
    1. Newクリックして作業用フォルダ選択→適当な名前.dbを入力して保存
    2. Selectクリックして画像のフォルダ選択
    3. Saveクリック
  5. Processing → Future extraction
    1. Colmap (https://colmap.github.io/)でcamera modelをFULL_OPENCVに設定
    2. Camera modelのオプションShared for all images (全ての画像が同じ内部パラメータ)
    3. Camera modelのオプションCustom parameters(初期値)に640,640,640,512,0,0,0,0,0,0,0,0を設定
    4. Extractクリック
  6. Processing → Future matching → Exhaustive (すべての画像のペアでマッチング)
    1. Runクリック
  7. Reconstruction → Reconstruction options → Bundle → Camera parameters
    1. refine_***を全部チェック
  8. Reconstruction → Start reconstructionクリック (約1時間)
  9. Reconstruction → Bundle adjustment
    1. refine_****を全部チェック
    2. Runクリック
  10. File → Export model as text(ここでキャリブレーションデータ抽出終わり)
  11. Reconstruction → Dense reconstruction(ここからはおまけ.メッシュモデルができる)
    1. Undistortionクリック
    2. Stereoクリック
    3. Fusionクリック
    4. Poissonクリック
    5. Delaunayクリック

パラメータ初期値の決め方

今回,「Custom parameters(初期値)に640,640,640,512,0,0,0,0,0,0,0,0を設定」したけど,これはどうやって与えたのか? COLMAPのカメラモデルのうち「Full OpenCV camera model」を用いたので,「$f_x, f_y, c_x, c_y, k_1, k_2, p_1, p_2, k_3, k_4, k_5, k_6$」の順に値が並んでいる. これらは,OpenCVのパラメータなので「Camera calibration With OpenCV」を見て欲しい.

今回は,入力画像の水平方向の解像度が1280画素で,カメラの画角がおおよそ90度くらいだったので, 「画角と解像度から内部パラメータ行列を作る」を参考にすると, camera matrixの部分は決まる.レンズ歪みのパラメータについては全部ゼロ(つまり歪み無し)を初期値として, Colmapの最適化の過程で最適な値を求めてもらった.

Colmapを閉じた後の再ロード方法

  1. Colmapを開く
  2. File→Open project
  3. プロジェクトファイルを開く(Export model as textで出力されたもの)
  4. File→Import model
  5. 「Export model as text」で出力したフォルダを選択

参考

2018年11月22日木曜日

標準偏差と標準誤差を直感的に理解する

この記事は,研究室のゼミでせっかくグラフをエラーバー付きで示してプレゼンしたのに, もしくは104.3±4.5のように誤差つきで計測値を論文に書いたのに, それって標準偏差それとも標準誤差?などと聞かれた人向け(それ以外にも誤差の示し方は半値幅とか2σとかいくらでもある). 標準偏差の意味は,なんとなくデータのばらつき具合で, 精度(もしくは誤差)を表すのに都合が良い,というところまでは理解しているけど, よく似た名前でよく似た数式の標準誤差とどうちがうのか,いまいち教科書を読んでも良くわからない,という人向け. 「三角形は,コンビニのおにぎりの形」くらいのざっくりした説明をする.

標準偏差と標準誤差の違い

まず名前が違う

当たり前だけど名前が違う. 名前が物事を分かりにくくするということが多々あって, 私もこの名前のせいで理解しようとする気持ちが長年失せ続けた人間の一人. まず,共通部分の「標準」だけど,はっきり言って「標準」ということに殆ど意味はないので無視した方がいいい. 「統一規格の」というくらいの意味なのだろうか?命名された経緯は良くわからない.

次に「偏差」と「誤差」という部分が違いだけど, これも2種類の統計量の違いを的確にあらわしている訳ではないので,無視して丸暗記するしかない. しいて自分で名前をつけるなら,標準偏差は「ばらつき幅」,標準誤差は「平均値精度」が良いと思っている. そう,わざわざ全然違う名前にするということは,意味が違うということ. この記事では名前の分かりにくさが理解を妨げてるという立場をとってるので,「標準偏差(ばらつき幅)」のように常にセットで用いる.

数式が違う

それぞれの定義式を説明しはじめると,ややこしくなるので両者の関係式から. 教科書を読むとごちゃごちゃ数式がでてきて嫌になってしまって, どうやって計算するのかが書かれている最後の部分だけ見るとこんな感じになっている.

\[ 標準誤差(平均値精度)=\frac{標準偏差(ばらつき幅)}{\sqrt{データ数}} \]

要するに標準偏差が計算できれば標準誤差は簡単に計算できるということ. 「というか,ほとんど同じやん」と思ったのでは? 全然違う名前をつけた割りには,標準誤差(平均値精度)は単に標準偏差(ばらつき幅)をデータ数のルートで割っただけのもの. 要するに標準偏差(ばらつき幅)が大きなときは標準誤差(平均値精度)も大きくなる,という意味では同じようなもの.

こう考えると全然意味が分からなくなる. この結果は,もともと異なる統計量を計算した偶然の結果であってこの関係詞期から両統計量の違いを理解しようとすると理解できなくなる. 実際教科書では,標準偏差は直感的なイメージとともになぜそういう定義がされたか説明されるが,標準誤差は中心極限定理を持ち出して説明される.

使い方が違う

標準偏差
データのばらつきを表すのに用いる.データ単体を示して云々語るときはこちら.
標準誤差
データから得られた平均値の精度を表すのに用いる.2つ以上のデータセットの平均値の差を比較する場合はこちら.

以上です.詳しくは教科書を読んで勉強して欲しい.

参考