相机标定,内参数与外参数

这篇具有很好参考价值的文章主要介绍了相机标定,内参数与外参数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

相机标定

简介

所谓的相机标定就是将外界世界的坐标信息转化为计算机(自带相机/摄像头)可以理解的“距离”,将世界坐标系转换到相机坐标系。我们可以理解为从一个坐标系转换到另一个坐标系所需要的转换关系就是相机标定。

简单滴说:A=F(B),其中F()就是相机标定要做的工作。 其标定的目的就是为了相机内参、外参、畸变参数。

基本原理

求解Homographic矩阵

相机标定,内参数与外参数
相机标定,内参数与外参数
其中 H是描述Homographic矩阵
H 矩阵可以根据特征点/棋盘格角点的空间坐标,以及其图像坐标用最小二乘法很容易求解。
相机标定,内参数与外参数
Homography 有 8 个自由度,
由r1和r2正交,且r1和r2的模相等,可以得到如下约束:
相机标定,内参数与外参数

计算内参数矩阵

相机标定,内参数与外参数相机标定,内参数与外参数相机标定,内参数与外参数相机标定,内参数与外参数
相机标定,内参数与外参数

计算外参数矩阵

相机标定,内参数与外参数

相机标定步骤:

1、打印一张棋盘格,把它贴在一个平面上,作为标定物。
2、通过调整标定物或摄像机的方向,为标定物拍摄一些不同方向的照片。
3、从照片中提取棋盘格角点。
4、估算理想无畸变的情况下,五个内参和六个外参。
5、应用最小二乘法估算实际存在径向畸变下的畸变系数。
6、极大似然法,优化估计,提升估计精度。

标定过程

准备标定板

OpenCV使用棋盘格板进行标定。为了标定相机,我们需要输入一系列三维点和它们对应的二维图像点。在黑白相间的棋盘格上,二维图像点很容易通过角点检测找到。而对于真实世界中的三维点呢?由于我们采集中,是将相机放在一个地方,而将棋盘格定标板进行移动变换不同的位置,然后对其进行拍摄。所以我们需要知道(X,Y,Z)的值。但是简单来说,我们定义棋盘格所在平面为XY平面,即Z=0。
相机标定,内参数与外参数
相机标定,内参数与外参数

检测棋盘格角点

为了找到棋盘格模板,我们使用openCV中的函数cv2.findChessboardCorners()。我们也需要告诉程序我们使用的模板是什么规格的,例如88的棋盘格或者55棋盘格等,建议使用x方向和y方向个数不相等的棋盘格模板。下面实验中,我们使用的是107的棋盘格,每个方格边长是20mm,即含有96的内部角点。这个函数如果检测到模板,会返回对应的角点,并返回true。当然不一定所有的图像都能找到需要的模板,所以我们可以使用多幅图像进行定标。除了使用棋盘格,我们还可以使用圆点阵,对应的函数为cv2.findCirclesGrid()。
  找到角点后,我们可以使用cv2.cornerSubPix()可以得到更为准确的角点像素坐标。我们也可以使用cv2.drawChessboardCorners()将角点绘制到图像上显示。

ret, corners = cv2.findChessboardCorners(gray1, (9, 6), None)
img = cv2.drawChessboardCorners(gray1, (9,6), corners,ret)
cv2.waitKey(1000)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
corners2 = cv2.cornerSubPix(gray1, corners, (9, 6), (-1, -1), criteria)
objpoints.append(objp)
imgpoints.append(corners2)
img = cv2.drawChessboardCorners(gray1, (9, 6), corners2, ret)

相机标定,内参数与外参数

标定

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

通过上面的步骤,我们得到了用于标定的三维点和与其对应的图像上的二维点对。我们使用cv2.calibrateCamera()进行标定,这个函数会返回标定结果、相机的内参数矩阵、畸变系数、旋转矩阵和平移向量。
第三步我们已经得到了相机内参和畸变系数,在将图像去畸变之前,我们还可以使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数,通过设定自由自由比例因子alpha。当alpha设为0的时候,将会返回一个剪裁过的将去畸变后不想要的像素去掉的内参数和畸变系数;当alpha设为1的时候,将会返回一个包含额外黑色像素点的内参数和畸变系数,并返回一个ROI用于将其剪裁掉。
然后我们就可以使用新得到的内参数矩阵和畸变系数对图像进行去畸变了。有两种方法进行去畸变:

