5.22. レンズおよびパースペクティブ補正¶
幾何補正には、矩形から矩形へのマッピングでは扱えない方法で画像をゆがめる2つの種類があります。レンズ補正は、実際の広角レンズが生じさせる放射状のゆがみ(魚眼によるふくらみで、シーン内の直線がフレームの隅付近で目に見える曲線に曲げられる現象)を取り除きます。パースペクティブ補正は、レンズがシーンに対して垂直に向いていないときに生じるキーストーン効果(実世界の既知の矩形を画像内では非矩形のブロブに変えてしまう台形状のゆがみ)を取り除きます。どちらの補正も、撮影が済んだあとに、光学的な原因によって生じた効果を取り除くものです。
5.22.1. 放射状のレンズひずみ¶
実際のレンズ効果に関する資料では、安価な広角レンズが生じさせる樽型ひずみについて説明しています。フレームの中心付近のピクセルはおおむねピンホールモデルが予測する位置にありますが、端付近のピクセルは光軸からの放射距離の二乗に比例して外側に膨らみます。フレームの端付近を通るシーン内の直線は、撮影された画像内では目に見えて湾曲し、直線が直線のままであることを前提とする古典的なマシンビジョンのアルゴリズム(AprilTagのコーナー検出、エッジ追跡、ライン追従ナビゲーションなど)は、隅付近で誤った結果を出してしまいます。
lens_corr()はこのひずみを取り除きます。このメソッドは逆マッピングを実行します。すべての出力ピクセルは、レンズがそこから外側へ膨らませた入力位置からサンプリングされ、その結果は幾何学的にまっすぐな画像になります。
img.lens_corr(strength=1.8)
strengthパラメータはこの補正の中核です。これはレンズがどれだけ強く膨らませるかを表す単一の数値で、1.0付近の値は適度に広いレンズに対する穏やかな補正であり、強い魚眼に対しては約2.0までの値が妥当です。デフォルトの1.8は、標準のOpenMV Camレンズに対する妥当な出発点です。特定のレンズに対する適切な値は、いくつか試して画像を見ながら決めるものです。
2つの補助パラメータは通常デフォルトのままで問題ありません。zoom(デフォルト1.0)は出力を拡大縮小します。1より大きい値は、レンズ補正が隅をさらに外側へ押し出す分を補うために外側へクロップします。小さい値は補正後のシーンをより多く見えるようにしますが、その代わり画像の端に空白ピクセルが含まれます。x_corrとy_corrは、補正の中心を画像の幾何中心からずらします。これはレンズがセンサーの上に光学的に中心を合わせて配置されていない場合に役立ちます(まれなケースですが、知っておく価値があります)。
典型的なパイプラインは次のとおりです。撮影し、lens_corr()を一度実行して幾何形状をまっすぐにし、その結果に対してアプリケーションが実際に行う処理を実行します。
5.22.2. 3D回転補正¶
もう1つの種類の幾何ひずみは、センサー面がシーン面と平行でないときに生じるパースペクティブのゆがみです。古典的な例は、下から見た看板やナンバープレートです。看板の上端は下端よりレンズから遠いため、より小さく投影され、撮影された画像では矩形が、上辺が下辺より短い台形として写ります。
この修正方法は、撮影されたフレームに3D回転を適用して、センサー面を仮想的にシーン面と平行になるよう再配置することです。その数学は、AprilTag検出がタグの4つのコーナーからその姿勢を復元するために使う、まさに同じパースペクティブマッピングを逆向きに実行したものです。回転が与えられると、この演算はすべての出力ピクセルを、その回転が生じたであろう入力位置へと逆にマッピングします。
rotation_corr()はその補正を実行します。
img.rotation_corr(x_rotation=10.0, y_rotation=0.0, z_rotation=0.0)
3つの回転パラメータは度単位で、画像を中心とする仮想カメラのx、y、z軸まわりの回転を表します。x_rotationはカメラを上下に傾けます(地面の高さから壁を撮ったショットに対する自然な補正)。y_rotationはカメラを左右にパンします。z_rotationはカメラを光軸まわりに回転させます(水平でない取り付けに対する自然な補正)。
x_translationとy_translationは、仮想カメラを回転させずに横方向へ移動させます。zoom(デフォルト1.0)は出力を拡大縮小します。fov(デフォルト60.0)はカメラの垂直視野を表し、投影の計算に使われます。幾何形状の一貫性を保つために、この値は実際のレンズに一致させる必要があります。
任意のチルトとパンの組み合わせの場合、複数のゼロでない回転を1回の呼び出しで合成できます。演算の順序は実装内部で固定されており、アプリケーションは角度を与えるだけで結果が出力されます。
5.22.3. 既知の矩形を補正する¶
rotation_corr()の最もよく使われる便利な形式はcorners=キーワードで、入力画像内の既知の矩形のコーナーを表す4つの(x, y)タプルのリストを受け取ります。このメソッドは、真の矩形をそれらの特定の4点へマッピングしたであろう3D回転を計算し、その回転の逆を画像全体に適用して、既知の矩形が再び矩形になる結果を返します。
plate_corners = [(45, 80), (300, 60), (310, 180), (40, 200)]
img.rotation_corr(corners=plate_corners)
古典的な使い方は名前が示すとおりです。斜めの角度から撮影されたナンバープレート(あるいはその他の矩形の特徴)です。上流の段階がプレートを検出し、撮影された画像内でその4つのコーナー位置を報告します。それらのコーナーをrotation_corr()に渡すと、プレートが真の矩形として収まり、次に続く文字認識やテンプレートマッチングの段階に備えた画像が得られます。
4コーナー形式がアプリケーションの解決しようとしている問題を解く場合、6パラメータ形式よりもはるかに便利です。アプリケーションは回転角度を推定する必要がなく、メソッドに4点を渡すだけで、残りはメソッドが計算してくれます。6パラメータ形式は、シーン内に識別可能な矩形が見えず、外部の知識(たとえば校正済みの取り付け角度)から回転を手動で調整しなければならない場合に役立ちます。