无人驾驶学习---第二课

本文讲解了无人驾驶中的相机标定过程,包括相机失真的两种类型——径向畸变和切向畸变,以及如何通过计算畸变系数进行畸变消除。介绍了相机标定所需的数据和流程,包括使用棋盘格图像获取物体点与图片点,以及如何利用这些数据求解相机的内在和外在参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无人驾驶学习—第二课

(本课程内容来自优达学城无人驾驶纳米学位)
相机标定
相机失真表现为两种:
1、径向畸变:
由相机镜头边缘造成。表现为直线变弯且距离图片中心越远,影响越大,如下图所示。
在这里插入图片描述
2、切向畸变:
由相机镜头没有与被拍摄物体平行造成。表现为图片没有正对拍摄者,如下图所示。
在这里插入图片描述
畸变消除方法:
校正径向畸变使用校正公式需要三个系数:k1、k2和k3。 (x,y)是扭曲图像的一个点,为了使这些点不失真,OpenCV需要计算r,r是未失真图像对应点(x_corrected, y_corrected)和图像中心点(x_c, y_c)的距离。该中心点(x_c, y_c)有时也被称为畸变中心。
在这里插入图片描述
校正切向畸变使用校正公式需要两个系数:p1和p2。
在这里插入图片描述
总的来说,我们总共需要知道5个参数,也就是畸变系数:
在这里插入图片描述
除此之外,我们还需要知道一些其他信息,比如相机的内在和外部参数。内在参数是由相机内部决定的,它取决于特定的相机,包括焦距(fx,fy),光心(cx,cy)等。称作为相机矩阵,它取决于相机本身,因此只需要计算一次。
在这里插入图片描述
外部参数对应于旋转和平移向量,它将三维点的坐标转换为坐标系统。
准备:
对于三维应用程序,上面这些畸变系数需要先被计算。要找到所有这些参数,我们需要一些定义好的模式的示例图像(如棋盘格,棋盘格非常适合校准,因为它具有规则的高对比度图案,使得自动检测变得非常容易)。我们找到模式中特定的点(格子的交点),这样我们知道这些点在真实世界中的坐标,也知道它们在图片中的坐标。有了这些数据,就可以通过解决一些数学问题,从而得到畸变系数,这就是解决整个问题的思路。
为了得到更好的结果,我们需要20-30张测试模式图片。
在这里插入图片描述
物体点与图片点获取:
相机标定需要的数据是一系列3D世界的点和它相对的2D图片上的点。
2D图片上的点获取:
从图片上计算它们的位置(这些图像点是两个黑色块相接触的地方)。

3D世界的点获取:
这些图像是静态的摄像机拍摄放置在不同的位置和方向的棋盘格得到的,我们假设图片放在XY平面上(因此Z值总是等于0),同时相机相对移动,只需要找出X,Y的值。
3D点称作物体点(objpoints),2D点称作图片点(imgpoints)。

找到角点:
为了找到棋盘格的样式,我们使用cv2.findChessboardCorners()函数找到棋盘格上的角点,使用cv2.drawChessboardCorners()将角点标注出来。
在本例中,我们使用7*6的棋盘格,它返回每一个角点,如果匹配到了模式,它将返回是True,这些角点将按一定顺序标注出来(从左到右,从上到下)。
测试图:
在这里插入图片描述
代码:

import matplotlib.pyplot as plt
import cv2

# prepare object points
nx = 9
ny = 6

# Make a list of calibration images
fname = 'test.jpg'
img = cv2.imread(fname)

# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Find the chessboard corners
ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)

# If found, draw corners
if ret == True:
    # Draw and display the corners
    cv2.drawChessboardCorners(img, (nx, ny), corners, ret)
    plt.imshow(img)
    plt.show()

标记了的角点图:
在这里插入图片描述
标定
上面我们有了物体点坐标和图片点坐标,就可以开始标定相机了。我们使用cv2.calibrateCamera()求解相机的内在参数和外在参数,返回相机矩阵、畸变系数、旋转和平移向量等。
代码:

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img.shape[1:], None, None)

dist:畸变矩阵
mtx:内参数矩阵
rvecs, tvecs:旋转和平移向量

消除畸变
我们已经得到了所有数据,现在我们可以拿一张图片来消除它的畸变。

import pickle
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

# Read in the saved objpoints and imgpoints
dist_pickle = pickle.load( open( "wide_dist_pickle.p", "rb" ) )
objpoints = dist_pickle["objpoints"]
imgpoints = dist_pickle["imgpoints"]

# Read image
img = cv2.imread('test_image.png')

def cal_undistort(img, objpoints, imgpoints):
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img.shape[1:], None, None)
    undist = cv2.undistort(img, mtx, dist, None, mtx)
    return undist

undistorted = cal_undistort(img, objpoints, imgpoints)

f,(ax1,ax2) = plt.subplots(1, 2, figsize=(24, 9))
f.tight_layout()
ax1.imshow(img)
ax1.set_title('Original Image', fontsize=50)
ax2.imshow(undistorted)
ax2.set_title('Undistorted Image', fontsize=50)
plt.subplots_adjust(left=0., right=1, top=0.9, bottom=0.)

测试图:
在这里插入图片描述
校准图:
在这里插入图片描述
这里好像有点问题。。。。似乎线条是看起来直了,但倾斜程度更歪了。没有使用自己去创建队列保存物体点与图像点,直接使用了优达学城提供的这两个点集合。但是思路是没有错误的,仅供参考吧,后续有时间再修改。
第二课较简单,只进行了相机的校准工作,后续继续加油,本博客内容不得转载,不得作为他用,仅互相学习,谢谢。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值