计算机视觉之相机模型
目录一、相机模型1、相机与图像2、坐标系3、世界坐标系到摄像机坐标系4、摄像机坐标系到图像物理坐标系5、图像物理坐标系到图像像素坐标系6、摄像机坐标系到图像像素坐标系7、世界坐标系到图像像素坐标系二、 镜头畸变1、相机成像原理2、镜头畸变径向畸变:切向畸变:3、畸变矫正三、透视变换1、定义一、相机模型1、相机与图像针孔相机模型存在四个坐标系:世界坐标系、摄像机坐标系、图像物理坐标系和图像像素坐标系
目录
一、相机模型
1、相机与图像
下图中如何从P到P’? 这是一个三维转二维的过程。
针孔相机模型存在四个坐标系:世界坐标系、摄像机坐标系、图像物理坐标系和图像像素坐
标系。
假设:
• 世界坐标系的坐标为Pw(Xw,Yw,Zw),
• 对应的摄像机坐标系坐标为Po(x,y,z),
• 对应的图像物理坐标系的坐标为P’(x’,y’),
• 对应的图像像素坐标系的坐标为p(u,v)。
2、坐标系
世界坐标系:是客观三维世界的绝对坐标系,也称客观坐标系。就是物体在真实世界中的坐标。世界坐标系是随着物体的大小和位置变化的,单位是长度单位。
相机坐标系:以相机的光心为坐标系的原点,以平行于图像的x和y方向为x轴和y轴, z轴和光轴平行, x,y, z互相垂直,单位是长度单位。
图像物理坐标系:以主光轴和图像平面交点为坐标原点, x’和y’方向如图所示,单位是长度单位。
图像像素坐标系:以图像的顶点为坐标原点, u和v方向平行于x’和y’方向, 单位是以像素计。
相机成像:
3、世界坐标系到摄像机坐标系
这两个坐标系之间除了旋转矩阵R,还存在平移矩阵t。其关系可表示为:
R 、t 、0T都是矩阵
欧式变换:欧氏变换由两部分组成:旋转R 平移t
齐次坐标:
多次连续的旋转和平移的情况下。假设我们将向量a进行了两次欧氏变换,旋转和平移分别为R1, t1 和 R2, t2,分别得到:
b = R1*a + t1, c = R2*b + t2 ===>> c = R2*(R1*a + t1) + t2
这样下去公式会越来越长,我们可以用矩阵的形式进行表达:
4、摄像机坐标系到图像物理坐标系
相似三角形:
将Zc移到等式左边,并构建齐次坐标,然后将上述公式转为矩阵的形式:
5、图像物理坐标系到图像像素坐标系
dx和dy表示: x方向和y方向的一个像素分别占多少个(可能是小数) 长度单位。
齐次坐标下:
6、摄像机坐标系到图像像素坐标系
7、世界坐标系到图像像素坐标系
K表示相机的内参矩阵,设定好的;R、t表示相机的外参矩阵,随拍摄的图片而变化
上述内容所讲的相机模型是指图像处理过程中计算需要用到的,而非真正的照相机在照相的过程,真正的照相机成像是光学原理进行成像的.
二、 镜头畸变
1、相机成像原理
2、镜头畸变
➢ 透镜由于制造精度以及组装工艺的偏差会引入畸变,导致原始图像的失真。
➢ 镜头的畸变分为径向畸变和切向畸变两类。
r表示半径
径向畸变:沿半径方向的畸变
由透镜的形状引起的畸变称为径向畸变,透镜径向畸变后点位的偏移示意图如下所示
➢ 枕形畸变
➢ 桶形畸变
切向畸变:沿切线方向形成的畸变
切向畸变是由于透镜本身与相机传感器平面(成像平面)或图像平面不平行而产生的。这种情况多是由于透镜被粘贴到镜头模组上的安装偏差导致,较少见,一般都是机器安装的,很少出问题。切向畸变示意图:
3、畸变矫正
• 径向畸变和切向畸变模型中一共有5个畸变参数,在Opencv中他们被排列成一个5*1的矩阵,依次包含k1、k2、 p1、 p2、 k3,经常被定义为Mat矩阵的形式,如Mat distCoeffs=Mat(1,5, CV_32FC1, Scalar::all(0));
• 这5个参数就是相机标定中需要确定的相机的5个畸变系数。
• 求得这5个参数后,就可以校正由于镜头畸变引起的图像的变形失真。这些参数在相机生产出来后就确定了,是可以得到的,在日常应用中一般都是已知的,相机标定中给定的。此外,也可通过矫正前的图像与矫正后的图像进行计算得到。
摄像中广角的原理类似将正常的图像变为畸变,使画面的内容变多。
三、透视变换
1、定义及算法流程
透视变换是**将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。**我们常说的仿射变换是透视变换的一个特例。
透视变换的目的就是把现实中为直线的物体,在图片上可能呈现为斜线,通过透视变换转换成直线的变换。
仿射变换(Affine Transformation或 Affine Map),又称为仿射映射,是指在几何中,图像进行从一个向量空间进行一次线性变换和一次平移,变换为到另一个向量空间的过程。
通用的变换公式为:这里的原始图片是带有畸变的,即x,y表示的图片
下式中的X,Y是原始图片坐标(上式的x,y), 对应得到变换后的图片坐标(X’;Y’;Z’)其中Z’=1:
一般地,我们令a33=1,展开上面公式,得到一个点的情况:
源点四个顶点坐标分别为A:(x0,y0),(x1,y1),(x2,y2),(x3,y3)
目标点四个顶点坐标分别为B: (X’0,Y’0),(X’1,Y’1),(X’2,Y’2),(X’3,Y’3)
将这八个点代入方程,并将其转换为矩阵相乘的格式:
上图中,点的坐标都是已知的,未知的只有warpMatrix中的元素的值,可通过解方程得到这些元素的值。
2、示例代码
根据上述算法过程实现代码:
import numpy as np
def WarpPerspectiveMatrix(src, dst):
assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4
nums = src.shape[0]
A = np.zeros((2*nums, 8)) # A*warpMatrix=B
B = np.zeros((2*nums, 1))
for i in range(0, nums):
A_i = src[i,:]
B_i = dst[i,:]
A[2*i, :] = [A_i[0], A_i[1], 1, 0, 0, 0,
-A_i[0]*B_i[0], -A_i[1]*B_i[0]]
B[2*i] = B_i[0]
A[2*i+1, :] = [0, 0, 0, A_i[0], A_i[1], 1,
-A_i[0]*B_i[1], -A_i[1]*B_i[1]]
B[2*i+1] = B_i[1]
A = np.mat(A)
#用A.I求出A的逆矩阵,然后与B相乘,求出warpMatrix
warpMatrix = A.I * B #求出a_11, a_12, a_13, a_21, a_22, a_23, a_31, a_32
#之后为结果的后处理
warpMatrix = np.array(warpMatrix).T[0]
warpMatrix = np.insert(warpMatrix, warpMatrix.shape[0], values=1.0, axis=0) #插入a_33 = 1
warpMatrix = warpMatrix.reshape((3, 3))
return warpMatrix
if __name__ == '__main__':
print('warpMatrix')
src = [[10.0, 457.0], [395.0, 291.0], [624.0, 291.0], [1000.0, 457.0]]
src = np.array(src)
dst = [[46.0, 920.0], [46.0, 100.0], [600.0, 100.0], [600.0, 920.0]]
dst = np.array(dst)
warpMatrix = WarpPerspectiveMatrix(src, dst)
print(warpMatrix)
调用opencv库实现:
import cv2
import numpy as np
img = cv2.imread('photo1.jpg')
result3 = img.copy()
'''
注意这里src和dst的输入并不是图像,而是图像对应的顶点坐标。
'''
src = np.float32([[207, 151], [517, 285], [17, 601], [343, 731]])
dst = np.float32([[0, 0], [337, 0], [0, 488], [337, 488]])
print(img.shape)
# 生成透视变换矩阵;进行透视变换
m = cv2.getPerspectiveTransform(src, dst)
print("warpMatrix:")
print(m)
result = cv2.warpPerspective(result3, m, (337, 488))
cv2.imshow("src", img)
cv2.imshow("result", result)
cv2.waitKey(0)
注:本文章参考了百度百科、他人技术博客、八斗学院课件资料、计算机视觉书籍等综合整理而来,如有侵权,联系删除!水平有限,欢迎各位指导交流!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)