如何用opencv计算相机内参去畸变
时间: 2025-01-06 07:31:49 浏览: 17
### 使用 OpenCV 进行相机内参计算和去畸变处理
#### 准备工作
为了使用OpenCV进行相机内参数的计算以及矫正畸变,首先需要安装必要的库。这通常涉及到Python环境中的`opencv-python-headless`和其他可能依赖的包[^3]。
```bash
pip install opencv-python-headless numpy
```
#### 获取校准图案图片集
对于相机校准来说,获取一组拍摄有已知几何形状(通常是黑白相间的棋盘格)的照片非常重要。这些照片应该覆盖不同的角度和距离,以便能够全面估计镜头的特性[^1]。
#### 编写并运行校准脚本
下面是一个简单的Python脚本来完成上述任务:
```python
import cv2
import numpy as np
import glob
# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最小误差容限0.001
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# 准备对象点,如(0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
# 存储对象点和图像点的数组
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('calibration_images/*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 寻找棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, (7,6),None)
# 如果找到,则添加对象点、图像点(经过细化)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# 绘制并显示角点
img = cv2.drawChessboardCorners(img, (7,6), corners2,ret)
cv2.imshow('img',img)
cv2.waitKey(500)
cv2.destroyAllWindows()
# 执行相机校准
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
print("相机矩阵:\n",mtx)
print("\n畸变系数:\n",dist)
```
这段代码会读取一系列预先拍好的含有标准棋盘格模式的图片,并尝试从中提取特征点用于后续的校准过程。成功定位到足够的角点之后,调用`cv2.calibrateCamera()`函数来估算相机内部参数(`mtx`)和径向及切向失真系数(`dist`)等信息。
#### 应用校准结果去除畸变
一旦获得了相机模型的信息,就可以应用它们来进行图像变形修正了。这里给出一段示范性的代码片段展示如何去除给定输入帧上的任何存在的光学畸变效果:
```python
h, w = img.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)
```
此部分先通过`getOptimalNewCameraMatrix()`优化新的相机矩阵以减少不必要的黑边区域;接着利用`undistort()`方法依据之前求得的各项参数对原始影像实施反扭曲操作;最后裁剪掉因纠正而产生的多余空白边界,保存最终的结果至文件系统中。
阅读全文