照相机模型与增强现实

目录

1. 针孔照相机模型

1.1 照相机矩阵

1.2 三维点的投影

1.3 照相机矩阵的分解

1.4 计算照相机中心

2. 相机标定

2.1 实验

2.2 实验结果

2.3 实验结果分析 

1. 针孔照相机模型

针孔照相机模型是计算机视觉和计算机图形学中常用的一种相机模型,它假定相机的光学系统可以被视为一个小孔或针孔,通过该孔洞进入的光线会投影到相机成像平面上,形成一个倒立的图像。

在针孔照相机模型中,相机的成像平面与针孔之间的距离称为焦距(f)。当一个点在真实世界中沿相机坐标系的某个方向运动时,在成像平面上的投影也会沿着相应的方向运动,这种运动被称为相机的视角(viewing angle)或者视线(line of sight)。

假设相机的成像平面位于二维空间中,且坐标原点位于针孔处。则对于三维空间中的一个点P,其在相机坐标系下的坐标为(X, Y, Z),在成像平面上的投影坐标为(x, y),则可以使用以下公式来计算其投影坐标:

x = -f * X / Z

y = -f * Y / Z

其中,负号表示投影是倒立的,f为相机的焦距,X、Y、Z为点P在相机坐标系下的坐标。这个公式将三维空间中的点投影到了相机成像平面上,形成了一个二维图像。

需要注意的是,针孔照相机模型是一个理想化的模型,它假设光线传播是直线传播,忽略了透镜的复杂光学效应,因此在实际应用中存在一定误差。为了提高准确度,可以使用更为复杂的相机模型,如针孔模型的扩展模型(如彩色相机模型、鱼眼相机模型等)或者基于光线追踪的模型(如蒙特卡罗相机模型等)来描述相机成像过程。

针孔模型

  1. 假设物体表面的反射光都经过一个针孔而投影到像平面上,即满足光的直线传播条件。
  2. 针孔模型主要由光心(投影中心)、成像面和光轴组成。
  3. 小孔成像由于透光量太小,因此需要很长的曝光时间,并且很难得到清晰的图像。实际摄像系统通常都由透镜或者透镜组成。
  4. 两种模型具有相同的成像关系,即像点是物点和光心的连线与图像平面的交点。因此,可以用针孔模型作为照相机成像模型。

针孔照相机
针孔照相机模型(有时称为射影照相机模型)是计算机视觉中广泛使用的照相机模型。对于大多数应用来说,针孔照相机模型简单,并且具有足够的精确度。

 

空间点0是投影中心,它到平面π的距离是f。空间点M在平面π上的投影(或像)m是以点0为端点并经过点M的射线与平面π的交点。

平面π:摄像机的像平面
点0:摄像机中心(光心)
f:摄像机的焦距
以点0为端点且垂直于像平面的射线称为光轴或主轴,主轴与像平面的交点p称为摄像机的主点。

图像坐标系:
以图像左上角为原点建立以像素为单位的直接坐标系u-v。像素的横坐标u与纵坐标v分别是在其图像数组中所在的列数与所在行数。(在OpenCV中u对应x,v对应y)

