目的
この章では、以下の方法を学ぶ
- カメラをキャリブレーションし、倍率色収差を補正するための係数を取得する。
- 赤/青チャンネルのずれをモデル化したこれらの係数をエクスポートする。
- OpenCV の関数を用いて画像を補正する。
基礎
倍率色収差は、異なる波長がわずかに異なる画像位置に結像することで生じる。その結果、高コントラストのエッジに赤/青のフリンジが現れ、特に古いカメラや低品質のカメラ・レンズで多く見られる。これはレンズの特性であり、そのカメラとレンズで撮影したすべての画像に一貫して現れる。
Chromatic Aberration Example
画像クレジット: PawełS, CC BY-SA 3.0 http://creativecommons.org/licenses/by-sa/3.0/, via Wikimedia Commons
倍率色収差を、基準となる緑チャンネルに対する赤チャンネルと青チャンネルの幾何学的歪みとして扱い、赤と青のチャンネルを緑にそろえるマッピングの推定を目指す。
この補正は、倍率色収差に関する Rudakova らの論文に従う。各チャンネルのずれは、ある次数の多項式としてモデル化される。赤/青チャンネルと緑チャンネルにおける中心の正確な位置間の距離を、これらの中心のワープによって最小化する。
この論文では、適切なフィッティングを得るために、多項式モデルの係数数よりもはるかに多い黒い円盤のキャリブレーションパターンを使用することも提案している。次数11がよく用いられるが、より小さい次数でも、はるかに優れたパフォーマンスで同等の精度を達成できる。
キャリブレーション
チャンネルのずれのモデルを作成するために、以下のキャリブレーション手順を用いる:
- opencv_extra/testdata/cv/cameracalibration/chromatic_aberration/chromatic_aberration_pattern_a3.png にあるキャリブレーション用の写真を印刷する。この写真は白背景に黒い円盤を並べたグリッドであり、色収差のフリンジは写真内の物体のエッジに現れるため、さまざまなずれを多数観察し、それらを精密にモデル化できる。
- 印刷したキャリブレーショングリッドをカメラで1枚以上撮影する。色収差は写真の端や隅で最も強く現れるため、すべての円盤が写真に収まり、グリッドができるだけ広い範囲を占めるようにする。色フリンジが肉眼で確認できるはずである。
- キャリブレーションを実行する。chromatic_calibration.py を参照のこと。このアプリは以下のように使用できる:
chromatic_calibration.py calibrate [-h] [--degree DEGREE] --coeffs_file YAML image
chromatic_calibration.py correct [-h] --coeffs_file YAML [-o OUTPUT] image
chromatic_calibration.py full [-h] [--degree DEGREE] --coeffs_file YAML [-o OUTPUT] image
chromatic_calibration.py scan [-h] --degree_range k0 k1 image
Calibrate は多項式係数を推定し、補正関数で使用するために YAML ファイルへ出力する。
- BGR を分割し、各チャンネルの円盤中心をサブピクセル精度で求める。
- KD木を用いて中心を緑チャンネルにペアリングする。
--degree までの単項式の項を構築し、最小二乗法で解いたのち、別の最適化アルゴリズムで精緻化する。
- Saves a YAML with:
image_width, image_height
red_channel/blue_channel: coeffs_x, coeffs_y (長さ $M=(d+1)(d+2)/2$)、および rms 残差。
Scan は多項式の次数範囲を走査し、品質を比較する。次数が高いほどほぼ常に収差をうまくモデル化できるはずだが、低い次数のほうがはるかに高速な場合がある。
- k0,..,k1(両端を含む)の各次数についてキャリブレーションを実行し、各次数のモデルをフィッティングする。
- 各チャンネルの完全な円盤輪郭を抽出する。
- 各次数の多項式を用いて R/B の輪郭を G に向けてワープし、最近傍距離を測定する。
- 赤と青について、最大/平均/標準偏差の距離(ピクセル単位)の表を出力する。
- その後、ユーザーは最も適した次数を選択し、その特定の次数でカメラをキャリブレーションできる。
コード
色収差補正の最小限の Python 例:
import cv2 as cv
INPUT = "path/to/input.jpg"
CALIB_YAML = "path/to/ca_photo_calib.yaml"
OUTPUT = "corrected.png"
BAYER = -1
SHOW = True
FileStorage fs(parsed_args.coeffs_file, FileStorage::READ);
coeffMat, calib_size, degree = cv2.loadChromaticAberrationParams(fs.root())
corrected = cv.correctChromaticAberration(img, coeffMat, calib_size, degree, BAYER)
if SHOW:
cv.namedWindow("Original", cv.WINDOW_AUTOSIZE)
cv.namedWindow("Corrected", cv.WINDOW_AUTOSIZE)
cv.imshow("Original", img)
cv.imshow("Corrected", corrected)
print("Press any key to close...")
cv.waitKey(0)
cv.destroyAllWindows()
cv.imwrite(OUTPUT, corrected)
追加リソース
[240]