编程语言
首页 > 编程语言> > OpenCV-Python相机标定(待更新)

OpenCV-Python相机标定(待更新)

作者:互联网

OpenCV-Python相机标定——张正友标定法为例(待更新)

写在前面

数学/物理原理(待更新)

编程实现

# 相机标定
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)

参考与致谢

本文参考了以下博客,在此表示我最真挚的谢意!

  1. 相机标定(Camera calibration) from csdn-无比机智的永哥
  2. 相机标定(Camera calibration)原理、步骤 from csdn-Seehidre
  3. 张正友相机标定Opencv实现以及标定流程&&标定结果评价&&图像矫正流程解析(附标定程序和棋盘图)csdn- -牧野-
  4. OpenCV学习笔记(二十一)——相机的标定
    -csdn-行歌er

标签:Python,cv2,标定,角点,相机,OpenCV,参数,print
来源: https://blog.csdn.net/BubbleCodes/article/details/119120979