网易首页 > 网易号 > 正文 申请入驻

无人自动驾驶技术之使用OpenCV进行相机校准

0
分享至

照相机与摄像头,是机器人,人工智能,计算机视觉,工业自动化甚至娱乐行业等多个领域的组成部分。在我们使用此设备时,不仅要了解照相原理外,需要使用特殊的技术对摄像头进行相机校准,特别在自动化驾驶上,需要实时的对照相机进行校准操作

我们需要确定真实世界中3D点与其在该校准相机捕获的图像中其对应2D投影(像素)之间的精确关系所需的有关相机的所有信息(参数或系数)。

1、相机/镜头系统的内部参数。例如镜头的焦距,光学中心和径向畸变系数。

2、外部参数:这是指摄像机相对于某些世界坐标系的方向(旋转和平移)。

使用OpenCV进行相机校准

要了解校准过程,我们首先需要了解照相成像的几何原理。

为了轻松理解问题,我们假设在一个房间内部署了一个摄像头。

给定这个房间中的3D点P,我们想在相机拍摄的图像中找到该3D点的像素坐标(u,v)。

1.世界坐标系

世界坐标系和摄影机坐标系通过旋转和平移关联。

这六个参数(3个用于旋转,3个用于平移)称为相机的外部参数。

要定义房间中点的位置,我们首先需要为此房间定义一个坐标系。

原点:我们可以任意固定房间的一角作为原点

X,Y,Z轴:我们还可以沿着地板的两个维度定义房间的X和Y轴,并沿着垂直墙定义Z轴。

2.相机坐标系3.图像坐标系

显示了点P在图像平面上的投影。

通过对点的世界坐标进行旋转和平移,在相机的3D坐标系中获得点后,便可以将点投影到图像平面上,从而获得该点在图像中的位置。

当图像像素坐标系的原点位于左上角时,显示了一个更现实的场景。

固有相机矩阵需要考虑主要点的位置,轴的偏斜以及沿不同轴的潜在不同焦距。

将世界坐标系中的3D点投影到相机像素坐标的过程分为三个步骤。

  • 1、使用外部矩阵将3D点从世界坐标转换为摄像机坐标,该矩阵由两个坐标系之间的旋转和平移组成。

  • 2.摄像机坐标系中的新3D点使用内部矩阵投影到图像平面上,该矩阵由内部摄像机参数组成,例如焦距,光学中心等。

  • 3.要找到3D点在图像平面上的投影,我们首先需要使用外部参数(旋转)将点从世界坐标系转换为相机坐标系。

总之,相机校准算法具有以下输入和输出

输入:具有点的图像集合,这些点的2D图像坐标和3D世界坐标是已知的。

输出:3×3摄像机固有矩阵,每个图像的旋转和平移。

注意:在OpenCV中,相机固有矩阵没有偏斜参数。所以矩阵的形式是

通过以上的基础知识,我们开始我们的代码操作

步骤1:使用棋盘格图案定义现实世界的坐标

为什么在校准中广泛使用棋盘格图案?

棋盘图案独特且易于在图像中检测。不仅如此,棋盘上正方形的角对于它们的局部定位也是理想的,因为它们在两个方向上都有明显的渐变。此外,这些角还因为它们位于棋盘格线的交点而相关。所有这些事实均用于以棋盘格图案牢固地定位正方形的角。

第2步:从不同的角度捕获棋盘格的多个图像

接下来,我们保持棋盘格静止,并通过移动相机来拍摄棋盘格的多个图像。

或者,我们也可以保持相机恒定不变,并以不同的方向拍摄棋盘格图案。

步骤3:查找棋盘的二维坐标

现在,我们有多个棋盘图像。我们还知道世界坐标下棋盘上点的3D位置。我们需要的最后一件事是图像中这些棋盘格角的2D像素位置。

3.1查找棋盘角

OpenCV提供了一个内置函数findChessboardCorners ,该函数查找棋盘并返回角的坐标。

主要参数如下:

