自作している3Dスキャナーでも使用したい。
(OenCVでは)カメラパラメータのfx, fyはピクセル単位で扱われるため、以下のように計算すればmm単位での焦点距離は求められる。
焦点距離(mm) = fx × W ÷ w
fx : 焦点距離(pixel)
W : イメージセンサーの幅(mm)
w : 画像の幅(pixel)
電卓で計算すればよいのだけど、OpenCVにはcv::calibrationMatrixValuesのAPIで焦点距離を含むカメラのスペックを計算してくれる。
せっかくなので、このAPIをPythonで使って見ようと思う。
使い方
まず、カメラパラメータと画像の解像度を読み込む。
これは、"opencv_interactive-calibration"で出力したファイルから読み込んでいる。
そして、calibrationMatrixValuesを呼び出す。
fs = cv2.FileStorage("PathToCameraParameterFile", cv2.FILE_STORAGE_READ)
if fs.isOpened():
        width = (int)(camera_fs.getNode("cameraResolution").at(0).real())
        height = (int)(camera_fs.getNode("cameraResolution").at(1).real())
        camera_matrix = camera_fs.getNode("cameraMatrix").mat()
そして、calibrationMatrixValuesを呼び出す。
fovx, fovy, focal_length, principal_point, aspect_ratio = cv2.calibrationMatrixValues(camera_matrix,
            (width, height), aperture_width, aperture_height)
print("  FOVX = ", "{:.6f}".format(fovx))
print("  FOVY = ", "{:.6f}".format(fovy))
print("  Focal length    = ", "{:.6f}".format(focal_length))
print("  Principal point = ", "{:.6f}, {:6f}".format(*principal_point))
print("  Aspect ratio    = ", "{:.6f}".format(aspect_ratio))
引数には以下を指定する。- cameraMatrix カメラパラメータ(先程ファイルから得たパラメータ)
 - imageSize 画像の解像度(先程ファイルから得たパラメータ, 単位:pixel)
 - apertureWidth イメージセンサーの幅(単位:mm)
 - apertureHeight イメージセンサーの高さ(単位:mm)
 
戻り値にはカメラのスペックが返る。
- fovx 垂直画角(単位:度)
 - fovy 水平画角(単位:度)
 - focalLength 焦点距離(単位:mm)
 - principalPoint 主点(単位:mm)
 - aspectRatio fy / fz
 
試してみる
PiCamera V2.1でカメラキャリブレーションを行った結果で試してみる。
キャリブレーションした結果は以下の通りだった(chArucoパターンでキャリブレーション)。
<cameraResolution>
  640 480</cameraResolution>
<cameraMatrix type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>d</dt>
  <data>
    5.3447832911092576e+02 0. 3.1759911211440613e+02 0.
    5.3447832911092576e+02 2.3505836099223782e+02 0. 0. 1.</data></cameraMatrix>
cv::calibrationMatrixValuesでカメラのスペックを出力してみる。
イメージセンサーのサイズは、公式ドキュメントから3.68 x 2.76 mm を指定。
FOVX = 61.818399 FOVY = 48.360546 Focal length = 3.073250 Principal point = 1.826195, 1.351586 Aspect ratio = 1.000000
公式のドキュメントからと比較すると
- Sensor image area 3.68 x 2.76 mm (4.6 mm diagonal)
 - Focal length 3.04 mm
 - Horizontal field of view 62.2 degrees
 - Vertical field of view 48.8 degrees
 
なので、まずまず良いカメラキャリブレーションができたかな?
0 件のコメント:
コメントを投稿