相機标定相機标定的目的
擷取錄影機的内參和外參矩陣(同時也會得到每一幅标定圖像的選擇和平移矩陣),内參和外參系數可以對之後相機拍攝的圖像就進行矯正,得到畸變相對很小的圖像。
相機标定的輸入
标定圖像上所有内角點的圖像坐标,标定闆圖像上所有内角點的空間三維坐标(一般情況下假定圖像位于Z=0平面上)。
相機标定的輸出
錄影機的内參、外參系數。
拍攝的物體都處于三維世界坐标系中,而相機拍攝時鏡頭看到的是三維相機坐标系,成像時三維相機坐标系向二維圖像坐标系轉換。不同的鏡頭成像時的轉換矩陣不同,同時可能引入失真,标定的作用是近似地估算出轉換矩陣和失真系數。為了估算,需要知道若幹點的三維世界坐标系中的坐标和二維圖像坐标系中的坐标,也就是拍攝棋盤的意義。
相機成像
相機的成像原理:小孔成像
相機的内參相機的外參
在實際由于設計工藝問題、相機安裝環境或物體擺放位置等影響,會照成成像與實際圖像不一樣的現象。
由于設計工藝照成的影響是無法改變的事實,是以這将是相機的内參;
由環境或安裝方式照成的影響是可以改變的,這就是相機的外參。
張正友标定相機原理
1.求得相機内參數:
用于标定的棋盤格是特制的,其角點坐标已知。标定棋盤格是三維場景中的一個平面∏,棋盤格在成像平面為π(知道了∏與π的對應點坐标之後,可求解兩個平面1對應的單應矩陣H)。
根據相機成像模型,P為标定的棋盤坐标,p為其像素點坐标。則
,通過對應的點坐标求解H後,可用于求K,R,T。
2.設棋盤格所在平面為世界坐标系上XOY平面,則棋盤格上任一角點P世界坐标系為(X,Y,0)。
3、内參限制條件
實驗步驟列印棋盤圖檔(網上找一張)
将列印出的紙固定放到一個平面上,使用同一相機從不同的位置,不同的角度,拍攝标定闆的多張照片(我拍了15張)手機型号是華為mate9
提取标定闆的世界坐标
标定闆的大小是标定闆在水準和豎直方向上内角點的個數。内角點指的是,标定闆上不挨着邊界的角點。
我列印的是6x9的标定闆。
标定相機
mtx -->内參數矩陣
dist --> 畸變系數
rvecs --> 旋轉向量
tvecs --> 平移向量
我們可以通過反投影誤差來評估結果的好壞,越接近0,說明結果越理想。
通過之前計算的内參數矩陣、畸變系數、旋轉矩陣和平移向量,使用cv2.projectPoints()計算三維點到二維圖像的投影,然後計算反投影得到的點與圖像上檢測到的點的誤差,最後計算一個對于所有标定圖像的平均誤差即反投影誤差
我的棋盤列印出來有些不平整,可能是列印的紙張沒有放正,導緻有些地方翹着,效果不是很好,誤內插補點有些大了,把紙張貼平整應該會好很多。而且我可能拍照的角度變化不是太大,可以試着把拍照的角度更加差異些,結果會更明顯。
import cv2
import numpy as np
import glob
# 設定尋找亞像素角點的參數,采用的停止準則是最大循環次數30和最大誤差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)
# 擷取标定闆角點的位置
objp = np.zeros((6 * 9, 3), np.float32)
objp[:, :2] = np.mgrid[0:9, 0:6].T.reshape(-1, 2) # 将世界坐标系建在标定闆上,所有點的Z坐标全部為0,是以隻需要指派x和y
obj_points = [] # 存儲3D點
img_points = [] # 存儲2D點
images = glob.glob("E:/test_pic/qipan/*.jpg")
for fname in images:
img = cv2.imread(fname)
cv2.imshow('img',img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
size = gray.shape[::-1]
ret, corners = cv2.findChessboardCorners(gray, (6, 9), None)
print(ret)
if ret:
obj_points.append(objp)
corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria) # 在原角點的基礎上尋找亞像素角點
#print(corners2)
if [corners2]:
img_points.append(corners2)
else:
img_points.append(corners)
cv2.drawChessboardCorners(img, (8, 6), corners, ret) # 記住,OpenCV的繪制函數一般無傳回值
cv2.imshow('img', img)
cv2.waitKey(2000)
print(len(img_points))
cv2.destroyAllWindows()
# 标定
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, size, None, None)
print("ret:", ret)
print("mtx:\n", mtx) # 内參數矩陣
print("dist:\n", dist) # 畸變系數 distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print("rvecs:\n", rvecs) # 旋轉向量 # 外參數
print("tvecs:\n", tvecs ) # 平移向量 # 外參數
print("-----------------------------------------------------")
以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援我們。
時間: 2020-04-08