计算机视觉学习blog(五)——张正友相机标定

一、相机标定

1.相机标定介绍

相机标定指建立相机图像像素位置与场景点位置之间的关系,根据相机成像模型,由特征点在图像中坐标与世界坐标的对应关系,求解相机模型的参数,包括内部参数和外部参数。标定照相机的标准方法是,拍摄多幅平面棋盘模式的图像,然后进行处理计算。

针孔相机成像原理其实就是利用投影将真实的三维世界坐标转换到二维的相机坐标上去,其模型示意图如下图所示:
在这里插入图片描述
从图中我们可以看出,在世界坐标中的一条直线上的点在相机上只呈现出了一个点,其中发生了非常大的变化,同时也损失和很多重要的信息,这正是我们3D重建、目标检测与识别领域的重点和难点。实际中,镜头并非理想的透视成像,带有不同程度的畸变。理论上镜头的畸变包括径向畸变和切向畸变,切向畸变影响较小,通常只考虑径向畸变。
径向畸变:径向畸变主要由镜头径向曲率产生(光线在远离透镜中心的地方比靠近中心的地方更加弯曲)。导致真实成像点向内或向外偏离理想成像点。其中畸变像点相对于理想像点沿径向向外偏移,远离中心的,称为枕形畸变;径向畸点相对于理想点沿径向向中心靠拢,称为桶状畸变。

在这里插入图片描述

2.相机标定方法

1、传统相机标定
最简单的相机标定为线性标定,即不考虑相机的畸变而只考虑空间坐标转换。
每个坐标点有X,Y两个变量,可列两个方程,相机内参有5个未知数,外参平移和旋转各3个,共有11个变量,因此至少需要6个特征点来求解。
2、非线性标定
当镜头畸变明显时必须考虑畸变,一般较为便宜的网络摄像头畸变特别大,而价格较贵的工业摄像头则畸变很小,因为其中已经嵌入了许多消除畸变的程序。这时线性模型转化为非线性模型,需要通过非线性标定方法求解。有最速下降法,遗传算法,高斯牛顿法和神经网络算法等。
3、张正友标定
“张正友标定”又称“张氏标定”,是指张正友教授于1998年提出的单平面棋盘格的摄像机标定方法。张氏标定法已经作为工具箱或封装好的函数被广泛应用。张氏标定的原文为“A Flexible New Technique forCamera Calibration”。此文中所提到的方法,为相机标定提供了很大便利,并且具有很高的精度。从此标定可以不需要特殊的标定物,只需要一张打印出来的棋盘格。

二、相机参数

同步标定内部参数和外部参数一般包括两种策略:

光学标定: 利用已知的几何信息(如定长棋盘格)实现参数求解。
自标定: 在静态场景中利用 structure from motion估算参数。

1.内参

为什么叫内参呢,这个是因为这些参数是只有相机来决定的,不会因为外界环境而改变。
相机内部参数/内方位元素: 焦距、像主点坐标、畸变参数
相机的内参是:1/dx、1/dy、r、u0、v0、f
opencv中的内参是4个,分别为fx、fy、u0、v0。其实opencv中的fx也就是F*Sx,其中F是焦距上面的f,Sx是像素/每毫米也就是上面的1/dx。
dx和dy表示x方向和y方向的一个像素分别占多少个单位,是反映现实中的图像物理坐标关系与像素坐标系转换的关键(我理解的是可以反映像元密度)。
u0,v0代表图像的中心像素坐标和图像原点像素坐标之间相差的横向和纵向像素数。

2.外参

相机外部参数/外方位元素: 旋转、平移
相机的外参是6个,三个轴的旋转参数分别是(w、δ、θ),把每个轴的33旋转矩阵进行组合(矩阵之间相乘),得到集合三个轴旋转信息的R,其大小还是33;T的三个轴的平移参数(Tx、Ty、Tz)。R、T组合成3*4的矩阵,其是转换到标定纸坐标的关键。

3.畸变参数