int cvFindChessboardCorners( const void* image, CvSize pattern_size,
CvPoint2D32f* corners, int* corner_count = 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 - 使用其他的准则(如轮廓面积,周长,方形形状)
来去除在轮廓检测阶段检测到的错误方块。
函数根据是否检测到图案,输出为真还是假。

3.2优化棋盘格角

良好的校准与精度有关。为了获得良好的结果,重要的是获得具有亚像素精度的角的位置。

OpenCV提供cornerSubPix功能,接收原始图像和拐角位置,并在原始位置的一个小邻域内寻找最佳拐角位置。该算法本质上是迭代的,因此我们需要指定终止条件(例如,迭代次数和/或精度)

主要参数如下:


void cv::cornerSubPix(
cv::InputArray image, // 输入图像
cv::InputOutputArray corners, // 角点(既作为输入也作为输出)
cv::Size winSize, // 区域大小为 NXN; N=(winSize*2+1)
cv::Size zeroZone, // 类似于winSize,但是总具有较小的范围,Size(-1,-1)表示忽略
cv::TermCriteria criteria // 停止优化的标准
参数解析:
第一个参数是输入图像,和cv::goodFeaturesToTrack()中的输入图像是同一个图像。
第二个参数是检测到的角点,即是输入也是输出。
第三个参数是计算亚像素角点时考虑的区域的大小,大小为NXN; N=(winSize*2+1)。
第四个参数作用类似于winSize,但是总是具有较小的范围,通常忽略(即Size(-1, -1))。
第五个参数用于表示计算亚像素时停止迭代的标准,可选的值有cv::TermCriteria::MAX_ITER 、cv::TermCriteria::EPS(可以是两者其一,或两者均选),
前者表示迭代次数达到了最大次数时停止,后者表示角点位置变化的最小值已经达到最小时停止迭代。二者均使用cv::TermCriteria()构造函数进行指定。

步骤4:校准相机

校准的最后一步是将世界坐标中的3D点及其在所有图像中的2D位置传递给OpenCV的calibrateCamera方法。

retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(
objectPoints, imagePoints, imageSize)
第一个参数objectPoints,为世界坐标系中的三维点。
需要依据棋盘上单个黑白矩阵的大小,计算出(初始化)每一个内角点的世界坐标;
第二个参数imagePoints,为每一个内角点对应的图像坐标点;
第三个参数imageSize,为图像的像素尺寸大小
,在计算相机的内参和畸变矩阵时需要使用到该参数;
第四个参数cameraMatrix为相机的内参矩阵;
第五个参数distCoeffs为畸变矩阵;
第六个参数rvecs为旋转向量;
第七个参数tvecs为位移向量;
第八个参数flags为标定时所采用的算法。有如下几个参数:
CV_CALIB_USE_INTRINSIC_GUESS:
使用该参数时,在cameraMatrix矩阵中应该有fx,fy,u0,v0的估计值。否则的话,将初始化(u0,v0)图像的中心点,使用最小二乘估算出fx,fy。
CV_CALIB_FIX_PRINCIPAL_POINT:
在进行优化时会固定光轴点。当CV_CALIB_USE_INTRINSIC_GUESS参数被设置,光轴点将保持在中心或者某个输入的值。
CV_CALIB_FIX_ASPECT_RATIO:
固定fx/fy的比值,只将fy作为可变量,进行优化计算。
当CV_CALIB_USE_INTRINSIC_GUESS没有被设置,fx和fy将会被忽略。只有fx/fy的比值在计算中会被用到。
CV_CALIB_ZERO_TANGENT_DIST:设定切向畸变参数(p1,p2)为零。
CV_CALIB_FIX_K1,…,CV_CALIB_FIX_K6:对应的径向畸变在优化中保持不变。
CV_CALIB_RATIONAL_MODEL:计算k4,k5,k6三个畸变参数。
如果没有设置,则只计算其它5个畸变参数。
第九个参数criteria是最优迭代终止条件设定。

在使用该函数进行标定运算之前,需要对棋盘上每一个内角点的空间坐标系的位置坐标进行初始化,标定的结果是生成相机的内参矩阵cameraMatrix、相机的5个畸变系数distCoeffs,另外每张图像都会生成属于自己的平移向量和旋转向量。

利用求得的相机的内参和外参数据,可以对图像进行畸变的矫正,使用undistort函数实现,其函数原型如下

cv2.undistort()函数
第一个参数src,输入参数,代表畸变的原始图像;
第二个参数cameraMatrix,为之前求得的相机的内参矩阵;
第三个参数distCoeffs,为之前求得的相机畸变矩阵;
第四个参数dst,矫正后的输出图像,跟输入图像具有相同的类型和大小;
第五个参数newCameraMatrix,默认跟cameraMatrix保持一致;
完整代码:

根据以上的步骤,我们使用OpenCV来进行相机的校准操作

import cv2
import numpy as np
import os
import glob
# 定义checkboard的尺寸
CHECKERBOARD = (6,9)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# 保存checkerboard image 的 3D points
objpoints = []
# 保存checkerboard image 的 2D points
imgpoints = []
# 定义世界 坐标系3D points
objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
prev_img_shape = None

代码截图

首先我们定义一下需要校准的初始化参数,包括世界坐标系以及checkboard的参数

# 获取所有图片的地址
images = glob.glob('./images/*.jpg')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# findChessboardCorners函数,该函数查找棋盘并返回角的坐标
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+
cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE)

if ret == True:
objpoints.append(objp)
# 接收原始图像和拐角位置,并在原始位置的一个小邻域内寻找最佳拐角位置
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
img = cv2.drawChessboardCorners(img, CHECKERBOARD, corners2,ret)

cv2.imshow('img',img)
cv2.waitKey(0)

代码截图

然后使用findChessboardCorners函数查找棋盘并返回角的坐标,然后使用cornerSubPix函数在原始位置的一个小邻域内寻找最佳拐角位置

cv2.destroyAllWindows()
h,w = img.shape[:2]
# calibrateCamera相机校准
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
print("Camera matrix : \n")
print(mtx)
print("dist : \n")
print(dist)
print("rvecs : \n")
print(rvecs)
print("tvecs : \n")
print(tvecs)

代码截图

经过以上步骤,便可以使用calibrateCamera函数对相机进行校准了,
我们也可以打印一下相机校准后的所有参数,到这里相机校准已经完成,
我们在校准后,需要对原始图片进行校正,使用到的函数便是undistort函数

# undistort对图像进行畸变的矫正
img = cv2.imread(images[0])
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w,h), 1, (w,h))
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)
mapx,mapy=cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow("undistorted image",dst)
cv2.waitKey(0)

