私は同じ状況にありました。非平面 3D ターゲットがありますが、キャリブレーション プロセスに OpenCV の非線形 LM 最適化を使用したいと考えていました。(OpenCV で使用される Zhang の初期化方法では、平面キャリブレーション ターゲットのみが許可されます)
できることは、独自の DLT 結果からカメラ行列を抽出し、これを の初期推定として使用することですcalibrateCamera
。1 組 (カメラ ポイント - オブジェクト ポイント) だけで十分です。他のペアは他のカメラ マトリックスを生成する可能性がありますが、それらは類似していることを願っており、初期化のためにのみそのマトリックスが必要になります。
ただし、独自の DLT を使用すると、P
同種のワールド ポイントX
を hom にマッピングする射影行列が得られると思います。画像点x
経由での発送となりx = P * X
ます。
これは行くべき道でしょう、それはPythonにありますが、あなた自身のニーズに適応できるはずです:
P = YOUR_DLT(imagePoints[0], objectPoints[0])
cameraMatrix, _, _, _, _, _, _ = cv2.decomposeProjectionMatrix(P)
cameraMatrix /= cameraMatrix[2,2] # ensure unit elem[2,2]
cameraMatrix[0,1] = 0 # ensure no skew
cameraMatrix[0,0] = abs(cameraMatrix[0,0]) # ensure positive focal lengthes
cameraMatrix[1,1] = abs(cameraMatrix[1,1])
# ensure principal point within image:
cameraMatrix[0,2] = min(resX-1, max(0, cameraMatrix[0,2]))
cameraMatrix[1,2] = min(resY-1, max(0, cameraMatrix[1,2]))
retval, cameraMatrix, distCoeffs, rvecs, tvecs = \
cv2.calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix)
calibrateCamera
は、正の焦点距離と 0 のスキューを想定し、それcameraMatrix[2,2]==1
に制約されているため、上記のコードで示したように、カメラ マトリックスを修正する必要があることに注意してください。