目錄
1.針孔相機(jī)模型
2.相機(jī)成像過(guò)程
2.1? 各個(gè)坐標(biāo)系之間的轉(zhuǎn)換
2.1.1 圖像坐標(biāo)系到像素坐標(biāo)系?
2.1.2 相機(jī)坐標(biāo)系到圖像坐標(biāo)系
?2.1.3世界坐標(biāo)系到相機(jī)坐標(biāo)系
?2.1.4世界坐標(biāo)系到像素坐標(biāo)系
3.畸變與畸變矯正
3.1 畸變
3.2 畸變公式
4.相機(jī)標(biāo)定原理
5.張正友標(biāo)定法介紹
5.1張正友標(biāo)定法的整體流程
5.2 張正友標(biāo)定法的模型
5.3 模型求解
6.相機(jī)標(biāo)定的步驟
7.源代碼
8.實(shí)驗(yàn)結(jié)果及分析
8.1 實(shí)驗(yàn)結(jié)果
8.2 結(jié)果分析
1.針孔相機(jī)模型
? ? ? 針孔相機(jī)成像原理其實(shí)就是利用投影將真實(shí)的三維世界坐標(biāo)轉(zhuǎn)換到二維的相機(jī)坐標(biāo)上去,其模型示意圖如下圖所示:
? ? ??(X,Y,Z)為在世界坐標(biāo)系下一點(diǎn)的物理坐標(biāo)
? ? ? ( u , v ) 為該點(diǎn)對(duì)應(yīng)的在像素坐標(biāo)系下的像素坐標(biāo)
? ? ?引入齊次坐標(biāo)的原因:引入齊次坐標(biāo)的目的是為了升維,將坐標(biāo)從二維坐標(biāo)變?yōu)槿S坐標(biāo)。
?
2.相機(jī)成像過(guò)程
? ? ?相機(jī)成像系統(tǒng)中,共包含四個(gè)坐標(biāo)系:世界坐標(biāo)系、相機(jī)坐標(biāo)系、圖像坐標(biāo)系、像素坐標(biāo)系。
??(1)世界坐標(biāo)系(,,)
? ? ? ? 描述目標(biāo)在真實(shí)世界中的位置引入的參考坐標(biāo)系。
? (2)相機(jī)坐標(biāo)系(,,)
? ? ? ? 聯(lián)系世界坐標(biāo)系與圖像坐標(biāo)系的橋梁,一般取攝像機(jī)的光學(xué)軸為z軸。
??(3)圖像坐標(biāo)系(x,y)
? ? ? ? 根據(jù)投影關(guān)系引入,方便進(jìn)一步得到像素坐標(biāo),單位為毫米,坐標(biāo)原點(diǎn)為攝像機(jī)光軸與圖像物理坐標(biāo)系的交點(diǎn)位置。
? (4)像素坐標(biāo)系(u,v)
? ? ? ? 真正從相機(jī)內(nèi)讀到的信息,圖像物理坐標(biāo)的離散化,以像素為單位,坐標(biāo)原點(diǎn)在左上角。
2.1? 各個(gè)坐標(biāo)系之間的轉(zhuǎn)換
2.1.1 圖像坐標(biāo)系到像素坐標(biāo)系?
? ? ?像素坐標(biāo)系和圖像坐標(biāo)系都在成像平面上,只是各自的原點(diǎn)和度量單位不一樣。
? ? ? 由于(u,v)只代表像素的列數(shù)與行數(shù),而像素在圖像中的位置并沒(méi)有用物理單位表示出來(lái),所以,我們還要建立以物理單位(如毫米)表示的圖像坐標(biāo)系(x,y)。將相機(jī)光軸與圖像平面的交點(diǎn)(一般位于圖像平面的中心處,也稱為像主點(diǎn)(principal point)定義為該坐標(biāo)系的原點(diǎn),且x軸與u軸平行,y軸與v軸平行,假設(shè)(,)代表在(u,v)坐標(biāo)系下的坐標(biāo),dx與dy分別表示每個(gè)像素在橫軸x和縱軸y上的物理尺寸,則圖像中的每個(gè)像素在(u,v)坐標(biāo)系中的坐標(biāo)和在(x,y)坐標(biāo)系中的坐標(biāo)之間都存在如下的關(guān)系:
?
2.1.2 相機(jī)坐標(biāo)系到圖像坐標(biāo)系
? ? ?點(diǎn)P(Xc,Yc,Zc)由通過(guò)投影中心的光線投影到圖像平面上,相應(yīng)的圖像點(diǎn)為p(x,y,f);根據(jù)相似三角形原理:
用線性矩陣描述為:
?2.1.3世界坐標(biāo)系到相機(jī)坐標(biāo)系
? ? ? 世界坐標(biāo)系是為了描述相機(jī)的位置而被引入,上圖中坐標(biāo)系OwXwYwZw即為世界坐標(biāo)系。平移向量t旋轉(zhuǎn)矩陣R可以用來(lái)表示相機(jī)坐標(biāo)系與世界坐標(biāo)系的關(guān)系。所以,假設(shè)空間點(diǎn)P在世界坐標(biāo)系下的齊次坐標(biāo)是,在相機(jī)坐標(biāo)下的齊次坐標(biāo)是,則存在如下關(guān)系:? ?
? ? ? ? ?其中 R為3x3的旋轉(zhuǎn)矩陣,t為3x1的平移矢量。
?2.1.4世界坐標(biāo)系到像素坐標(biāo)系
? ? ? ?世界坐標(biāo)系到像素坐標(biāo)系的變換可由上面的公式組合而成:
? ? ?其中M1稱為相機(jī)的內(nèi)部參數(shù)矩陣,M2稱為相機(jī)的外部參數(shù)矩陣,M稱為投影矩陣?。
3.畸變與畸變矯正
3.1 畸變
? ? ?在世界坐標(biāo)中的一條直線上的點(diǎn)在相機(jī)上只呈現(xiàn)出了一個(gè)點(diǎn),其中發(fā)生了非常大的變化,同時(shí)也損失和很多重要的信息,這正是我們3D重建、目標(biāo)檢測(cè)與識(shí)別領(lǐng)域的重點(diǎn)和難點(diǎn)。實(shí)際中,鏡頭并非理想的透視成像,帶有不同程度的畸變。理論上鏡頭的畸變包括徑向畸變和切向畸變,切向畸變影響較小,通常只考慮徑向畸變。
? ? ?徑向畸變:徑向畸變主要由鏡頭徑向曲率產(chǎn)生(光線在遠(yuǎn)離透鏡中心的地方比靠近中心的地方更加彎曲)。導(dǎo)致真實(shí)成像點(diǎn)向內(nèi)或向外偏離理想成像點(diǎn)。其中畸變像點(diǎn)相對(duì)于理想像點(diǎn)沿徑向向外偏移,遠(yuǎn)離中心的,稱為枕形畸變;徑向畸點(diǎn)相對(duì)于理想點(diǎn)沿徑向向中心靠攏,稱為桶狀畸變。
桶狀畸變:
枕形畸變:
3.2 畸變公式
徑向畸變公式:
切向畸變公式:
? ? 其中,(),()分別為理想的無(wú)畸變的歸一化的圖像坐標(biāo)、畸變后的歸一化圖像坐標(biāo),為圖像像素點(diǎn)到圖像中心點(diǎn)的距離,即
?相機(jī)標(biāo)定的第二個(gè)目的就是獲得相機(jī)的畸變參數(shù),如上式中的
4.相機(jī)標(biāo)定原理
? ? ? ?針對(duì)針孔相機(jī)模型,只要內(nèi)參矩陣和外參矩陣就可以唯一的確定相機(jī)模型。這個(gè)過(guò)程就稱為相機(jī)標(biāo)定。相機(jī)標(biāo)定的目的是為了獲得相機(jī)的內(nèi)參矩陣和外參矩陣。相機(jī)標(biāo)定的內(nèi)參主要包括焦距、像主點(diǎn)坐標(biāo)、畸變參數(shù)。
? ? ? 通過(guò)世界坐標(biāo)集(,,),以及它們?cè)趫D像平面上的投影坐標(biāo)集(,),計(jì)算相機(jī)投影 矩陣M中的 11個(gè)未知參數(shù)。
相機(jī)模型:
線性方法:
非線性方法:
5.張正友標(biāo)定法介紹
? ? ? 張正友標(biāo)定法利用如下圖所示的棋盤格標(biāo)定板,在得到一張標(biāo)定板的圖像之后,可以利用相應(yīng)的圖像檢測(cè)算法得到每一個(gè)角點(diǎn)的像素坐標(biāo)( u , v ) 。
? ? ?張正友標(biāo)定法將世界坐標(biāo)系固定于棋盤格上,則棋盤格上任一點(diǎn)的物理坐標(biāo)W = 0 ,由于標(biāo)定板的世界坐標(biāo)系是人為事先定義好的,標(biāo)定板上每一個(gè)格子的大小是已知的,我們可以計(jì)算得到每一個(gè)角點(diǎn)在世界坐標(biāo)系下的物理坐標(biāo)( U , V , W = 0 ) 。
? ? ? 我們將利用這些信息:每一個(gè)角點(diǎn)的像素坐標(biāo)( u , v ) 、每一個(gè)角點(diǎn)在世界坐標(biāo)系下的物理坐標(biāo)( U , V , W = 0 ),來(lái)進(jìn)行相機(jī)的標(biāo)定,獲得相機(jī)的內(nèi)外參矩陣、畸變參數(shù)。
5.1張正友標(biāo)定法的整體流程
5.2 張正友標(biāo)定法的模型
? ? ? 2D圖像點(diǎn):
? ? ? 3D圖像點(diǎn):
? ? ? ?描述空間坐標(biāo)到圖像坐標(biāo)的映射:
? ? ? ?? ?
5.3 模型求解
? ? 張正友標(biāo)定法標(biāo)定相機(jī)的內(nèi)外參數(shù)的思路如下:
? ? ? 1)、求解內(nèi)參矩陣與外參矩陣的積;
? ? ? 2)、求解內(nèi)參矩陣;
? ? ? 3)、求解外參矩陣。
? 1)求解內(nèi)參與外參的積
? ? ? ? ? ?不妨設(shè)棋盤格位于Z=0
? ? ? ? ? ?定義旋轉(zhuǎn)矩陣R的第i列為ri,則有:
? ? ? ? ? ? ?于是空間到圖像的映射可改為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? 令H為
? ? ? ? ? ? Homography 有 8 個(gè)自由度,
? ? ? 其中,H為一個(gè)3*3的矩陣,并且有一個(gè)元素作為齊次坐標(biāo)。因此,H有8個(gè)自由度?,F(xiàn)在有8個(gè)自由度需要求解,所以需要四個(gè)對(duì)應(yīng)點(diǎn)。也就是四個(gè)點(diǎn)就可以求出圖像平面到世界平面的單應(yīng)性矩陣H。通過(guò)4個(gè)點(diǎn),我們就可以可以獲得單應(yīng)性矩陣H。但是,H是內(nèi)參陣和外參陣的合體。
? ? ?由于和是通過(guò)單應(yīng)性求解出來(lái)的,所以我們要求解的參數(shù)就變成K矩陣中未知的5個(gè)參數(shù)。我們可以通過(guò)三個(gè)單應(yīng)性矩陣來(lái)求解這5個(gè)參數(shù),利用三個(gè)單應(yīng)性矩陣在兩個(gè)約束下可以生成6個(gè)方程。其中,三個(gè)單應(yīng)性矩陣可以通過(guò)三張對(duì)同一標(biāo)定板不同角度和高度的照片獲得。
2)求解內(nèi)參
? ? ?定義
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? B是對(duì)稱矩陣,其未知量可表示為6D向量b,
? ? 設(shè)H中的第i列為,
? ? 根據(jù)b的定義,推導(dǎo)出:
? ? 可以推導(dǎo)出
? ??當(dāng)觀測(cè)圖像大于或等于三幅圖像時(shí),就可以得到b的唯一解,應(yīng)用上述公式我們就可以估算出B了。
? ? ? B是通過(guò)b構(gòu)造的對(duì)稱矩陣。
? ? ? 得到B后,我們通過(guò)cholesky分解?,就可以得到攝相機(jī)機(jī)的內(nèi)參陣A的六個(gè)自由度,即
?3)求解外參
? ? ? 根據(jù)化簡(jiǎn)可得外部參數(shù),即:
6.相機(jī)標(biāo)定的步驟
? ?(1)準(zhǔn)備一個(gè)張正友標(biāo)定法的棋盤格,棋盤格大小已知,用相機(jī)對(duì)其進(jìn)行不同角度的拍攝,得到一組圖像;
? (2)對(duì)圖像中的特征點(diǎn)如標(biāo)定板角點(diǎn)進(jìn)行檢測(cè),得到標(biāo)定板角點(diǎn)的像素坐標(biāo)值,根據(jù)已知的棋盤格大小和世界坐標(biāo)系原點(diǎn),計(jì)算得到標(biāo)定板角點(diǎn)的物理坐標(biāo)值;
? (3)求解內(nèi)參矩陣與外參矩陣;
? (4)求解畸變系數(shù);
? (5)利用L-M(Levenberg-Marquardt)算法對(duì)上述參數(shù)進(jìn)行優(yōu)化。
7.源代碼
import cv2
import glob
import numpy as np
w = 9 # 內(nèi)角點(diǎn)個(gè)數(shù),內(nèi)角點(diǎn)是和其他格子連著的點(diǎn)
h = 6
objp = np.zeros((w * h, 3), np.float32)#一個(gè)9*6行3列的矩陣
objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)# 儲(chǔ)存棋盤格角點(diǎn)的世界坐標(biāo)和圖像坐標(biāo)對(duì) reshape(-1, 2)-1表示不確定分幾行,2表示分為2列
objp=2.6*objp #棋盤格實(shí)際大小
objpoints = [] # 在世界坐標(biāo)系中的三維點(diǎn)
imgpoints = [] # 在圖像平面的二維點(diǎn)
images = glob.glob('photo2/*.jpg')
# 取文件夾中所有圖片
for fname in images:
# 對(duì)每張圖片,識(shí)別出角點(diǎn),記錄世界物體坐標(biāo)和圖像坐標(biāo)
img = cv2.imread(fname)#獲取圖像的水平方向和垂直方向的尺寸
img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)#立方插值法 縮放到原來(lái)的二分之一
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 轉(zhuǎn)灰度
# 尋找角點(diǎn),存入corners,ret是找到角點(diǎn)的flag
ret, corners = cv2.findChessboardCorners(gray, (9, 6), None)
# criteria:角點(diǎn)精準(zhǔn)化迭代過(guò)程的終止條件
criteria = (cv2.TERM_CRITERIA_MAX_ITER+ cv2.TERM_CRITERIA_EPS , 30, 0.001)#第一項(xiàng)表示迭代次數(shù)達(dá)到最大次數(shù)時(shí)停止迭代,第二項(xiàng)表示角點(diǎn)位置變化的最小值已經(jīng)達(dá)到最小時(shí)停止迭代
# 執(zhí)行亞像素級(jí)角點(diǎn)檢測(cè)
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) # 輸入圖像、角點(diǎn)初始坐標(biāo)、搜索窗口為2*winsize+1、第四個(gè)參數(shù)作用類似于winSize,但是總是具有較小的范圍,通常忽略(即Size(-1, -1)), 求角點(diǎn)的迭代終止條件
objpoints.append(objp)# .append()向列表/數(shù)組添加元素
imgpoints.append(corners2)
# 在棋盤上繪制角點(diǎn)
img = cv2.drawChessboardCorners(img, (9, 6), corners2, ret)
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.imshow('img', img)
cv2.waitKey(1000)
'''
傳入所有圖片各自角點(diǎn)的三維、二維坐標(biāo),相機(jī)標(biāo)定。
每張圖片都有自己的旋轉(zhuǎn)和平移矩陣,但是相機(jī)內(nèi)參和畸變系數(shù)只有一組。
mtx,相機(jī)內(nèi)參;dist,畸變系數(shù);rvecs,旋轉(zhuǎn)矩陣;tvecs,平移矩陣。
'''
# 輸入:世界坐標(biāo)系里的位置 像素坐標(biāo) 圖像的像素尺寸大小 3*3矩陣,相機(jī)內(nèi)參數(shù)矩陣 畸變矩陣
#使用cv2.calibrateCamera()進(jìn)行標(biāo)定,這個(gè)函數(shù)會(huì)返回標(biāo)定結(jié)果、相機(jī)的內(nèi)參數(shù)矩陣、畸變系數(shù)、旋轉(zhuǎn)矩陣和平移向量
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
img = cv2.imread('photo2/5.jpg')
img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
h, w = img.shape[:2]
'''
使用cv.getOptimalNewCameraMatrix()優(yōu)化內(nèi)參數(shù)和畸變系數(shù)
參數(shù)1表示保留所有像素點(diǎn),同時(shí)可能引入黑色像素,并返回一個(gè)ROI用于將其剪裁掉
設(shè)為0表示盡可能裁剪不想要的像素,這是個(gè)scale,0-1都可以取。
'''
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))
# 糾正畸變
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
# 輸出糾正畸變以后的圖片
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv2.imwrite('result.png', dst)
# 輸出:標(biāo)定結(jié)果 相機(jī)的內(nèi)參數(shù)矩陣 畸變系數(shù) 旋轉(zhuǎn)矩陣 平移向量
mtx_new=mtx.tolist()
print("相機(jī)內(nèi)參矩陣:\n", mtx_new)#[fx,s,x0;0,fy,y0;0,0,1],fx,fy為焦距,一般二者相等;x0、y0為主點(diǎn)坐標(biāo)(相對(duì)于成像平面),s為坐標(biāo)軸傾斜參數(shù),理想情況下為0
print("newcameramtx:\n", newcameramtx)
print (("旋轉(zhuǎn)向量rvecs:\n"),rvecs) # 旋轉(zhuǎn)向量 # 外參數(shù),3個(gè)旋轉(zhuǎn)參數(shù)
print (("平移向量tvecs:\n"),tvecs) # 平移向量 # 外參數(shù),3個(gè)平移參數(shù)
print("畸變系數(shù)dist:\n", dist)#5個(gè)畸變參數(shù),徑向畸變k1,k2,k3,切向畸變p1、p2
# 計(jì)算誤差
# 反投影誤差越接近0,說(shuō)明結(jié)果越理想。
# 通過(guò)之前計(jì)算的內(nèi)參數(shù)矩陣、畸變系數(shù)、旋轉(zhuǎn)矩陣和平移向量,使用cv2.projectPoints()計(jì)算三維點(diǎn)到二維圖像的投影,
# 然后計(jì)算反投影得到的點(diǎn)與圖像上檢測(cè)到的點(diǎn)的誤差,最后計(jì)算一個(gè)對(duì)于所有標(biāo)定圖像的平均誤差,這個(gè)值就是反投影誤差。
tot_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
tot_error += error
print("total error: ", tot_error / len(objpoints))
8.實(shí)驗(yàn)結(jié)果及分析
本次實(shí)驗(yàn)采用了兩組數(shù)據(jù),第1組為拍攝角度變化較大的15張,第2組拍攝角度幾乎沒(méi)變的15張。
8.1 實(shí)驗(yàn)結(jié)果
第1組棋盤格照片(角度變化比較大的15張):
? ?實(shí)驗(yàn)結(jié)果:
? ? 角點(diǎn)檢測(cè)結(jié)果:
?
??
?第2組棋盤格照片(拍攝角度幾乎不變的15張):
?實(shí)驗(yàn)結(jié)果:
?
?
? ? ? ? ? ? ??
8.2 結(jié)果分析
? ? (1) 同一相機(jī)用同一組圖片進(jìn)行多次實(shí)驗(yàn)得到的相機(jī)內(nèi)參一致,且畸變系數(shù)保持不變。但是每張圖片的旋轉(zhuǎn)矩陣和平移矩陣不同。
? ? (2) 同一相機(jī)分別對(duì)角度變化比較大的15張圖片和角度幾乎不變的15張圖片進(jìn)行實(shí)驗(yàn)得到的相機(jī)內(nèi)參不一致,是由于相機(jī)標(biāo)定時(shí)采用的是小孔成像模型,但是這個(gè)模型并不是真正的模型,只是一個(gè)近似模型,所以不同距離等效的相機(jī)光心點(diǎn)不一樣,導(dǎo)致在不同距離標(biāo)定的相機(jī)內(nèi)參是不一樣的。另一方面的原因是因?yàn)橄鄼C(jī)標(biāo)定時(shí)標(biāo)定板并不能做到完全在一個(gè)平面上,會(huì)對(duì)實(shí)驗(yàn)結(jié)果產(chǎn)生一定的誤差。
? ? ? (3)? ?標(biāo)定照片的圖片不能太少,會(huì)導(dǎo)致標(biāo)定參數(shù)不準(zhǔn)確。
? ? ? (4)? ?拍攝過(guò)程中如果調(diào)整了焦距會(huì)對(duì)實(shí)驗(yàn)結(jié)果有影響,需要重新標(biāo)定。
? ? (5)拍攝的圖片的清晰度會(huì)影響角點(diǎn)檢測(cè),從而影響實(shí)驗(yàn)結(jié)果。
? ?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-792588.html
? ? ? ?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-792588.html
到了這里,關(guān)于相機(jī)標(biāo)定-張正友棋盤格標(biāo)定法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!