畸变一般可以分为:径向畸变、切向畸变
径向畸变来自于透镜形状。
切向畸变来自于整个摄像机的组装过程。
畸变还有其他类型的畸变,但是没有径向畸变、切向畸变显著,所以忽略不计。
畸变参数是:k1,k2,k3径向畸变,p1,p2是切向畸变系数。径向畸变发生在相机坐标系转像物理坐标系的过程中。
切向畸变:产生的原因是透镜不完全平行于图像。

三、张正友标定

优点:
1.只需一个平面
2.标定过程中无需知道棋盘格的方位
3.大量开源代码

1.实验数据

图片集:手机拍摄的11张棋盘格照片(尽量多拍10-20张,以防有些图片效果不好)

在这里插入图片描述
特别注意:文件存放路径为英文名

2.代码

import cv2
import numpy as np
import glob

# 找棋盘格角点
# 阈值
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#棋盘格模板规格
w = 14   #内角点个数,内角点是和其他格子连着的点
h = 9

# 世界坐标系中的棋盘格点,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐标,记为二维矩阵
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
# 储存棋盘格角点的世界坐标和图像坐标对
objpoints = [] # 在世界坐标系中的三维点
imgpoints = [] # 在图像平面的二维点

images = glob.glob('D:/picture/*.jpg')
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    # 找到棋盘格角点
    # 棋盘图像(8位灰度或彩色图像)  棋盘尺寸  存放角点的位置
    ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
    # 如果找到足够点对,将其存储起来
    if ret == True:
        # 角点精确检测
        # 输入图像 角点初始坐标 搜索窗口为2*winsize+1 死区 求角点的迭代终止条件
        cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
        objpoints.append(objp)
        imgpoints.append(corners)
        # 将角点在图像上显示
        cv2.drawChessboardCorners(img, (w,h), corners, ret)
        cv2.imshow('findCorners',img)
        cv2.waitKey(1000)
# cv2.destroyAllWindows()
#标定、去畸变
# 输入:世界坐标系里的位置 像素坐标 图像的像素尺寸大小 3*3矩阵,相机内参数矩阵 畸变矩阵
# 输出:标定结果 相机的内参数矩阵 畸变系数 旋转矩阵 平移向量
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
# mtx:内参数矩阵
# dist:畸变系数
# rvecs:旋转向量 (外参数)
# tvecs :平移向量 (外参数)
print (("ret:"),ret)
print (("mtx:\n"),mtx)        # 内参数矩阵
print (("dist:\n"),dist)      # 畸变系数   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)
print (("rvecs:\n"),rvecs)    # 旋转向量  # 外参数
print (("tvecs:\n"),tvecs)    # 平移向量  # 外参数
# 去畸变
img2 = cv2.imread('D:/picture/5.jpg')
h,w = img2.shape[:2]
# 我们已经得到了相机内参和畸变系数,在将图像去畸变之前,
# 我们还可以使用cv.getOptimalNewCameraMatrix()优化内参数和畸变系数,
# 通过设定自由自由比例因子alpha。当alpha设为0的时候,
# 将会返回一个剪裁过的将去畸变后不想要的像素去掉的内参数和畸变系数;
# 当alpha设为1的时候,将会返回一个包含额外黑色像素点的内参数和畸变系数,并返回一个ROI用于将其剪裁掉
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) # 自由比例参数

dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
# 根据前面ROI区域裁剪图片
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.jpg',dst)

# 反投影误差
# 通过反投影误差,我们可以来评估结果的好坏。越接近0,说明结果越理想。
# 通过之前计算的内参数矩阵、畸变系数、旋转矩阵和平移向量,使用cv2.projectPoints()计算三维点到二维图像的投影,
# 然后计算反投影得到的点与图像上检测到的点的误差,最后计算一个对于所有标定图像的平均误差,这个值就是反投影误差。
total_error = 0
for i in range(len(objpoints)):
    imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
    error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
    total_error += error
print (("total error: "), total_error/len(objpoints))




3.实验结果

角点检测:
在这里插入图片描述
可见该图角点检测效果较好。
在这里插入图片描述
内参矩阵:
在这里插入图片描述
这里利用matlab自带标定工具计算内参数得
在这里插入图片描述
由于手机拍摄,此处无畸变参数

外参数:
旋转向量:
在这里插入图片描述

