1. 程式人生 > >單目相機標定(Camera Calibration)

單目相機標定(Camera Calibration)

為什麼需要相機標定

通過image formation pipeline, 我們可以將已知世界座標系上的點對映在畫素座標系上,那麼如何預測影象上的點在3d世界中的位置呢?

第一步便是相機標定。相機標定的工作是消除鏡頭造成的影象變形(distortion)。

image formation pipeline

世界座標系中的點imP轉換到畫素座標系中的點Wp,可以表示為:

imP=MWp
其中M=KCTWK為相機的內參數,由相機自身決定;CTW為外引數,由位移和旋轉決定。相機標定所要求的便是矩陣M

內參數由5個引數組成,分別是: f, Sx, Sy, Ox, Oy

外引數由兩個部分組成:旋轉矩陣R和位移矩陣t

這裡寫圖片描述

K

中的s被稱為skew。

DLT(direct linear transform)進行相機標定

M是一個3*4、自由度為11的矩陣。我們已知的只有一系列圖片上的點座標,為了求出3d世界中點和圖片上點的轉換關係(也就是M),需要使用homography來解決問題。

具體步驟:

  1. 使用標定板獲得一系列圖片和3d世界中的對應點。
  2. 利用對應點構造homography等式,求出M

建成的homography關係式:

這裡寫圖片描述

提取出未知變數m11, m12….,化成Aq=0形式,q=[m11, m12 …..]^T,A的形式為:

這裡寫圖片描述

使用svd分解法對A進行分解,便可求出q,也就求出了M。

從M中獲取資訊內外引數K, T

這裡使用的方法是QR分解法。對M進行svd可以求出位移矩陣t,而對M進行QR分解,Q部分為旋轉矩陣的逆(R^-1),R部分為內參數的逆(K^-1)。

python-opencv實現相機標定

使用命令cv2.calibrateCamera()可以直接進行標定。

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)

程式碼範例:

import cv2
import numpy as np
from matplotlib import
pyplot as plt def main(): # camera calibration to compute K criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) w = 7 h = 9 objp=np.zeros((w*h, 3), np.float32) objp[:, :2]=np.mgrid[0:w, 0:h].T.reshape(-1, 2) #store the world coord. and image coord. points objpoints=[] imgpoints=[] #images save in folder "hw6" images=glob.glob('hw6-for-camera-calibration/*.jpg') for fname in images: img=cv2.imread(fname) gray=cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #find the corner of checkboard ret, corners=cv2.findChessboardCorners(gray, (w,h), None) #save the points as long as find enough pair points if ret==True: cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria) objpoints.append(objp) imgpoints.append(corners) #calibration ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None) K = mtx #output K print 'K is: ' print K if __name__ == '__main__': main()

程式碼是從我自己的作業裡提出來的,僅作為範例,如有任何問題請私聊我。