OpenCV-Python相機標定——張正友標定法為例(待更新)
- 寫在前面
- 數學/物理原理(待更新)
- 編程實作
- 參考與致謝
寫在前面
- 為什么機器視覺要用相機標定:直接目的是求出相機的內、外引數,以及畸變引數
- 那么這些引數有何用呢:通過相機標定可以矯正這種鏡頭畸變,生成矯正后的影像;另一個目的是根據獲得的影像重構三維場景,
- 怎么獲得這些引數:輸入為各種角度的標定板影像、各個標定板影像的角點位置,通過呼叫
Opencv-python中的各種方法 - 標定并矯正之后,真的有作用嗎:
- 不進行標定有什么影響:其標定結果的精度及演算法的穩定性直接影響相機作業產生結果的準確性,
數學/物理原理(待更新)
- 坐標系
- 世界坐標系
- 相機坐標系
- 標定板坐標系
- 引數
- 由于設計工藝照成的影響是無法改變的事實,所以這將是相機的內參;
- 由環境或安裝方式照成的影響是可以改變的,這就是相機的外參
編程實作
- 使用的工具/材料:python3、opencv-python庫、10-20張各種角度的棋盤標定板影像
- API函式
cv2.findChessboardCorners(),尋找角點
第一個引數Image,傳入拍攝的棋盤圖Mat影像,必須是8位的灰度或者彩色影像;
第二個引數patternSize,每個棋盤圖上內角點的行列數,一般情況下,行列數不要相同,便于后續標定程式識別標定板的方向;
第三個引數corners,用于存盤檢測到的內角點影像坐標位置,一般是陣列形式;
第四個引數flage:用于定義棋盤圖上內角點查找的不同處理方式,有默認值,cv2.cornerSubPix(),尋找亞像素角點
第一個引數image,輸入影像的像素矩陣,最好是8位灰度影像,檢測效率更高;
第二個引數corners,初始的角點坐標向量,同時作為亞像素坐標位置的輸出,所以需要是浮點型資料;
第三個引數winSize,大小為搜索視窗的一半;
第四個引數zeroZone,死區的一半尺寸,死區為不對搜索區的中央位置做求和運算的區域,它是用來避免自相關矩陣出現某些可能的奇異性,當值為(-1,-1)時表示沒有死區;
第五個引數criteria,定義求角點的迭代程序的終止條件,可以為迭代次數和角點精度兩者的組合;cv2.drawChessboardCorners(),畫角點
第一個引數image,8位灰度或者彩色影像;
第二個引數patternSize,每張標定棋盤上內角點的行列數;
第三個引數corners,初始的角點坐標向量,同時作為亞像素坐標位置的輸出,所以需要是浮點型資料;
第四個引數patternWasFound,標志位,用來指示定義的棋盤內角點是否被完整的探測到,true表示別完整的探測到,函式會用直線依次連接所有的內角點,作為一個整體,false表示有未被探測到的內角點,這時候函式會以(紅色)圓圈標記處檢測到的內角點;cv2.calibrateCamera(),標定相機
第一個引數objectPoints,為世界坐標系中的三維點,需要依據棋盤上單個黑白矩陣的大小,計算出(初始化)每一個內角點的世界坐標;
第二個引數imagePoints,為每一個內角點對應的影像坐標點;
第三個引數imageSize,為影像的像素尺寸大小,在計算相機的內參和畸變矩陣時需要使用到該引數;
第四個引數cameraMatrix為相機的內參矩陣;
第五個引數distCoeffs為畸變矩陣;
第六個引數rvecs為旋轉向量;
第七個引數tvecs為位移向量;
第八個引數flags為標定時所采用的演算法,有如下幾個引數:
第九個引數criteria是最優迭代終止條件設定,cv2.undistort(),矯正
第一個引數src,輸入引數,代表畸變的原始影像;
第二個引數cameraMatrix,為之前求得的相機的內參矩陣;
第三個引數distCoeffs,為之前求得的相機畸變矩陣;
第四個引數dst,矯正后的輸出影像,跟輸入影像具有相同的型別和大小;
第五個引數newCameraMatrix,默認跟cameraMatrix保持一致; - 實作實體:注意棋盤影像路徑,并且注意棋盤角點不同需要修改引數,否則會
assertion error
# 相機標定
import cv2
import numpy as np
import glob
# 設定尋找亞像素角點的引數,采用的停止準則是最大回圈次數1和最大誤差容限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)
# 遍歷每一幅棋盤格板,獲取其對應的內角點數目,即 nx * ny,
# 用陣列的形式來保存每一幅棋盤格板中所有內角點的三維坐標,
# 將世界坐標系建在標定板上,所有點的Z坐標全部為0,所以只需要賦值x和y
# print(objp),部分輸出如下:
# [[0. 0. 0.]
# [1. 0. 0.]
# [2. 0. 0.]
# [3. 0. 0.]
# [4. 0. 0.]
# [5. 0. 0.]
# [6. 0. 0.]
# [7. 0. 0.]
# [8. 0. 0.]
# [0. 1. 0.]
# [1. 1. 0.]
# [2. 1. 0.]
# ...
obj_points = [] # 存盤3D點
img_points = [] # 存盤2D點
images = glob.glob("../images/*.jpg")
i = 0
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 將BGR圖轉化為灰度值圖
size = gray.shape[::-1]
ret, corners = cv2.findChessboardCorners(gray, (9, 6), None) # 提取角點,這里的角點專指的是標定板上的內角點,這些角點與標定板的邊緣不接觸,
# print(corners)
# 提取角點成功
if ret:
obj_points.append(objp)
corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria) # 在原角點的基礎上尋找亞像素角點,提升角點的精細度
# print(corners2)
if corners2.any():
img_points.append(corners2)
else:
img_points.append(corners)
cv2.drawChessboardCorners(img, (9, 6), corners, ret) # 繪制角點,記住,OpenCV的繪制函式一般無回傳值
i += 1
cv2.imwrite('conimg' + str(i) + '.jpg', img)
# cv2.waitKey(10)
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("-----------------------------------------------------")
img = cv2.imread(images[2])
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h)) # 顯示更大范圍的圖片(正常重映射之后會刪掉一部分影像)
print(newcameramtx)
print("------------------使用undistort函式-------------------")
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
x, y, w, h = roi
dst1 = dst[y:y + h, x:x + w]
cv2.imwrite('calibresult3.jpg', dst1)
print("方法一:dst的大小為:", dst1.shape)
- 矯正(undistortion)和校正(rectification)不等價,矯正在數學上強調去掉透鏡畸變,而校正是數學上將影像排列整齊
參考與致謝
本文參考了以下博客,在此表示我最真摯的謝意!
- 相機標定(Camera calibration) from csdn-無比機智的永哥
- 相機標定(Camera calibration)原理、步驟 from csdn-Seehidre
- 張正友相機標定Opencv實作以及標定流程&&標定結果評價&&影像矯正流程決議(附標定程式和棋盤圖)csdn- -牧野-
- OpenCV學習筆記(二十一)——相機的標定
-csdn-行歌er
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/290763.html
標籤:其他
上一篇:計算機視覺中的注意力機制理解
下一篇:訊飛小車比賽語音控制(基礎)
