opencv チュートリアルチャレンジ カメラキャリブレーション
カメラキャリブレーション — OpenCV-Python Tutorials 1 documentation
Aruco で estimatePoseSingleMarkers を試したいと思ったところ、cameraMatrix と distCoeffs が必要だと判明。
OpenCV: ArUco Marker Detection
estimatePoseSingleMarkers Pose estimation for single markers.
cameraMatrix と distCoeffs は、カメラ行列(内部パラメータ)
レンズ歪みパラメータ
らしい。
Camera Calibration and 3D Reconstruction — OpenCV 3.0.0-dev documentation
Python: cv2.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs[, rvecs[, tvecs[, flags[, criteria]]]]) → retval, cameraMatrix, distCoeffs, rvecs, tvecs
とにかく取得しましょう。
チェスボードを用意する
https://github.com/opencv/opencv/tree/master/samples/data
こちらから、chessboard.png
を取得し、印刷。
曲がらないように、板に貼り付けました。
画像を用意する
キャリブレーションしたいカメラ(今回はWEBカメラ)で、チェスボード用紙を、いろんな角度から撮影します。
(背景にいろいろ写り込んでいたので、写真の掲載は控えます)
ディレクトリ calib を作成し、入れ込んでおきます。
パラメーターを算出する
こちらを参考(ほぼそのまま)にしました。
csharp/calibration.py at master · tanaka0079/csharp · GitHub
myCalib.py
# -*- coding: utf-8 -*- import numpy as np import cv2 from glob import glob def main(): square_size = 1.0 # 正方形のサイズ pattern_size = (7, 7) # 交差ポイントの数 pattern_points = np.zeros( (np.prod(pattern_size), 3), np.float32 ) #チェスボード(X,Y,Z)座標の指定 (Z=0) pattern_points[:,:2] = np.indices(pattern_size).T.reshape(-1, 2) pattern_points *= square_size objpoints = [] imgpoints = [] for fn in glob("calib/*.jpg"): # 画像の取得 gray = cv2.imread(fn, 0) print("loading..." + fn) # チェスボードのコーナーを検出 ret, corner = cv2.findChessboardCorners(gray, pattern_size) # コーナーがあれば if ret == True: term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1) cv2.cornerSubPix(gray, corner, (5,5), (-1,-1), term) else: print('Chessboard not found!') continue imgpoints.append(corner.reshape(-1, 2)) #appendメソッド:リストの最後に因数のオブジェクトを追加 objpoints.append(pattern_points) #corner.reshape(-1, 2) : 検出したコーナーの画像内座標値(x, y) # 内部パラメータを計算 ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) # 計算結果を表示 print("RMS = ", ret) print("mtx = \n", mtx) print("dist = ", dist.ravel()) # 計算結果を保存 np.savetxt("ret.csv", np.array([ret]), delimiter =',',fmt="%0.14f") np.savetxt("mtx.csv", mtx, delimiter =',',fmt="%0.14f") if __name__ == '__main__': main()
私の結果は、
mtx
1420.68234847996541,0.00000000000000,949.20851179562965 0.00000000000000,1374.16684667116965,539.62205073603297 0.00000000000000,0.00000000000000,1.00000000000000
ret
1.129281781
でした。