实验结果

只有正面照片时

相机标定,内参数与外参数

内参数矩阵,newcameramtx :

 [[1.39247888e+03 0.00000000e+00 4.21531719e+02]
 [0.00000000e+00 1.39737781e+03 9.65615613e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

归一化焦距

fx= 1392.4788818359375 ,fy= 1397.3778076171875

像主点(光心)的坐标

cx,cy 421.53171941416076 965.6156127999784

dist为畸变系数。dist:

 [[-3.02007106e-01  7.88399855e+00 -2.46474817e-02  1.70686761e-03
  -4.04756976e+01]]

ret:

 1.543195731560363

mtx,

 [[1.39695861e+03 0.00000000e+00 4.21660147e+02]
 [0.00000000e+00 1.39810589e+03 9.66118704e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

revcs,旋转矩阵,

 [[[-0.44309197]
  [ 1.07147812]
  [ 2.54591039]]

 [[-0.84261395]
  [-0.41259128]
  [-0.67023628]]

 [[-0.68681096]
  [ 0.48542523]
  [ 1.39249712]]

 [[-0.46926989]
  [ 0.85300712]
  [ 2.35431065]]

 [[-0.90272359]
  [-0.16052316]
  [-0.06843877]]

 [[-0.53683367]
  [ 0.72170338]
  [ 1.88219057]]

 [[-0.58768252]
  [-0.86576238]
  [-1.78717314]]

 [[-0.11030619]
  [-0.95418799]
  [-2.14221165]]

 [[-0.75441289]
  [-0.58611659]
  [-1.21926087]]]

tvecs,平移矩阵

 (array([[ 4.88345717],
       [ 0.05394641],
       [26.82703677]]), array([[-4.50241296],
       [-2.47457431],
       [24.1376541 ]]), array([[ 1.6678211 ],
       [-6.65197784],
       [21.42807732]]), array([[ 6.1818145 ],
       [-3.33303195],
       [26.24933552]]), array([[-4.74254289],
       [-2.1579989 ],
       [25.51213894]]), array([[ 4.19599853],
       [-6.14602571],
       [24.7580413 ]]), array([[-1.69668164],
       [-0.61900485],
       [18.5261494 ]]), array([[ 1.12094953],
       [ 3.90569145],
       [16.84087091]]), array([[-2.72197755],
       [-2.52729824],
       [20.64903984]]))

total error为总体误差:

  0.20800721454025364

```python

只有侧面的照片时

相机标定,内参数与外参数


```python
 [[1.82535645e+03 0.00000000e+00 4.18737546e+02]
 [0.00000000e+00 3.35064893e+03 8.69153073e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

归一化焦距

fx= 1825.3564453125 ,fy= 3350.64892578125

像主点(光心)的坐标`

cx,cy 418.73754642918357 869.153072791858`

dist为畸变系数。dist:

 [[-1.40512508e+00  5.11022470e+01 -7.72332110e-02 -4.38502255e-02
  -2.59448179e+02]]

ret:

 3.5459118388096216

mtx,相机内参:

 [[1.81551877e+03 0.00000000e+00 4.41070962e+02]
 [0.00000000e+00 3.27082753e+03 9.49563451e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

revcs,旋转矩阵,

 [[[-0.80727033]
  [-1.01171386]
  [-1.38129347]]

 [[-0.75218536]
  [ 1.14355184]
  [ 1.84500315]]

 [[-0.52719775]
  [ 1.45639709]
  [ 2.29389315]]

 [[-0.63501651]
  [-1.21903686]
  [-1.67978362]]

 [[-1.09993196]
  [-0.21990954]
  [-0.11986996]]]

tvecs,平移矩阵

 (array([[-2.89017706],
       [ 0.98237799],
       [21.24180682]]), array([[ 4.81100307],
       [-3.58585171],
       [26.84381837]]), array([[ 4.79268410e+00],
       [-5.12204200e-03],
       [ 2.77421342e+01]]), array([[-0.75778873],
       [ 1.25678028],
       [22.1323928 ]]), array([[-4.34387342],
       [-0.49682161],
       [25.88038286]]))

total error为总体误差:

`0.4767580123269295`

正面和侧面都有时

内参数矩阵,newcameramtx :

 [[1.47756372e+03 0.00000000e+00 3.84641645e+02]
 [0.00000000e+00 1.47626343e+03 8.22453102e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

归一化焦距

`fx= 1477.563720703125 ,fy= 1476.263427734375`

像主点(光心)的坐标

cx,cy 384.6416450763427 822.4531022500742

dist为畸变系数。dist:

 [[-9.26352628e-01  2.87704635e+01 -6.32812203e-02 -1.19180863e-02
  -2.38869326e+02]]

ret:

 2.153142220889635

mtx,

 [[1.50446561e+03 0.00000000e+00 3.76968572e+02]
 [0.00000000e+00 1.71088936e+03 9.53167429e+02]
 [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

revcs,旋转矩阵,

 [[[-0.40954189]
  [ 1.23275464]
  [ 2.499671  ]]

 [[-0.57533214]
  [-0.83954196]
  [-1.41737043]]

 [[-0.95020771]
  [-0.41739403]
  [-0.64296516]]

 [[-0.76361682]
  [ 0.60652417]
  [ 1.37935282]]

 [[-0.53011171]
  [ 1.12347077]
  [ 2.48832118]]

 [[-0.4729612 ]
  [ 1.03220648]
  [ 2.31536491]]

 [[-1.00259535]
  [-0.12403123]
  [-0.05485035]]

 [[-0.58901605]
  [ 0.86765807]
  [ 1.85667864]]

 [[-0.67763739]
  [-0.94516277]
  [-1.73384762]]

 [[-0.23942408]
  [-1.05697544]
  [-2.09534043]]]

tvecs,平移矩阵

(array([[ 5.75125712],
       [ 0.30145146],
       [28.50095635]]), array([[-2.11435859],
       [ 1.47584997],
       [17.05490001]]), array([[-3.72925642],
       [-1.98627606],
       [26.15021609]]), array([[ 2.35337777],
       [-5.64738809],
       [23.16349946]]), array([[ 5.69328695],
       [-0.04058948],
       [22.8784759 ]]), array([[ 7.02740175],
       [-2.64972244],
       [27.99528916]]), array([[-3.93080855],
       [-1.686195  ],
       [27.55035256]]), array([[ 4.99191567],
       [-5.15586085],
       [26.61341699]]), array([[-1.10128061],
       [-0.39738934],
       [19.96949129]]), array([[ 1.68065367],
       [ 3.62482022],
       [17.86602482]]))

total error为总体误差:

0.27106081554424943

只有正面照片时误差 0.20800721454025364
正面侧面都有时误差0.27106081554424943
只有侧面时误差0.4767580123269295
由于正面拍时旋转角度较小所以最后的误差也相对较小文章来源地址https://www.toymoban.com/news/detail-485248.html

程序代码

import cv2
import glob
import numpy as np
from ipython_genutils.py3compat import xrange
import matplotlib.pyplot as plt
from pylab import *

# from work1.Harris import plot_harris_points
# from work1.refine_all_param import refinall_all_param

cbraw = 9  # 有6行角点
cbcol = 6  # 有4列角点

objp = np.zeros((cbraw * cbcol, 3), np.float32)
objp[:, :2] = np.mgrid[0:cbraw, 0:cbcol].T.reshape(-1, 2)

objpoints = []  # 3d point in real world space
imgpoints = []  # 2d points in image plane.

# glob是个文件名管理工具
images = glob.glob(r"./image/zm/*.jpg")
print("images",images)
for fname in images:
	# 对每张图片,识别出角点,记录世界物体坐标和图像坐标
	img = cv2.imread(fname)  # source image
	# 我用的图片太大,缩小了一半
	# img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
	gray1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转灰度


	# 寻找角点,存入corners,ret是找到角点的flag
	ret, corners = cv2.findChessboardCorners(gray1, (9, 6), None)
	img = cv2.drawChessboardCorners(gray1, (9,6), corners,ret)
	cv2.waitKey(1000)
	# criteria:角点精准化迭代过程的终止条件
	criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
	# 执行亚像素级角点检测
	corners2 = cv2.cornerSubPix(gray1, corners, (9, 6), (-1, -1), criteria)
	objpoints.append(objp)
	imgpoints.append(corners2)
	# 在棋盘上绘制角点,只是可视化工具
	img = cv2.drawChessboardCorners(gray1, (9, 6), corners2, ret)
	cv2.imshow('img', img)
# cv2.waitKey(1000)

'''
传入所有图片各自角点的三维、二维坐标,相机标定。
每张图片都有自己的旋转和平移矩阵,但是相机内参和畸变系数只有一组。
mtx,相机内参;dist,畸变系数;外参数:revcs,旋转矩阵;tvecs,平移矩阵。
'''
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray1.shape[::-1], None, None)
img = cv2.imread(r'./image/zm/4ffe6fa6c7732896b58c0ef7cfd8cb7.jpg')
# print(img)
# extrinsics_param\
rvecs = np.array(rvecs)
# print("rvecs="+str(rvecs))
# rvecsnp, _ = cv2.Rodrigues(rvecs)

# print("rvecsnp="+str(rvecsnp))
# print("tvecs="+str(tvecs))
# 注意这里跟循环开头读取图片一样,如果图片太大要同比例缩放,不然后面优化相机内参肯定是错的。
# img = cv2.resize(img, None, fx=0.5, fy=0.5, interpolation=cv2.INTER_CUBIC)
# img1 = (9,6)
# h ,w = img1
h, w = img.shape[:2]

'''
优化相机内参(camera matrix),这一步可选。
参数1表示保留所有像素点,同时可能引入黑色像素,
设为0表示尽可能裁剪不想要的像素,这是个scale,0-1都可以取。
'''
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx, dist, (w, h), 1, (w, h))#显示更大范围的图片(正常重映射之后会删掉一部分图像)

# 纠正畸变
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# 这步只是输出纠正畸变以后的图片
x, y, w, h = roi
dst = dst[y:y + h, x:x + w]
cv2.imwrite('calibresult.png', dst)

# 打印我们要求的两个矩阵参数
"""参数newcameramtx为内参数矩阵,
dist为畸变系数,total error为总体误差。
newcameramtx:
归一化焦距fx=1.25045215e+03,fy=7.76162048e+02,
像主点(光心)的坐标cx=1.48972123e+03,cy=1.31742293e+03。
所有图像投影坐标和亚像素角点坐标之间的总体的平均误差大概为0.10,误差较小,标定结果不错"""

print("内参数矩阵,newcameramtx  :\n", newcameramtx)
print("归一化焦距fx,fy=",newcameramtx[0][0],newcameramtx[1][1])
print("像主点(光心)的坐标cx,cy",newcameramtx[0][2],newcameramtx[1][2])
print("dist为畸变系数。dist:\n", dist)
print("ret:\n",ret)
print("mtx,相机内参:\n",mtx)
print("revcs,旋转矩阵,",rvecs)
print("tvecs,平移矩阵",tvecs)
# mtx,相机内参;dist,畸变系数;外参数:revcs,旋转矩阵;tvecs,平移矩阵
# 计算误差
tot_error = 0
for i in xrange(len(objpoints)):
	imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
	error = cv2.norm(imgpoints[i], imgpoints2, cv2.NORM_L2) / len(imgpoints2)
	tot_error += error
print("total error为总体误差: ", tot_error / len(objpoints))

到了这里,关于相机标定,内参数与外参数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Matlab相机标定方法及主要参数含义,坐标变换过程

    网上有很多关于matlab相机标定的资料,但找了很久没有相应的参数说明:怎样利用获得参数从世界坐标系变换到图像坐标系,所以这里为了记录一下,也方便新人理解。 首先由图像到参数的获取部分在网上有很多资料,也很容易,在这就不再赘述,我利用的标定板的格子大小

    2024年02月05日
    浏览(45)
  • python利用opencv进行相机标定获取参数,并根据畸变参数修正图像附有全部代码(流畅无痛版)

    今天的低价单孔摄像机(照相机)会给图像带来很多畸变。畸变主要有两 种:径向畸变和切想畸变。如下图所示,用红色直线将棋盘的两个边标注出来, 但是你会发现棋盘的边界并不和红线重合。所有我们认为应该是直线的也都凸 出来了。 在 3D 相关应用中,必须要先校正这些畸变

    2024年02月06日
    浏览(50)
  • 【笔记&问题解决】激光雷达和相机外部参数标定全流程(livox_camera_calib加载数据问题解决 [#85 Issue] & PCL无法创建KDTree问题解决 [#19 Issue])

    激光雷达:DJI Livox Avia混合固态激光雷达 相机:Intel Realsense D435i深度相机 外参标定是进行多传感器融合的必要前提。 livox_camera_calib 是香港大学MaRS 实验室开发的一款的激光雷达和相机标定的算法。算法分为分为 单场景标定(Single scene calibration) 和 多场景标定(Multi scenes

    2024年02月04日
    浏览(78)
  • M2DGR数据集各相机话题名与外参名的对应关系

    M2DGR数据集各传感器的名称-话题-外参的对应关系-CSDN博客 文中介绍了M2DGR数据集各传感器的名称-话题-外参的对应关系。 M2DGR数据集除了视觉惯性器件、天向相机,还有6个安装在同一平面、参数一致的鱼眼相机。 本文对这6个相机的安装位置、外参、topic话题进行区分。 安装

    2024年02月10日
    浏览(59)
  • 相机标定和双目相机标定标定原理推导及效果展示

      参考了一些大佬的文章,整理了一下相机标定和双目标定的原理和推导。   摄像机成像就是空间场景投影至二维图像平面的空间变换过程。摄像机标定的要解决两个问题:首先确定三维空间点与像素平面像素点间的转换关系,即求解相机内外参;然后确定相机成像过程中

    2023年04月09日
    浏览(47)
  • 相机标定 - (02) - 相机标定步骤与原理

    目录 2 相机标定步骤 2.1 张正有标定操作步骤 2.2 张正有标定原理 参考文章: 三步骤详解张正友标定法_谜之_摄影爱好者的博客-CSDN博客         1998年,张正友提出了基于二维平面靶标的标定方法,使用相机在不同角度下拍摄多幅平面靶标的图像,比如棋盘格的图像,然

    2024年02月11日
    浏览(69)
  • 相机标定-机器视觉基础(理论推导、Halcon和OpenCV相机标定)

             相机标定是获得目标工件精准坐标信息的基础。首先,必须进行相机内参标定,构建一个模型消除图像畸变;其次,需要对相机和机器人的映射关系进行手眼标定,构建一个模型将图像坐标系上的点映射到世界坐标系。主要分为背景知识、相机内外参模型推导、

    2023年04月21日
    浏览(48)
  • 相机标定—— 张正友标定法(1)

    我们首先要明白两个问题:1、相机是如何成像的?2、相机标定的目的是什么? 相机的成像过程涉及了 4 种坐标系与 3 种变换关系,这 3种变换关系分别是刚体变换、投影变换和离散化。 图 1 : 四 种 坐 标 系 的 关 系 图1 :四种坐标系的关系 图 1 : 四 种 坐 标 系 的 关 系

    2023年04月09日
    浏览(84)
  • 【相机标定】相机内参

    相机在计算机视觉方面的一些应用一般需要相机标定。我们总是听到标定这个词,那么具体标定的是什么呢?相机的拍摄是一个三维到二维(透视投影)的过程,这个过程可以用数学模型去表述,标定便是计算这个数学模型中的参数,我们最终希望通过这些参数能够从二维的

    2023年04月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包