代码截图

以上便是完整的相机校准的所有步骤,利用此步骤,我们可以使用到人工智能的自动化驾驶项目上,特别是一些车道线的检测,后期我们会介绍车道线的检测,哪里都需要相机校准的操作。

校准后的图片如下:

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
委内瑞拉:全国哀悼七天

委内瑞拉:全国哀悼七天

潇湘晨报
2026-01-07 09:51:29
深圳要率先取消中考?

深圳要率先取消中考?

Dr小鱼
2026-01-07 10:11:23
重庆终于全城入冬,接下来一周都是好天气

重庆终于全城入冬,接下来一周都是好天气

上游新闻
2026-01-07 12:50:03
特斯拉,放大招了......

特斯拉,放大招了......

放毒
2026-01-07 15:22:00
紧急道歉反转!雷军又被捅了一刀!

紧急道歉反转!雷军又被捅了一刀!

广告创意
2026-01-06 17:41:33
1951年毛主席接见梁兴初,一开口就喊错军衔,全场死寂,梁兴初直接回了句大实话

1951年毛主席接见梁兴初,一开口就喊错军衔,全场死寂,梁兴初直接回了句大实话

寄史言志
2026-01-06 23:04:16
黄一鸣自曝:王思聪每次约她,车费都给10万,来给5万,回再给5万

