做计算机视觉项目,相机校准是所有高精度项目的第一步。
不管是图像拼接、3D测距、视觉定位、工业检测、AR透视矫正,只要涉及真实物理坐标映射,都必须先做相机标定。
日常拍摄的图片,普遍存在两种畸变:
❌ 径向畸变:画面中心正常、边缘向内/向外弯曲(桶形、枕形畸变)
❌ 切向畸变:镜头组装偏差导致画面倾斜偏移
不校准的相机,所有坐标计算、尺寸检测、透视变换都会存在系统性误差。
OpenCV 工业标定只靠两种核心方案:棋盘格标定、圆形网格标定。
今天彻底讲透两者的原理、区别、优劣、适用场景,附带两套完整可运行标定代码,零基础也能独立完成相机校准!
一、相机校准核心原理(通俗大白话)
相机标定的本质,就是求解相机内参、外参、畸变系数,通过数学模型反向修正畸变画面。
1、核心参数定义
•内参矩阵:相机固有属性(焦距、主点坐标),设备固定不变
•畸变系数:描述镜头畸变程度,矫正画面扭曲的核心参数
•外参矩阵:标定板相对相机的旋转、平移矩阵
2、标定通用逻辑
无论棋盘格还是圆形网格,标定流程完全一致:
拍摄多视角标定板图片→ 提取2D图像特征点 → 匹配3D物理坐标 → 迭代求解相机参数 → 矫正畸变图像
二、两种标定图案详解与优劣对比
1、棋盘格标定(Chessboard)
最经典、最通用、入门首选的标定方案,黑白相间方格网格,依靠方格交点角点作为特征点。
核心优势:
•图案简单、打印成本极低
•角点特征辨识度高、算法稳定
•适配绝大多数普通相机、监控摄像头
•OpenCV原生支持,兼容性拉满
短板:
画面轻微模糊、反光、遮挡时,角点检测容易失效,精度小幅下降。
2、圆形网格标定(CirclesGrid)
分为对称圆形网格和非对称圆形网格,依靠圆点中心坐标作为标定特征点,是高精度工业标定首选。
核心优势:
•圆点中心亚像素精度极高,远超棋盘格角点
•抗模糊、抗反光、抗干扰能力强
•低画质、轻微失焦画面也能精准识别
•工业精密检测、3D视觉项目专用
短板:
图案打印精度要求高,普通打印容易出现圆点变形,影响标定效果。
三、场景选型公式(直接抄作业)
✅ 新手入门、普通监控、日常矫正、快速标定→ 棋盘格标定
✅ 工业精密检测、3D测距、高精度定位、低画质设备→ 圆形网格标定
四、实战1:棋盘格相机标定(完整可运行代码)
最常用入门方案,支持批量读取标定图片、自动提取角点、计算参数、矫正图像,全程自动化。
pythonimport cv2import numpy as npimport glob# 1. 配置棋盘格参数(内角点行列数)w, h = 9, 6# 物理坐标:假设每个方格边长20mmobjp = np.zeros((w*h,3), np.float32)objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2) * 20# 存储3D物理点、2D图像点obj_points = []img_points = []# 读取所有标定图片images = glob.glob("chessboard/*.jpg")for fname in images:img = cv2.imread(fname)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 检测棋盘格内角点ret, corners = cv2.findChessboardCorners(gray, (w,h), None)if ret:obj_points.append(objp)# 亚像素精确化,提升精度criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)corners2 = cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)img_points.append(corners2)# 绘制角点可视化cv2.drawChessboardCorners(img, (w,h), corners2, ret)cv2.imshow("chessboard", img)cv2.waitKey(200)cv2.destroyAllWindows()# 2. 相机标定,求解内参、畸变系数ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)print("相机内参矩阵:")print(mtx)print("畸变系数:")print(dist)# 3. 畸变矫正img = cv2.imread("test.jpg")h, w = img.shape[:2]new_mtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))dst = cv2.undistort(img, mtx, dist, None, new_mtx)# 裁剪有效区域x,y,w,h = roidst = dst[y:y+h, x:x+w]cv2.imwrite("undistort_result.jpg", dst)cv2.imshow("origin", img)cv2.imshow("undistort", dst)cv2.waitKey(0)cv2.destroyAllWindows() |
五、实战2:圆形网格高精度标定(工业级代码)
采用非对称圆形网格标定,抗干扰更强、精度更高,适配工业精密场景,核心函数findCirclesGrid。
pythonimport cv2import numpy as npimport glob# 1. 圆形网格参数:11行4列非对称圆点w, h = 11, 4objp = np.zeros((w*h,3), np.float32)objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2) * 15obj_points = []img_points = []images = glob.glob("circles/*.jpg")for fname in images:img = cv2.imread(fname)gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 非对称圆形网格检测,高精度标定ret, corners = cv2.findCirclesGrid(gray, (w,h), flags=cv2.CALIB_CB_ASYMMETRIC_GRID)if ret:obj_points.append(objp)# 亚像素优化criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)corners2 = cv2.cornerSubPix(gray, corners, (5,5), (-1,-1), criteria)img_points.append(corners2)cv2.drawChessboardCorners(img, (w,h), corners2, ret)cv2.imshow("circles_grid", img)cv2.waitKey(200)cv2.destroyAllWindows()# 2. 标定求解参数ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, gray.shape[::-1], None, None)print("高精度标定-内参矩阵:")print(mtx)print("高精度标定-畸变系数:")print(dist)# 3. 畸变矫正img = cv2.imread("test.jpg")h, w = img.shape[:2]new_mtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))dst = cv2.undistort(img, mtx, dist, None, new_mtx)x,y,w,h = roidst = dst[y:y+h, x:x+w]cv2.imwrite("circles_undistort.jpg", dst)cv2.imshow("origin", img)cv2.imshow("circles_undistort", dst)cv2.waitKey(0)cv2.destroyAllWindows() |

