Opencv-python
中的各种方法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)
本文参考了以下博客,在此表示我最真挚的谢意!
- 相机标定(Camera calibration) from csdn-无比机智的永哥
- 相机标定(Camera calibration)原理、步骤 from csdn-Seehidre
- 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)csdn- -牧野-
- OpenCV学习笔记(二十一)——相机的标定
-csdn-行歌er