黄一鸣自曝:王思聪每次约她,车费都给10万,来给5万,回再给5万

汉史趣闻
2025-06-24 10:07:59
上海美女博主浅柠去世,身体一塌糊涂仍在直播,最后家人忍痛拔管

上海美女博主浅柠去世,身体一塌糊涂仍在直播,最后家人忍痛拔管

林雁飞
2026-01-06 15:16:11
煮熟鸭子飞了:闫学晶儿子角色被换,揭开星二代“好日子”的终结

煮熟鸭子飞了:闫学晶儿子角色被换,揭开星二代“好日子”的终结

TVB的四小花
2026-01-07 12:19:15
明明场上作用相当明显,结果湖人锋线大闸差点都打不了比赛了?

明明场上作用相当明显,结果湖人锋线大闸差点都打不了比赛了?

稻谷与小麦
2026-01-07 19:19:56
涉马杜罗指控出现反转:美司法部不再将“太阳集团”视为真实贩毒组织

涉马杜罗指控出现反转:美司法部不再将“太阳集团”视为真实贩毒组织

红星新闻
2026-01-06 17:28:19
澳洲政府突宣!再见,澳洲移民!

澳洲政府突宣!再见,澳洲移民!

澳洲红领巾
2026-01-07 14:08:14
特朗普政府正在讨论获取格陵兰岛的方案,包括军事选项

特朗普政府正在讨论获取格陵兰岛的方案,包括军事选项

界面新闻
2026-01-07 07:16:24
炸裂!中国拼命搞核聚变,什么信号?

炸裂!中国拼命搞核聚变,什么信号?

智谷趋势
2026-01-07 10:54:04
懂球译站   揭秘阿莫林下课内幕:战术安排屡遭干涉,管理层积怨已久

懂球译站   揭秘阿莫林下课内幕:战术安排屡遭干涉,管理层积怨已久

懂球帝
2026-01-07 18:11:15
太猛了!广州,全国第一!

太猛了!广州,全国第一!

楼市灭霸
2026-01-07 11:01:53
头号内奸锁定,接替马杜罗后立刻邀请美国共治,杀父之仇不报了

头号内奸锁定,接替马杜罗后立刻邀请美国共治,杀父之仇不报了

夜里看海
2026-01-07 17:35:21
婆婆将我20万陪嫁卡拿走,说帮我存,我直接挂失,当晚小叔子上门

婆婆将我20万陪嫁卡拿走,说帮我存,我直接挂失,当晚小叔子上门

船长与船1
2025-12-15 10:03:13
火箭队阵容变动!23岁替补被召回!轰26分7助攻,乌度卡靠他救场

火箭队阵容变动!23岁替补被召回!轰26分7助攻,乌度卡靠他救场

熊哥爱篮球
2026-01-07 19:04:29
那些把胆囊切了的人,后来都怎么样了?

那些把胆囊切了的人,后来都怎么样了?

大象新闻
2026-01-04 22:53:03
2026-01-07 19:40:49
人工智能研究所AI
人工智能研究所AI
python人工智能,大数据,人生苦短,我用python
153文章数 774关注度
往期回顾 全部

科技要闻

精华!黄仁勋CES记者会:揭秘新款大杀器

头条要闻

三亚一游客被司机诱导就餐 点了4道海鲜花1868元

头条要闻

三亚一游客被司机诱导就餐 点了4道海鲜花1868元

体育要闻

卖水果、搬砖的小伙,与哈兰德争英超金靴

娱乐要闻

2026年央视春晚彩排:沈腾确定回归

财经要闻

农大教授科普:无需过度担忧蔬菜农残

汽车要闻

燃油驾趣+智能电感双Buff 试驾全新奥迪Q5L

态度原创

家居
手机
健康
游戏
公开课

家居要闻

宁静不单调 恰到好处的美

手机要闻

雷军解释新一代小米SU7发布前三个月开小订,称和YU7情况不同

这些新疗法,让化疗不再那么痛苦

《DQ7RE》试玩版PS商店4.23分!但中文版乱码已下架

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版