【キャリブレーション対決】チェスボード vs 円形

#チェスボード vs 円形マーカー
ステレオ計測などでは，事前にカメラのレンズ歪みやカメラの位置関係に関するパラメータを求めておく必要があります。サイズが既知のパターンを使ったキャリブレーションボードが使われます。↓こんなやつです。

<table>
<tr>
<td>
<img src=https://qiita-image-store.s3.amazonaws.com/0/217237/f881265b-fe77-51e6-02cd-9ace0f68a9c7.jpeg width=100%>
<br>
チェスボード
</td>
<td>


<img src=https://qiita-image-store.s3.amazonaws.com/0/217237/368895cd-0748-46f9-6ea5-0dc2c4aa0895.jpeg width=40%>
<br>
円形マーカー
</td>
</table>


代表的なパターンとして，チェスボードタイプと，円形マーカータイプがあり，<b>円形マーカーのほうがよい</b>，という噂を以前から聞いていました。今回，その噂をopencvのライブラリを使って検証したいと思います。結論から言うと，~~今回の実験ケースでは<b>円形マーカーのほうが性能がよい</b>ようです。~~
<b>確かに円形マーカーのほうが再投影誤差は低くなるようです。ですが，チェスボードもそんなに悪くないということが分かりました。</b>

###特徴点の検出
チェスボードの場合はharrisなどのコーナー点検出を使います。その後，たぶん，局所的な微分強度値を使って多項式に当てはめるなりしてサブピクセル位置を出していると思います。
一方で，円形パターンではおそらく２値化＋重心位置で検出します。こっちのほうが簡単かつ検出サブピクセル精度がよく，キャリブレーションボードが傾いていても検出される中心位置は安定してそうです。

###実験条件
最初の図で示したチェスボードと円形マーカーのキャリブレーションボードを使って，９枚のステレオ画像を60cmほど離して撮影します。それぞれのキャリブレーションパラメータを求めておきます。画像サイズは800x600[pix]です。

なお，パワポでキャリブレーションパターンを作って印刷しましたが，パワポ上では20mmで作っても印刷すると21mmくらいになっていました。そこで，ボードにパターンと同じ寸法のトンボを印刷しておきこれを精密定規で測り，この値をリファレンス値として使います。

<img src=https://qiita-image-store.s3.amazonaws.com/0/217237/b889fac6-2988-3e83-66c1-5b267e9b6535.jpeg width=30%></img>



今回，ステレオカメラはこいつを使います。FUJIFILMのFinePix 3D W3です。コンデジと同じ感覚でステレオが取れ，ステレオなのになぜか光学ズームができるという~~変態的な~~ナイスなカメラですが，残念ながら既にディスコンです。こいつの左右のベースライン長さは75mmなので，キャリブレーションの検証にも使えます。
<img src=https://qiita-image-store.s3.amazonaws.com/0/217237/95d416ed-ee0d-2a7e-faa0-26ac069c7331.jpeg width=30%></img>



##円形マーカーでのキャリブレーション結果
ステレオキャリブレーションで推定された左右のカメラの相対位置Tと回転行列Rは以下となりました。

~~~
T = [-74.921;0.457;4.739]
R = [
  0.999, -0.007, -0.001;
  0.007,  0.999,  0.000;
  0.001, -0.000,  0.999]
キャリブレーション誤差=0.195, 推定ベースライン長=75.073
~~~

opencvのstereoCalibrate関数の戻り値であるキャリブレーション誤差は0.19，
推定されたベースライン長さは75.07mmなので概ねあってそうです。
回転行列もほぼ単位行列となっていて平行に設置されていることが分かります。

##チェスボードでのキャリブレーション結果
同様にチェスボードでの結果が以下となりました。

~~ベースライン長が<b>95mm???</b>となったため当初バグかと思いましたが，
findCirclesGridをfindChessboardCornersに差し替えただけなので間違いはないかと思います。
画像の手ぶれが問題だったかもしれないと思って，
気を取り直して再度画像を撮影し，キャリブレーションを行った結果は以下となりました。
76.55mmとなって，まあまあ合っているかな？という感じです。z方向のずれが気になります。
ただし，カメラが傾いている感じになっています。~~
~~この時点で既に勝負がついてしまった気もしますが，一応，評価を続けます。~~

<b>キャリブレーション誤差は平均ピクセル投影誤差[pix]とのことで，
さすがにこれはおかしいと思って見直したところ，コードにバグが
あることが判明しました・・・(2017/11/20)。</br>

結果は以下となります。円形マーカーよりは誤差は大きいようです。

~~~
T = [-74.868;-0.135;-2.322]
R = [
  0.999, -0.007  -0.009;
  0.007,  0.999, -0.000;
  0.009,  0.000,  0.999]
キャリブレーション誤差=0.292, 推定ベースライン長=74.904
~~~


#実験評価その２
それぞれのパラメータにて，キャリブレーションには使っていない下図のテスト画像（ステレオ）でマーカーの3D位置を求めて，その距離の平均と標準偏差を求めて比較します。距離は41.7mmが正解です。計測点は３３か所です。

<img src=https://qiita-image-store.s3.amazonaws.com/0/217237/e4234bef-0c7c-180b-ef08-ac7e26b15e55.jpeg width=30%></img>

~~結果は以下となりました。円形マーカーのほうが誤差平均が1/2くらいになっていて良いですが，
チェスボードの結果もさっきのキャリブレーション結果に対しては悪くないという感じです。~~

<b>こちらも再計測しました。円形マーカーのほうがいいですが僅差という感じです。</b>

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217237/f97d9c9a-9d5c-8472-a619-be8fe9e7c683.png)

#実験評価その３

![scale.jpg](https://qiita-image-store.s3.amazonaws.com/0/217237/c125f4ab-6572-a71d-1981-d13876cbd440.jpeg)


定規を撮影して，80cmと90cmの箇所を目視でクリックして，それぞれのキャリブレーションパラメータにて，
その距離を計測してみます。５回試行して，その平均をみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/217237/7286b4fb-c62d-e731-157d-8010f691852f.png)

~~100mmが正解ですので円形マーカーのほうが正確に計測できていることが分かります。~~
<b>このケースでは，目視の誤差もあるのですがチェスボードの結果がわずかによくなりました。</b>

#まとめ
円形マーカー vs チェスボードにおいて，円形マーカーのほうが良い，という噂を検証しました。
~~そして，その通りであることを確認しました。~~
キャリブレーションの再投影誤差やサイズ既知のマーカー計測では，わずかに円形チェスボードが良かったのですが，
目視でクリックして２点を計測するようなケースでは有意な差はみられませんでした。
<b>バグと円形マーカーがいいだろうという先入観は怖いとわかりました。</b>