六、核心函数参数详解(必记)
•cv2.findChessboardCorners():提取棋盘格内角点,参数为网格行列数
•cv2.findCirclesGrid():提取圆形网格中心点,非对称网格需开启对应flag
•cv2.cornerSubPix():亚像素精度优化,大幅提升标定精准度
•cv2.calibrateCamera():核心标定函数,输出内参、畸变、外参矩阵
•cv2.undistort():图像畸变矫正,输出无畸变图像
七、双算法优缺点终极总结
棋盘格标定
✅ 优点:素材易得、检测稳定、计算快速、新手友好、通用性强
❌ 缺点:模糊、反光场景精度下降,极限精度不如圆形网格
圆形网格标定
✅ 优点:亚像素高精度、抗干扰强、低画质适配好、工业级精度
❌ 缺点:对打印素材精度要求高、参数配置稍复杂
八、实操高频避坑指南(新手必看)
•坑1:标定图片数量过少至少采集15-25张不同角度、不同距离的标定图,数量不足参数误差极大
•坑2:网格行列数填反填写内角点数量,不是方格数量,填反直接检测失败
•坑3:忽略亚像素优化不做subPix优化,标定精度会损失30%以上
•坑4:素材反光、模糊、倾斜过度拍摄时保证光线均匀、无反光、图案完整露出
•坑5:混用标定参数每台相机参数唯一,不可直接套用他人标定数据,必须单独标定
九、全文总结
相机标定是传统CV高精度项目的地基,地基不稳,后续所有检测、定位、测距都会出错。
最后给大家终极选型结论:
日常学习、普通项目、快速矫正→ 棋盘格标定
工业检测、精密测量、3D视觉、高精度需求 → 圆形网格标定
掌握这两种标定方式,足以搞定99%的OpenCV相机畸变矫正与参数标定场景!
❤️ 点赞+在看,后台回复关键词【相机标定】,领取双版本优化工程代码+标定板高清素材+参数调优手册!
关注【AI与计算机视觉】,持续更新OpenCV从入门到工业落地全套实战教程!
评论区打卡:相机校准,一起深耕机器视觉基础!