平移向量:
在这里插入图片描述
平均误差大概为0.05,误差应该算很小了。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 张正友标定是一种计算机视觉领域常用的相机标定,CSND是国内IT技术社区的一个平台,而OpenCV是一个开源计算机视觉库。 张正友相机标定是一种基于棋盘格的相机标定。首先,需要拍摄包含已知尺寸的棋盘格图片。然后,通过OpenCV提供的函数,使用张正友相机标定对这些图片进行处理,计算相机内参和畸变系数。 在CSND这个平台上,我们可以找到很多关于OpenCV和相机标定的教学资源和代码实例。这些教程和代码可以帮助我们理解和实践相关的算相机标定的目的是为了减小相机的畸变,提高图像处理的精度。通过使用张正友相机标定,我们可以得到相机的内外参数,比如焦距和相机中心等信息。通过将这些参数应用于图像处理,可以更准确地还原和测量现实世界中的图像。 总的来说,张正友相机标定是一种常用且有效的相机标定,通过CSND和OpenCV,我们可以学习和实践相关的算,提高图像处理的精度和准确性。 ### 回答2: 张正友相机标定是一种常用的相机标定,它是通过计算相机内外参数以及畸变系数来实现的。在CSDN上有很多关于张正友相机标定的教程和代码库,使用OpenCV作为开发框架可以更加方便地实现相机标定。 在进行相机标定之前,首先需要准备一系列已知的三维空间坐标点以及对应的二维像素坐标点。这些坐标点可以通过测量目标场景中的物体或特征点得到。然后,通过利用张正友相机标定,可以根据这些已知坐标点来计算相机的内外参数和畸变系数。 张正友相机标定的步骤主要包括棋盘格拍摄、角点检测、角点定位和相机标定等。具体来说,首先需要用相机拍摄多张棋盘格图像。然后,使用OpenCV的角点检测函数对这些图像进行角点检测,获取角点像素坐标。接着,通过标定函数对获取的角点像素坐标以及已知的三维空间坐标点进行相机标定,计算出相机的内外参数和畸变系数。最后,可以通过这些参数将相机的图像坐标转换为真实世界中的三维坐标。 在CSDN上,有很多关于张正友相机标定的教程和示例代码。这些教程和代码可以帮助开发者更好地理解和应用张正友相机标定,加速相机标定的过程。 总结来说,张正友相机标定是一种常用的相机标定,通过计算相机内外参数和畸变系数来实现。在CSDN上可以找到相关的教程和代码库,并使用OpenCV进行开发和实现。这种相机标定计算机视觉、机器人、增强现实等领域有着广泛的应用。 ### 回答3: 张正友相机标定是一种常用的相机标定,通过计算相机的内参和畸变参数,可以实现对图像的几何校正和准确测量。这个方计算机视觉和机器视觉领域广泛应用。 CSDN是一个知名的中文技术论坛和博客网站,提供关于计算机科学和技术的各种信息和资源。CSDN上有很多关于张正友相机标定的教程和实例,供开发者学习和借鉴。 OpenCV是一个开源的计算机视觉库,提供了丰富的图像处理和计算机视觉。OpenCV支持张正友相机标定,并且提供了相应的函数和接口,方便开发者进行相机标定的实现。 张正友相机标定的原理是通过获取多个不同位置、不同角度的棋盘格图像,利用棋盘格的特征点进行相机内参和畸变参数的计算。这些参数可以用来校正图像,消除畸变,使得图像中的物体更加真实和准确。 在进行相机标定前,需要准备一套已知尺寸的棋盘格,在不同位置、不同角度下拍摄多张图像。然后利用OpenCV提供的函数,根据图像中棋盘格的特征点,计算相机内参和畸变参数。 相机标定完成后,可以使用标定参数进行图像校正和几何测量。例如,可以消除图像中的畸变,提高图像的质量;还可以根据已知物体在图像中的尺寸,通过相机的投影关系计算出物体在真实世界中的尺寸。 综上所述,张正友相机标定是一种常用的相机标定,在CSDN和OpenCV的支持下,可以方便地进行相机标定,实现图像的几何校正和准确测量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值