opencv标定程序

一. 标定原理

摄像机在成像的过程中会在边缘产生显著的畸变,对于普通的摄像机拍摄的图像,会产生径向畸变,切向畸变和其他类型的畸变,我们需要对图像进行矫正处理。使用opencv标定图像的过程,先根据一个标定物体计算旋转矩阵和平移向量,寻找标定物的角点cvFindchessboardCorners;再精确角点的位置(也叫亚像素角点)cvfindCornerSubPix;绘制出所有的标定物角点cvDrawChessboardCorners ;使用标定函数计算摄像机的内参数矩阵和畸变系数,旋转变量和平移变量 cvCalibrateCamera2;根据内参数矩阵和畸变系数求出畸变映射cvInitUndistortMap ,再使用重映射转换图片 cvRemap ,也可以使用cvUndistort2完成所有的事项。


二. 函数简介

1. cvFindchessboardCorners                 寻找棋盘上的角点位置
2. cvfindCornerSubPix                      精确角点位置
3. cvDrawChessboardCorners                 绘制检测到的棋盘角点
4. cvCalibrateCamera2                      利用定标来计算摄像机的内参数和外参数 
5. cvfindExtrinsicCameraParam2             只计算外参数
6. cvRodrigues2                           进行旋转矩阵和旋转向量间的转换 
7. cvUndistort2                            校正图像因相机镜头引起的变形
8. cvInitUndistortMap                      计算畸变映射
9. cvRemap                                 重映射

<寻找棋盘上的角点位置>

函数cvFindChessboardCorners试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到切它们都被以一定顺序排布(一行一行地,每行从左到右),函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互联通地位置。这个函数检测到地坐标只是一个大约地值,如果要精确地确定它们的位置,可以使用函数cvFindCornerSubPix。

int cvFindChessboardCorners(const void* image, CvSize patternSize, CvPoint2D32f* corners, int* cornerCount=NULL, int flags=CV_CALIB_CB_ADAPTIVE_THRESH )
  • image 输入的棋盘图,必须是8位的灰度或者彩色图像。
  • pattern_size 棋盘图中每行和每列角点的个数。
  • corners 检测到的角点
  • corner_count 输出,角点的个数。如果不是NULL,函数将检测到的角点的个数存储于此变量。
  • flags 各种操作标志,可以是0或者下面值的组合:
    CV_CALIB_CB_ADAPTIVE_THRESH - 使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
    CV_CALIB_CB_NORMALIZE_IMAGE - 在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
    CV_CALIB_CB_FILTER_QUADS - 使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

<精确角点位置>

函数 cvFindCornerSubPix 通过迭代来发现具有子象素精度的角点位置

void cvFindCornerSubPix(const CvArr* image, CvPoint2D32f* corners, int count, CvSize winSize, CvSize zeroZone, CvTermCriteria criteria)                   
  • 第一个参数 image 输入图像.
  • 第二个参数 corners 输入角点的初始坐标,也存储精确的输出坐标
  • 第三个参数 count 角点数目
  • 第四个参数 win 搜索窗口的一半尺寸。如果 win=(5,5) 那么使用 5*2+1 × 5*2+1 = 11 × 11 大小的搜索窗口
  • 第五个参数 zero_zone 死区的一半尺寸,死区为不对搜索区的中央位置做求和运算的区域。它是用来避免自相关矩阵出现的某些可能的奇异性。当值为 (-1,-1) 表示没有死区。
  • 第六个参数 criteria 求角点的迭代过程的终止条件。即角点位置的确定,要么迭代数大于某个设定值,或者是精确度达到某个设定值。 criteria 可以是最大迭代数目,或者是设定的精确度,也可以是它们的组合。

<绘制检测到的棋盘角点>

函数cvDrawChessboardCorners以红色圆圈绘制检测到的棋盘角点;如果整个棋盘都检测到,则用直线连接所有的角点。

void cvDrawChessboardCorners(CvArr* image, CvSize patternSize, CvPoint2D32f* corners, int count, int patternWasFound)
  • 第一个参数 image 结果图像,必须是8位彩色图像。
  • 第二个参数 pattern_size 每行和每列地内角点数目。
  • 第三个参数 corners 检测到地角点数组。
  • 第四个参数 count 角点数目。
  • 第五个参数 pattern_was_found 指示完整地棋盘被发现(≠0)还是没有发现(=0)。可以传输cvFindChessboardCorners函数的返回值。

<利用定标来计算摄像机的内参数和外参数 >

函数cvCalibrateCamera2从每个视图中估计相机的内参数和外参数。

double cvCalibrateCamera2(const CvMat* objectPoints, const CvMat* imagePoints, const CvMat* pointCounts, CvSize imageSize, CvMat* cameraMatrix, CvMat* distCoeffs, CvMat* rvecs=NULL, CvMat* tvecs=NULL, int flags=0 )                  
  • 第一个参数 object_points 定标点的世界坐标,为3xN或者Nx3的矩阵,这里N是所有视图中点的总数。
  • 第二个参数 image_points 定标点的图像坐标,为2xN或者Nx2的矩阵,这里N是所有视图中点的总数。
  • 第三个参数 point_counts 向量,指定不同视图里点的数目,1xM或者Mx1向量,M是视图数目。
  • 第四个参数 image_size 图像大小,只用在初始化内参数时。
  • 第五个参数 intrinsic_matrix 输出内参矩阵(A)
    fx000fy0cx
下面是一个使用OpenCV进行标定标定的简单程序示例: ```python import numpy as np import cv2 # 准备标定板参数 board_size = (9, 6) # 标定板内角点数目 square_size = 25.0 # 每个方格的物理尺寸(毫米) # 准备标定板角点的真实世界坐标 objp = np.zeros((board_size[0] * board_size[1], 3), np.float32) objp[:, :2] = np.mgrid[0:board_size[0], 0:board_size[1]].T.reshape(-1, 2) * square_size # 存储所有图像的角点和物理坐标 obj_points = [] # 真实世界坐标 img_points = [] # 图像坐标 # 检测和提取角点 cap = cv2.VideoCapture(0) # 打开相机 while True: ret, frame = cap.read() # 读取相机图像 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 转换为灰度图像 ret, corners = cv2.findChessboardCorners(gray, board_size, None) # 检测角点 if ret: obj_points.append(objp) img_points.append(corners) cv2.drawChessboardCorners(frame, board_size, corners, ret) cv2.imshow('Chessboard', frame) if cv2.waitKey(1) == ord('q'): # 按下 'q' 键退出循环 break cap.release() cv2.destroyAllWindows() # 相机标定 ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera( obj_points, img_points, gray.shape[::-1], None, None ) # 打印相机内参矩阵和畸变系数 print("相机内参矩阵:") print(camera_matrix) print("\n畸变系数:") print(dist_coeffs) ``` 这个程序首先准备了标定板的参数,包括内角点数目和每个方格的物理尺寸。然后通过相机拍摄一系列包含标定板的图像,并检测提取图像中的角点。最后,使用`calibrateCamera`函数进行相机标定,并打印出相机的内参矩阵和畸变系数。 请注意,在运行程序之前,确保你的计算机连接了摄像头,并且已经安装了OpenCV库。希望这个示例能帮助到你!如果你还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值