由于(u,v)只代表像素的列数与行数,而像素在图像中的位置并没有用物理单位表示出来,所以,我们还要建立以物理单位(如毫米)表示的图像坐标系x-y。将相机光轴与图像平面的交点(一般位于图像平面的中心处,也称为图像的主点(principal point)定义为该坐标系的原点O1,且x轴与u轴平行,y轴与v轴平行,假设(u0,v0)代表O1在u-v坐标系下的坐标,dx与dy分别表示每个像素在横轴x和纵轴y上的物理尺寸,则图像中的每个像素在u-v坐标系中的坐标和在x-y坐标系中的坐标之间都存在如下的关系:

2019061400150844.gif (96×33)

20190614001516741.gif (93×37) 

其中,我们假设物理坐标系中的单位为毫米,那么dx的的单位为:毫米/像素。那么x/dx的单位就是像素了,即和u的单位一样都是像素。为了使用方便,可将上式用齐次坐标与矩阵形式表示为: 

 20190614002227909.gif (193×69)

相机坐标系:
相机成像的几何关系可由图2表示。其中O点为摄像机光心(投影中心),Xc轴和Yc轴与成像平面坐标系的x轴和y轴平行,Zc轴为相机的光轴,和图像平面垂直。光轴与图像平面的交点为图像的主点O1,由点O与Xc,Yc,Zc轴组成的直角坐标系称为摄像机的坐标系。OO1为相机的焦距。

 

世界坐标系:也称真实或现实世界坐标系,或全局坐标系。世界坐标系是为了描述相机的位置而被引入的,如图2.2中坐标系OwXwYwZw即为世界坐标系。

世界坐标与相机坐标之间的转换关系:
平移向量t和旋转矩阵R可以用来表示相机坐标系与世界坐标系的关系。所以,假设空间点P在世界坐标系下的齐次坐标是(Xw,Yw,Zw,1)T,(这里T是上标转置),在相机坐标下的齐次坐标是(Xc,Yc,Zc,1)T,则存在如下的关系:

其中:

1. R是3×3的正交单位矩阵(也称为旋转矩阵)
满足约束条件:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. T是三维的平移向量,矢量 ,是世界坐标系原点在照相机坐标系中的坐标。

3. M1是4×4矩阵。

 

4. 矩阵R实际上只含有三个独立变量R_{x},R_{y},R_{z},再加上t_{x},t_{y},t_{z},总共六个参数决定了照相机光轴在世界坐标系的坐标,因此这六个参数称为照相机的外部参数

图像坐标系与相机坐标系变换关系
照相机坐标系中的一点P在图像物理坐标系中像点P坐标为:

 

齐次坐标表示为:

 

将上式图像物理坐标系进一步转化为图像坐标系:

 因此可得物点P与图像像素坐标系中像点P_{f}的变换关系为:

 其中,f_{x}=fs_{x},f_{y}=fs_{y},分别定义为X和Y方向的等效焦距。f_{x},f_{y},u_{0},v_{0}这四个参数只与照相机内部结构有关,因此称为照相机的内部参数。

世界坐标系与图像坐标系变换关系:

转化为齐次坐标为:

 

这是针孔模型或者中心图像的数学表达式,在计算机内部参数确定的条件下 ,利用若干个已知的物点和相应的像点坐标,就可以求解出摄像机的内部和外部参数。 

1.1 照相机矩阵

相机矩阵(camera matrix)是计算机视觉和计算机图形学中常用的一个概念,它是描述相机内部参数和外部参数的矩阵。相机矩阵通常包含如下信息:

  1. 焦距(f):相机矩阵中的f元素是相机的焦距,表示相机成像平面与针孔之间的距离。焦距通常以像素为单位表示,可以通过测量相机成像平面上物体的实际尺寸和其在成像平面上的像素尺寸来估计。

  2. 光心(c):相机矩阵中的c元素是相机的光心,表示相机成像平面的中心点。光心通常以像素为单位表示,可以通过标定相机来估计。

  3. 图像畸变参数:相机矩阵中的畸变参数(k1、k2、k3等)用于描述相机镜头的畸变效应,包括径向畸变和切向畸变。径向畸变是由于镜头曲率半径不同而导致的图像畸变,切向畸变是由于镜头中心与成像平面不垂直而导致的图像畸变。这些畸变参数通常可以通过标定相机来估计。

  4. 外部参数(R、t):相机矩阵中的外部参数用于描述相机的位置和朝向。具体来说,外部参数包括旋转矩阵R和平移向量t,它们描述了相机坐标系与世界坐标系之间的变换关系。外部参数通常可以通过解PnP问题来估计,即通过已知的三维点和它们在图像中的投影点来求解相机的旋转和平移。

摄像机坐标系:O-XcXcZc
图像坐标系:O-XY

根据三角形相似原理,有

 

上式可表示为下面的矩阵:

20190613124550347.gif (259×67) 

其中:

20190613124629919.gif (76×89) 

20190613124639223.gif (69×67) 

如果记P=diag(f,f,1)(I,0),则上式可表示为m=PX_{c}其中,矩阵P是一个3x4的矩阵,通常称它为照相机矩阵。

1.2 三维点的投影

三维点的投影是指将三维空间中的点投影到相机成像平面上,形成二维图像上的点。三维点的投影可以用于计算机视觉和计算机图形学中的许多应用,如目标检测、姿态估计、虚拟现实等。

在相机成像平面上,每个像素都有一个对应的坐标,通常使用像素坐标系(pixel coordinate system)来表示。在像素坐标系中,图像的左上角为原点,x轴向右延伸,y轴向下延伸。如果将相机成像平面沿水平方向旋转90度,那么像素坐标系与相机坐标系就是同一坐标系。

将三维点投影到相机成像平面上,需要先将三维点从世界坐标系转换到相机坐标系,然后再将相机坐标系中的点投影到相机成像平面上。具体来说,可以使用以下公式来计算三维点的投影:

x = f * X / Z + cx

y = f * Y / Z + cy

其中,x和y为在像素坐标系中的投影坐标,f为相机的焦距,cx和cy为相机成像平面的光心坐标,X、Y、Z为三维点在相机坐标系中的坐标。这个公式将三维点的坐标投影到了相机成像平面上,得到了一个二维图像上的点。

需要注意的是,在实际应用中,还需要考虑相机的畸变效应,如径向畸变和切向畸变等。为了得到更精确的投影结果,需要对相机进行标定,估计出相机的内部参数和畸变参数,并对投影公式进行修正。

1.3 照相机矩阵的分解

齐次坐标下,物体的物理坐标是 [x,y,z,1]′的形式,图像上对应点的坐标是 [u,v,1]′的形式,所以相机矩阵 P作为把物体映射成像的矩阵,应该是一个 3×4 的矩阵。

因此,照相机矩阵可以表示为如下形式:

20190618140500199.PNG (136×32) 

| 代表的是增广矩阵
M 代表的是可逆的 3×3 的矩阵
C 是列向量,代表世界坐标系中相机的位置

要想求得 C, 只需要 P 的前三列组成的M, 求出来 −M−1 再乘以最后一列,就得到了 C矩阵的确可以把 3D的点投影到 2D 空间,但是,这种形式下表达的信息是很粗糙的,比如

没有提供相机的摆放姿态
没有相机内部的几何特征
为了挖掘这些信息,对矩阵进一步分解为一个内参矩阵和外参矩阵的乘积:
20190618140632129.PNG (226×33) 

其中:

矩阵R是rotation矩阵,因此是正交的;K是上三角矩阵. 对P的前三列进行RQ分解就可得到KR
T=−RC, 是摄像机坐标系下世界坐标系原点的位置, tx,ty,tz分别代表世界坐标原点在相机的 左右,上下,前后 位置关系。在三维重建中,一组标定好了的图片序列,它们各自的相机矩阵中的T应该是相同的。
其中 K 就是内参,R,T 为外参。
如果给定照相机矩阵 P,我们需要恢复内参数 K 以及照相机的 位置t 和姿势R。矩阵分块操作称为因子分解。这里,我们将使用一种矩阵因子分 解的方法,称为 RQ 因子分解

将下面的方法添加到 Camera 类中:

    def factor(self):
        """    Factorize the camera matrix into K,R,t as P = K[R|t]. """

        # factor first 3*3 part
        K, R = linalg.rq(self.P[:, :3])

        # make diagonal of K positive
        T = diag(sign(diag(K)))
        if linalg.det(T) < 0:
            T[1, 1] *= -1

        self.K = dot(K, T)
        self.R = dot(T, R)  # T is its own inverse
        self.t = dot(linalg.inv(self.K), self.P[:, 3])

        return self.K, self.R, self.t

RQ 因子分解的结果并不是唯一的。在该因子分解中,分解的结果存在符号二义性。 由于我们需要限制旋转矩阵 R 为正定的(否则,旋转坐标轴即可),所以如果需要, 我们可以在求解到的结果中加入变换 T 来改变符号。

在示例照相机上运行下面的代码,观察照相机矩阵分解的效果:

import camera
from numpy import *
K = array([[1000,0,500],[0,1000,300],[0,0,1]])
tmp = camera.rotation_matrix([0,0,1])[:3,:3]
Rt = hstack((tmp,array([[50],[40],[30]])))
cam = camera.Camera(dot(K,Rt))
print K,Rt
print cam.factor()

控制台输出:

1.4 计算照相机中心

给定照相机投影矩阵 P,我们可以计算出空间上照相机的所在位置。照相机的中心 C,是一个三维点,满足约束 PC=0。对于投影矩阵为 P=K[R|t] 的照相机,有:

20190618141236900.PNG (218×35) 

照相机的中心可以由下述式子来计算:

20190618141248834.PNG (93×34) 

注意,如预期一样,照相机的中心和内标定矩阵 K 无关。

下面的代码可以按照上面公式计算照相机的中心。将其添加到 Camera 类中,该方法会返回照相机的中心:

    def center(self):
        """计算并返回照相机的中心"""
        
        if self.c is not None:
            return self.c
        else:
            #通过因子分解计算c
            self.factor()
            self.c = -dot(self.R.T,self.t)
            return self.c

上面的一些方法构成了 Camera 类的基本函数操作。

2. 相机标定

相机标定是计算机视觉中的一项基本任务,它的目的是确定相机的内参数和外参数。相机的内参数包括焦距、主点位置和畸变参数等,而相机的外参数包括相机的位置和朝向。

在相机标定过程中,我们通常需要使用一些已知的物体或者图案,来计算相机在不同位置下的投影矩阵,然后通过对投影矩阵的分解和优化来得到相机的内外参数。

常用的相机标定方法包括:

1. 棋盘格法:使用已知尺寸的棋盘格图案,通过对图案在不同位置下的投影进行分析,来计算相机的内外参数。

2. 立体标定法:使用已知尺寸的三维物体,通过对不同视角下的图像进行匹配,来计算相机的内外参数。

3. 自标定法:使用运动相机拍摄同一场景的多张图像,通过对图像的关键点进行分析,来计算相机的内外参数。这种方法通常需要使用一些特殊的相机或者附加设备,如陀螺仪、惯性测量单元等。

在实际应用中,我们通常使用一些相机标定工具来简化标定过程,如OpenCV提供的相机标定模块cv2.calibrateCamera()和cv2.stereoCalibrate()等。这些工具可以自动化地进行相机标定,并输出相机的内外参数,从而使得相机标定变得更加简单和可靠。

标定照相机是指计算出该照相机的内参数。在我们的例子中,是指计算矩阵 K。需要准备一个平面矩形的标定物体(一张图片即可)、用于测 量的卷尺和直尺,以及一个平面。

下面是具体操作步骤:

  1. 测量你选定矩形标定物体的边长dX 和 dY;
  2. 将照相机和标定物体放置在平面上,使得照相机的背面和标定物体平行,同时物体位于照相机图像视图的中心,你可能需要调整照相机或者物体来获得良好的对 齐效果;
  3. 测量标定物体到照相机的距离 dZ;
  4. 拍摄一副图像来检验该设置是否正确,即标定物体的边要和图像的行和列对齐;
  5. 使用像素数来测量标定物体图像的宽度和高度 dx和 dy

2.1 实验

下面通过实验来实现张正友标定法对照相机进行标定。我准备的是下图这种格子数为5×5,内角点为4×4的棋盘格图片,手机型号为iPhone13。

代码:

import cv2
import numpy as np
import glob

# 设置寻找亚像素角点的参数,采用的停止准则是最大循环次数30和最大误差容限0.001
criteria = (cv2.TERM_CRITERIA_MAX_ITER | cv2.TERM_CRITERIA_EPS, 30, 0.001)

# 获取标定板角点的位置
#内角点个数,内角点是和其他格子连着的点
objp = np.zeros((4 * 4, 3), np.float32)
# 类似view() or permute()
objp[:, :2] = np.mgrid[0:4, 0:4].T.reshape(-1, 2)  # 将世界坐标系建在标定板上,所有点的Z坐标全部为0,所以只需要赋值x和y

obj_points = []  # 存储3D点
img_points = []  # 存储2D点
i=0
# images = [str(i+1)+'.jpg' for i in range(10)]
# 图片不可以有中文符号
images = glob.glob(r'D:\\作业\\tupian.jpg\\*.jpg')
print(len(images))
for fname in images:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    size = gray.shape[::-1]
    # print(size)
    ret, corners = cv2.findChessboardCorners(gray, (4, 4), None)
    # print(corners)

    if ret:
        #存储3D点
        obj_points.append(objp)

        corners2 = cv2.cornerSubPix(gray, corners, (5, 5), (-1, -1), criteria)  # 在原角点的基础上寻找亚像素角点
        # print(corners2)
        # 存储2D点
        if [corners2]:
            img_points.append(corners2)
        else:
            img_points.append(corners)

        cv2.drawChessboardCorners(img, (4, 4), corners, ret)  # 记住,OpenCV的绘制函数一般无返回值
        i+=1;
        cv2.imwrite('conimg'+str(i)+'.jpg', img)
        cv2.waitKey(1500)

# print(len(img_points))
cv2.destroyAllWindows()

# 标定 去畸变
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(obj_points, img_points, size, None, None)

print("ret:布尔值:", ret)
print("内参数矩阵:\n", mtx) # 内参数矩阵
print("畸变系数:\n", dist)  # 畸变系数   
print("旋转向量:\n", rvecs)  # 旋转向量  # 外参数
print("平移向量:\n", tvecs ) # 平移向量  # 外参数

2.2 实验结果

 

 

畸变矫正:

代码:

img = cv2.imread(images[10])
h, w = img.shape[:2]
# 获取新的相机矩阵和ROI
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('correction.jpg', dst)
print("校正后的图片已保存到文件 'correction.jpg'")

畸变矫正前的图像:

畸变矫正后的图像:

2.3 实验结果分析 

从实验结果中可以看到成功计算出了照相机内部参数和外部参数,文件夹中有十张不同角度的拍摄图片,但是实验得出相机标定的图片只有六张,分析结果最有可能的俩个原因是:(1)标定图像选取不当:在选择标定图像时,需要尽可能覆盖相机参数空间,以获得更准确和稳定的标定结果。如果标定图像的选择不当,例如存在角度、距离或方向上的偏差,可能会导致标定结果不准确或不稳定。(2)标定算法和参数设置不当:标定算法和参数设置也会影响相机参数估计的精度和稳定性。如果使用的标定算法不适用于特定的标定数据集,或者标定参数设置不当,可能会导致标定结果不准确或不稳定。

 同时在实验过程中也体会到了张正友标定法的优点和一些问题,其主要优点包括:

1. 可以利用任意三维平面:Zhang的方法不仅可以使用棋盘格等特定的标定板,还可以使用任意三维平面作为标定物体,从而提高了标定的灵活性和通用性。

2. 精度较高:Zhang的方法通过最小化重投影误差来进行相机参数估计,可以获得相对较高的标定精度。

3. 简单易用:Zhang的方法不需要复杂的计算和数据处理,只需要使用标定板拍摄多张图像,即可自动估计相机参数。

尽管张正友标定法有很多优点,但也存在一些问题:

1. 对标定板的要求较高:虽然张正友标定法可以使用任意三维平面作为标定物体,但标定板的质量和特征对标定精度仍有很大影响。如果标定板的质量不佳或标定板的特征不明显,可能会导致标定结果不准确或不稳定。

2. 对图像质量的要求较高:Zhang的方法对图像质量要求较高,如果图像存在噪声、失真或模糊等问题,可能会导致标定结果不准确或不稳定。

3. 对标定样本的要求较高:Zhang的方法需要使用多个不同角度、不同距离和不同方向的图像来进行标定,以覆盖尽可能多的相机参数空间。如果标定样本数量不足或选择不当,可能会导致标定结果不准确或不稳定。

4. 对相机畸变的处理较为简单:Zhang的方法对相机畸变的处理较为简单,只能进行轻微的畸变校正。如果相机存在较大的畸变,可能需要使用其他的标定方法进行相机参数估计。

综上所述,张正友标定法是一种常用的相机标定方法,具有通用性、精度高、简单易用等特点。但是,在使用张正友标定法时需要注意标定板的质量和特征、图像质量、标定样本数量和选择、相机畸变等问题,以获得更准确和稳定的标定结果。

 畸变矫正的结果很不理想,分析可能存在的原因:(1)畸变模型选择问题:畸变矫正通常需要选择适当的畸变模型来描述相机的畸变形式。如果选择的畸变模型与实际畸变形式不匹配,就会影响畸变矫正的精度。(2)参数设置问题:畸变矫正通常需要设置一些参数,例如畸变系数、校准板大小等。如果参数设置不当,就会影响畸变矫正的精度。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值