ここまでの記事では、アストロトレーサーについていくつかの計算結果を紹介してきました。
→ アストロトレーサー①「星は止まるのに、なぜ地上は流れる?」
→ アストロトレーサー③「なぜ超広角の周辺では星が流れるのか?」
たとえば、同じ60秒でも焦点距離によって地上の流れる量が違うこと。
画面中央では星がよく止まっていても、超広角では周辺に追尾残差が生じること。
さらにアストロトレーサー③「なぜ超広角の周辺では星が流れるのか?」では、通常の超広角レンズと魚眼レンズを同じ画角で比較すると、今回のモデルでは魚眼のほうが追尾残差が小さくなるという結果も紹介しました。
そこで、
「ところで村田さん、その○pxという数字はいったいどうやって計算したんですか?」
と思った方もいるかもしれません。
確かに、そこを説明せずに「計算したら24.14pxでした」とだけ書いても、計算機から出てきた数字を並べているだけに見えてしまいます。
そこで今回は、アストロトレーサー①〜③で使った数字を実際にどうやって求めたのかを説明します。
最初に断っておくと、計算コードそのものはAIを使って作成しました。
ただし、
「アストロトレーサーの誤差を計算して」
とAIに聞いて、返ってきた数字をそのまま記事に使ったわけではありません。
何をモデル化するのか。
どんな条件を与えるのか。
何を「誤差」として測るのか。
既に分かっている結果を再現できるのか。
そうしたことを一つずつ確認しながら計算モデルを作っています。
そして実際にやっていることは、数式を抜きにすると意外と単純です。
図1:①〜③の「○px」がどう作られているか。画面の点から空へ逆算するのが出発点で、空に星を置くところからではありません。実際には計算でサンプルした各時刻・画面内の各格子点で残差を求め、この記事ではその最大値を比べています。理想化モデルであり、PENTAX の制御を再現したものではありません。
まずは上の図を見てください。
1 まず、画面の上に星を並べる
最初にやったのは、
センサー上に格子点を並べること
です。
今回のフルサイズモデルなら、センサーは35.9×24.0mm。
その上に等間隔の点を並べます。
一つ一つの点を、
「ここに星が写っている」
と考えます。
ここは私自身、最初に聞いたとき少し意外でした。
私はてっきり、
「空に星を並べて、それをカメラで撮影する」
という順番で計算するものだと思っていたからです。
実際には逆でした。
まず画面上の位置を決めてから、
「この位置に写っている星は、実際の空ではどの方向にあるのか?」
を逆算しています。
この方法なら、計算する星が必ず画面の中に入ります。
画面中央だけでなく、四隅まで均等に調べることもできます。
2 画面の点から、空の星の方向を逆算する
次に、その格子点をレンズを通して逆向きにたどります。
普通の撮影なら、
空の星 → レンズ → センサー
です。
ここでは逆に、
センサー → レンズ → 空
とたどります。
これを「逆投影」と考えればいいでしょう。
すると、
「画面の右上に写っているこの星は、カメラから見るとこの方向にある」
という三次元の方向が求められます。
このとき重要なのが、レンズによって投影方法が違うことです。
3 普通の広角と魚眼では、星を画面へ写す方法が違う
アストロトレーサー③で魚眼レンズを比較できたのは、ここを変えて計算したからです。
通常の広角レンズでは、直線を直線として写す一般的な投影を使います。
魚眼では、
等距離射影
等立体角射影
立体射影
など、別の投影方法があります。
つまり、
空で中心から同じ角度だけ離れた星でも、レンズによってセンサー上のどこへ写るかが違う
わけです。
たとえば通常の広角レンズでは、画面周辺へ行くほど像が大きく引き伸ばされます。
一方、魚眼では直線を曲げる代わりに、周辺の詰まり方・伸び方が違います。
アストロトレーサー③で、
「魚眼だからアストロトレーサーでは不利なのでは?」
を調べることができたのは、この投影式を入れ替えて、同じ星空を計算したからです。
実際の計算では通常広角のrectilinearに加えて、魚眼などを含む複数の投影方式を実装し、同じ画角に揃えた比較では魚眼3方式を使用しています。
4 地球を60秒ぶん回す
これで露光開始時の星の位置ができました。
次は時間を進めます。
たとえば60秒露光するとします。
地球は、その60秒の間にも自転しています。
今回のモデルでは恒星時の自転角速度、
7.2921159×10⁻⁵ rad/s
を使っています。
もちろん、この数字を覚える必要はありません。
重要なのは、
「60秒後には、地球がこれだけ回っている」
という角度を求めて、そのぶん星の方向を回しているということです。
正確に言えば、空そのものを回しているのではなく、地球の自転によって星がカメラからどちらへ動いて見えるかを計算しています。
これで、
露光開始時の星空
と、
60秒後の星空
ができます。
5 60秒後の星を、もう一度レンズで写す
次に、60秒後の星をもう一度レンズに通します。
すると、
最初はここにあった星が、60秒後には画面のここへ来る
という位置が分かります。
固定撮影なら、基本的にはこれが星の流れです。
しかし今回はアストロトレーサーを考えています。
アストロトレーサーは、この星の動きを撮像素子を動かして追いかけます。
そこで次の計算をします。
6 では、センサーをどう動かせば星を元へ戻せるのか
PENTAXのセンサーシフト機構では、撮像素子を
X方向へ移動
Y方向へ移動
光軸を中心に回転
させることができます。
この3自由度自体は、今回勝手に作ったものではなく、関連する特許にも記載されている機構です。
そこでモデル上でも、
60秒後に移動した星を、センサーのX/Y移動+回転で元の位置へ戻してみる
という計算をします。
ここで大切なのは、
実際のPENTAXが、今回のプログラムと同じ計算方法でセンサーを動かしていると言っているわけではない
ことです。
実機の制御アルゴリズムは分かりません。
今回知りたいのはもっと基本的なことです。
平面のセンサーを上下左右に動かして回転させるという条件だけで、空全体の動きをどこまで打ち消せるのか。
それを調べています。
7 全部合わせたつもりでも、少しズレが残る
ここがアストロトレーサー③につながります。
画面中央付近だけを見ると、かなりきれいに星を合わせることができます。
ところが画面全体を見ると、
すべての星が完全に元の位置へ戻るとは限りません。
ある星はほぼ完全に戻る。
別の星は少しズレる。
四隅ではもっとズレる。
そのズレが、アストロトレーサー①〜③で何度も出てきた、
追尾残差
です。
8 「追尾残差○px」の○とは、何を測っているのか
ここは今回の記事で、一番説明しておきたいところです。
記事に出てくる、
「追尾残差24.14px」
という数字は、平均値ではありません。
四隅だけを測った値でもありません。
また、星が描いた軌跡の長さでもありません。
実際の計算では露光中にも時間を区切って星の位置を調べています。
そして、
露光中の各時刻 × 画面内の各格子点
について、
「センサーを動かして追尾したあと、それでも元の位置からどれだけ離れているか」
を測ります。
その中で、
最も大きかったズレ
を記事の「○px」としています。
ですから24.14pxなら、
今回調べた露光時間と画面範囲の中で、最悪の場所・最悪の時刻では約24.14pxのズレが残った
という意味です。
平均24.14pxではありません。
9 なぜ平均ではなく「最大」を見たのか
これは写真を考えると分かりやすいと思います。
たとえば画面に100個の星があったとします。
99個はほとんど止まっている。
でも四隅の一つだけ、大きく流れている。
この状態で平均を取れば、かなり小さな数字になるかもしれません。
しかし写真を見る側からすれば、
その一本だけ大きく流れた星は見えます。
だから今回の記事では、
「平均的にどのくらい合っているか」
よりも、
「画面のどこまで星を止められるのか」
を見るために最大値を使いました。
これはPENTAXが製品評価に使っている指標ではありません。
今回の記事で追尾残差を考えるために選んだ評価方法です。
10 「中心を合わせる」と「画面全体を最もよく合わせる」も分けて計算した
図2:**同じ天球の動きでも、センサーのX/Y移動+回転をどう合わせると仮定するかで、残る誤差の大きさも分布も変わる。**対角画角114度・9×9格子。濃淡は分布の模式で、セルごとの数値ではない。どちらもモデル上の合わせ方であって、PENTAX実機の制御アルゴリズムではない。
今回のモデルでは、センサーの合わせ方も一種類ではありません。
一つは、
画面中央付近の星がよく合うようにする方法。
もう一つは、
画面全体の星に対して、X/Y移動+回転だけで最もよく合う状態を数学的に探す方法。
です。
アストロトレーサー①〜③に出てくる数値は、前者、つまり画面中央に合わせた場合のものです。
同じ条件でも、どちらの合わせ方をするかで残差は変わります。たとえば対角画角114度・フルサイズ・南向き高度40度・60秒なら、画面中央に合わせた場合が約24.14px、画面全体で最もよく合わせた場合が約17.85pxになります。
後者では画面全体の格子点を使い、最小二乗で最もよく合う平面の移動と回転を求めています。
どちらの合わせ方も、
「PENTAXがこう制御している」
という意味ではありません。
とくに後者は、
もしX/Y移動+回転という3つの動きだけを使って、画面全体へできるだけ都合よく合わせたら、どこまでいけるのか
を見るための計算です。
それでも残差が残る。
だからアストロトレーサー③で説明した、
「単に制御精度が悪いから周辺が流れるとは限らない」
という話につながります。
11 地上のブレは、もっと考え方が単純だった
図3:地上ブレは、動く撮像素子から見た静止した地上像の相対運動。
アストロトレーサー①②では、星だけでなく地上のブレも計算しました。
こちらは考え方がもっと簡単です。
カメラとレンズは三脚に固定されています。
ですから、理想化して考えれば地上の像そのものは像面上の同じ場所にあります。
でもアストロトレーサーを使うと、その下でセンサーが星を追って動きます。
するとセンサーから見れば、地上の像が反対方向へ流れていきます。
つまり、
地上を動かしているのではありません。
星を追うために動いたセンサーに対して、固定された地上像が相対的に動いて見える。
これがアストロトレーサー①②で使った地上ブレの基本的な考え方です。
12 500ルールと同じ式が出たのも、このためだった
アストロトレーサー②「何秒追尾すればいい?」で少し面白い結果を紹介しました。
固定撮影で使われてきた500ルールと、アストロトレーサー使用時の地上ブレを同じ許容量で考えると、同じ時間が出てきました。
これは偶然ではありません。
固定撮影では、
地球の自転によって星がセンサー上を動く。
アストロトレーサーでは、
その星の動きを打ち消すためにセンサーを動かす。
だから同じ角速度、同じ焦点距離、同じ許容移動量で考えれば、同じ関係式になります。
固定撮影で星が動く量も、アストロトレーサーで地上が流れる量も、同じ f・ω・T・cosδ という形になります。だから一致するのは偶然ではなく、式のうえで同じものを見ているということです。
このあたりは、計算してみて「なるほど」と思ったところでした。
13 魚眼との比較では、レンズの部分だけを入れ替えた
アストロトレーサー③で行った魚眼との比較も、基本的には同じ計算です。
星を作る。
地球を回す。
もう一度投影する。
センサーをX/Y移動+回転させる。
残った最大ズレを測る。
変えたのは主に、
レンズが空をセンサーへどう投影するか
です。
しかも同じ焦点距離だけで比べると写る範囲そのものが変わってしまいます。
そこで主要な比較では、通常の広角と魚眼が同じ対角画角になるよう条件を揃えました。
その状態で投影方式だけを変え、同じ計算を繰り返したわけです。
その結果が、
同じ画角なら、今回調べた範囲では魚眼のほうが追尾残差が小さかった
というアストロトレーサー③の結果です。
たとえば対角114°の比較では、アストロトレーサー③で示した通常広角24.14px・魚眼3方式3.67px、4.53px、5.12pxが、画面中央に合わせた場合の値です。
同じ条件を、画面全体で最もよく合わせた場合に切り替えると、通常広角17.85px、魚眼3方式は3.32px、3.35px、4.85pxになります。合わせ方を変えても、魚眼のほうが小さいという関係は変わりません。どちらもモデル上の合わせ方であって、PENTAX実機の追尾アルゴリズムを表すものではありません。
14 赤道儀だけは、計算する場所そのものが違う
図4:計算の上でも、赤道儀は投影の前で補正が入る。理想化モデルでは星の残差が0.00pxになるが、これは極軸合わせの誤差・たわみ・大気差をモデルに入れていないためで、現実の赤道儀の誤差がゼロという意味ではない。
アストロトレーサー③で赤道儀との違いも書きました。
これも計算モデルにすると、とても分かりやすくなります。
アストロトレーサーでは、
星が動く
→ レンズで投影する
→ できた像をセンサーで追う
という順番です。
一方、理想的な赤道儀では、星が動くのと同じだけカメラとレンズそのものを回します。
つまり、
レンズへ投影する前に、星とカメラの相対的な向きを保つ
ことになります。
今回の理想モデルでは、星とカメラを同じ回転行列で回しているため、カメラから見た星の方向が変わりません。
その結果、モデル上の星の追尾残差は0.00pxになります。
もちろん、
現実の赤道儀なら誤差ゼロ
という意味ではありません。
実際には極軸合わせの誤差、ピリオディックモーション、たわみ、大気差などがあります。
0.00pxなのは、それらを入れていない理想モデルだからです。
15 では、この計算はどこまで信用できるのか
ここまで説明すると、今度は逆の疑問が出てきます。
「モデルで計算した数字は、本当に信用できるのか?」
今回のモデルには、入れていないものがたくさんあります。
実際のPENTAX内部の制御アルゴリズム。
機械的な誤差。
キャリブレーション誤差。
大気差。
レンズ収差。
振動。
実際のレンズ固有の歪曲。
そうしたものを全部再現したシミュレーターではありません。
だから、
「実際のK-1で14mm・60秒なら必ず24.18px流れる」
とは言えません。
24.18pxという数字は、あくまで今回設定した理想化モデルの結果です。
なお、アストロトレーサー③に出てくる24.14pxは対角画角を114度ちょうどに揃えたときの値、こちらの24.18pxは焦点距離を14mmに固定したときの値です。ほとんど同じ条件ですが、何を揃えたかが違うので、数字もわずかに違います。
では何の役に立つのか。
たとえば、
センサーをX/Y+回転させるだけで、天球の動きを画面全体で完全に打ち消せるのか。
通常広角と魚眼では、投影方式だけで追尾残差にどんな違いが出るのか。
赤道儀とセンサーシフトでは、なぜ結果が違うのか。
こうした仕組みそのものを切り分けて考えるために使っています。
16 計算したら終わり、にはしなかった
もう一つ、今回かなり気をつけたことがあります。
AIを使って計算コードを作れば、数字そのものはいくらでも出せます。
でも、その数字が正しいかどうかは別です。
そこでアストロトレーサー①〜③で使用した主要な数値について、既存の計算結果、単位変換、投影式、同一画角条件などを再度機械的に照合しました。
検証したのは166項目です。
結果は、
165 PASS / 1 FAIL
でした。
そして、その1件は計算結果の誤りではありませんでした。
フルサイズセンサーの半対角について、文章に書いた数値の表記を間違えていたものです。
検証項目としては1件ですが、同じ書き間違いが複数の下書きに入っていました。
正しい値に直して再確認しても、計算結果は変わりませんでした。既存の主要数値や魚眼比較のself-validationもPASSしています。
むしろ、この再検証をしたことで記述ミスを一つ見つけられました。
17 AIに計算してもらう、ということ
今回、私は計算コードそのものを一から手で書いたわけではありません。
AIをかなり使っています。
でも、今回やってみて改めて思ったのは、
AIに計算させることと、AIが出した数字を信じることは同じではない
ということです。
何を計算するのか。
どこまでを現実として扱い、どこからを理想化するのか。
結果の○pxは何を意味しているのか。
別の方法でも既知の結果を再現できるのか。
そこを確認しないまま数字だけ使ってしまえば、私自身も説明できません。
今回の記事を書くために計算方法をもう一度コードから整理してみて、少なくとも、
何をモデル化したのか。
何を入力したのか。
何を比較したのか。
○pxとは何を測った数字なのか。
そこまでは自分の言葉で説明できる形にしました。
まとめ
今回の計算を、もう一度ものすごく簡単にまとめると、
画面に点を置く
↓
その点に写る星が空のどこにあるか逆算する
↓
地球を露光時間ぶん回す
↓
星をもう一度レンズで画面へ写す
↓
センサーをX/Y方向へ動かし、回転させて星を追う
↓
それでも残ったズレを測る
↓
露光中・画面全体で最も大きかったズレをpxにする
という計算です。
これがアストロトレーサー①〜③に出てきた、
「追尾残差○px」
の正体です。
数式だけを見るとかなり難しいことをしているように見えます。
でも順番に追っていくと、
星がどこへ動くのかを計算して、センサーで追いかけて、それでも残ったズレを測っている。
基本的にはそれだけです。
そして、このモデルを使ったからこそ、
「超広角の周辺で星が流れるのは、本当に魚眼だからなのか?」
という、私が長い間そのままにしていた疑問を、もう一度調べ直すことができました。