当前位置:   article > 正文

【计算机视觉】相机模型&立体视觉_相似三角形计算机视觉

相似三角形计算机视觉

1. 相机模型

1.1 相机模型的四个坐标系

针孔相机模型存在四个坐标系:世界坐标系、摄像机坐标系、图像物理坐标系和图像像素坐标系。

  • 世界坐标系Pw(Xw,Yw,Zw):是客观三维世界的绝对坐标系,也称客观坐标系。就是物体在真实世界中的坐标。 世界坐标系是随着物体的大小和位置变化的,单位是长度单位。

  • 相机坐标系Po(x,y,z):以相机的光心为坐标系的原点,以平行于图像的x和y方向为x轴和y轴,z轴和光轴平行,x, y,z互相垂直,单位是长度单位。

  • 图像物理坐标系P’(x’,y’):以主光轴和图像平面交点为坐标原点,x’和y’方向如图所示,单位是长度单位。

  • 图像像素坐标系p(u,v):以图像的顶点为坐标原点,u和v方向平行于x’和y’方向,单位是以像素计

1.2 坐标系关系图

四个坐标系关系图:
在这里插入图片描述

图像坐标系与像素坐标系的关系图:
在这里插入图片描述

1.3 坐标系之间的转换

坐标系之间的转换:物体→世界坐标→摄像机坐标→图像物理坐标→图像像素坐标

1.3.1 世界坐标系到摄像机坐标系

转换本质:旋转+平移

利用原理:欧式变换、齐次坐标

其关系可表示为(矩阵形式):旋转矩阵R、平移矩阵t
在这里插入图片描述

有以下两种算法进行坐标系的转换(区别:一次和多次)

  • 欧式变换:一次旋转+平移(两个三维坐标系的转换)
    a ′ = R a + t a'=Ra+t a=Ra+t
    在这里插入图片描述

  • 齐次坐标:多次旋转+平移

    假设我们将向量a进行了两次欧氏变换,旋转和平移分别为R1, t1 和 R2,t2,分别得到:

    b = R1a + t1, c = R2b + t2 ===>> c = R2*(R1*a + t1) + t2

    在这里插入图片描述

1.3.2 摄像机坐标系到图像物理坐标系

转换本质:三维坐标系降二维坐标系

利用原理:相似三角形

在这里插入图片描述

根据相似三角形等比例关系可以得到等式
X ′ = f X c Z c Y ′ = f Y c Z c X'=f\frac{X_c}{Z_c}\\ Y'=f\frac{Y_c}{Z_c} X=fZcXcY=fZcYc
等式右边f是固定的值,其他的值在前面步骤已经算出,故求出X‘和Y’。

将等式转换成矩阵形式为,可以看到从三维坐标系降到二维坐标系

在这里插入图片描述

1.3.3 图像物理坐标系到图像像素坐标系

转换本质:单位和原点的转化

在这里插入图片描述

图像解释:O点在O坐标系中的位置是原点(0,0),但是在Ouv坐标系中的位置是(Uo,Vo)。p点在O坐标系中的位置是(x,y),但在Ouv中的坐标就是(x+Uo,y+Vo)。但是需要单位转换,则坐标值应为
u = f X d x + u 0 v = f y d y + v 0 u=f\frac{X}{dx}+u_0\\ v=f\frac{y}{dy}+v_0 u=fdxX+u0v=fdyy+v0
dx和dy表示:x方向和y方向的一个像素分别占多少个(可能是小数)长度单位。

转换成齐次坐标为(矩阵形式)
在这里插入图片描述

1.4 总结

相机成像原理就是三次坐标系的转换

在这里插入图片描述

其中

在这里插入图片描述

U和V是需要求的未知量

XYZ为物体的坐标(已知)

f 焦距,dx,Uo和Vo是相机的内参,已知的固定值

R和t是相机的外参,随拍摄的图片而改变

简化后为
在这里插入图片描述

2. 相机畸变

2.1 镜头畸变

透镜由于制造精度以及组装工艺的偏差会引入畸变,导致原始图像的失真。

在这里插入图片描述

  1. 径向畸变

    由透镜的形状引起的畸变称为径向畸变,透镜径向畸变后点位的偏移示意图

    在这里插入图片描述

    箭头方向表示偏移方向(沿着半径方向)

    箭头长短表示偏移大小(畸变大小)

    距离光心越远,镜像内移动越大,箭头越长,畸变就越大

    有两种畸变

    • 枕形畸变在这里插入图片描述

    • 桶形畸变在这里插入图片描述

  2. 切向畸变

    产生切向畸变的原因:透镜本身与相机传感器平面(成像平面)或图像平面不平行。 这种情况多是由于透镜被粘贴到镜头模组上的安装偏差导致。(相机安装偏差导致出现的,一般不会出现这种情况)

    在这里插入图片描述

2.2 畸变矫正:透视变换

透视变换(投影映射):将图片投影到一个新的视平面(Viewing Plane)

透视变换的目的:把现实中为直线的物体,在图片上可能呈现为斜线,通过透视变换转换成直线 的变换。

仿射变换(仿射映射):是指在几何中,图像进行从 一个向量空间进行一次线性变换和一次平移,变换为到另一个向量空间的过程。(仿射变换是透视变换的一个特例)

在这里插入图片描述

通用的矩阵形式的变换公式(二维三维都通用):在这里插入图片描述

上式已知xy,求出矩阵(重点),就可以得到矫正后的图片的像素点的位置。

利用上述通用公式列出等式,下式XY是原始图片坐标,对应得到变换后的图片坐标(X’;Y’;Z’),其中Z’=1。

在这里插入图片描述

一般地,我们令a33=1,展开上面公式,得到一个点的情况:
a 11 x + a 12 y + a 13 − a 31 x X ′ − a 32 X ′ y = X ′ a 21 x + a 22 y + a 23 − a 31 x Y ′ − a 32 y Y ′ = Y ′ a_{11}x+a_{12}y+a_{13}-a_{31}xX'-a_{32}X'y=X'\\ a_{21}x+a_{22}y+a_{23}-a_{31}xY'-a_{32}yY'=Y' a11x+a12y+a13a31xXa32Xy=Xa21x+a22y+a23a31xYa32yY=Y
已知:原图像的四个顶点和矫正后的图像的四个顶点(使用边缘检测就可以获取)

原点四个坐标分别为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)

将八个顶点带入上面两个等式,就可以求出要求的八个变量 a11到a32

计算方法:可利用矩阵将值带入列出八个等式,如下矩阵等式

在这里插入图片描述

注意:上述八个点不一定都必须是图像的顶点。只要是可以对应的八个点就可以

【代码实现——warpMatrix】

# 详细的计算变换矩阵a的过程
import numpy as np
 
def WarpPerspectiveMatrix(src, dst):
    # 给定的原点和目标点的数量分别最少为4组
    assert src.shape[0] == dst.shape[0] and src.shape[0] >= 4
    
    nums = src.shape[0]
    # 创建一个8*8的矩阵A和8*1的矩阵B,要求A*warpMatrix=B
    A = np.zeros((2*nums, 8))
    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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

运行结果

warpMatrix
[[-5.01338334e-01 -1.35357643e+00  5.82386716e+02]
 [ 1.06858966e-15 -4.84035391e+00  1.38781980e+03]
 [ 4.33680869e-19 -4.14856327e-03  1.00000000e+00]]
  • 1
  • 2
  • 3
  • 4

【代码实现——透视变换】

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)# getPerspectiveTransform获得变换矩阵a
print("warpMatrix:")
print(m)
result = cv2.warpPerspective(result3, m, (337, 488))# warpPerspective变换矩阵a乘以原始坐标
cv2.imshow("src", img)
cv2.imshow("result", result)
cv2.waitKey(0)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

运行结果

(960, 540, 3)
warpMatrix:
[[ 8.92263779e-01  3.76733596e-01 -2.41585375e+02]
 [-4.08140258e-01  9.44205073e-01 -5.80899328e+01]
 [-8.53836442e-05  5.16464182e-05  1.00000000e+00]]
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

3. 立体视觉

立体视觉研究的是图像的深度信息,与三维空间有所不同

  • 含义:立体视觉是一种计算机视觉技术,其目的是从两幅或两幅以上的图像中推理出图像中每个像素点的深度信息。

  • 原理:立体视觉借鉴了人类双眼的“视差”原理,即左、右眼对于真实世界中某一物体的观测是存在差异的, 我们的大脑正是利用了左、右眼的差异,使得我们能够辨识物体的远近。(视差)(面试常问)

3.1 单目系统

在这里插入图片描述

3.2 双目系统

在这里插入图片描述

基本的几个概念:

  • 极平面:O1, O2, P三个点确定的平面
  • 极点:O1O2连线与像平面I1、I2的交点e1、e2;
  • 基线(baseline):O1O2
  • 极线:极平面与两个像平面之间的交线l1、l2

在这里插入图片描述

原理:三角形相似定理(△Ppp’~△POROT

在这里插入图片描述

Z是真正要求的距离,D就是视差

面试常问原理:相似三角形(不会问的特别细)

3.3 视差Disparity

视差:将同一空间物理点在不同图像中的映像点对应起来的差别叫视差
Z = B ⋅ f x R − x T = B ⋅ f D Z=\frac{B·f}{x_R-x_T}=\frac{B·f}{D} Z=xRxTBf=DBf
视差D越大,Z越小,是成反比的

在这里插入图片描述

3.4 面试常问

  1. 单目系统和双目系统主要的作用,为什么现在要用双目系统,单目系统的弊端

  2. 双目系统推导某个点的距离的时候用的什么原理?

    答:相似三角形

  3. 双目系统借鉴的是双眼,肉眼双目系统怎样通过视差呈现远近?

    答:说公式和反比图像

4. 点云模型

4.1 点云与三维图像

  • 三维图像:是一种特殊的信息表达形式,其特征是表达的空间中三个维度的数据。和二维图像相比, 三维图像借助第三个维度的信息,可以实现天然的物体和背景解耦。

  • 三维优点:对于视觉测量来说,物体的二维信息往往随射影方式而变化,但其三维特征对不同测量方式具有更好的统一性。

与相片不同,三维图像是对一类信息的统称,信息还需要有具体的表现形式,其表现形式包括:深度图(以灰度表达物体与相机的距离),几何模型(由CAD软件建立),点云模型(所有逆向工程 设备都将物体采样成点云)。

点云数据是最为常见也是最基础的三维模型。

  • 点云(Point Cloud)的理解:扫描资料以点的形式记录,每一个点包含有三维坐标,有些可能含有颜色信息(RGB)或反射强度信息(Intensity)。

  • 点云的概念:点云是在同一空间参考系下表达目标空间分布和目标表面特性的海量点集合,在获取物体表面每个采样点的空间坐标后,得到的是点的集合。

  • 点云的内容:(点云的储存信息不是固定不变的,根据具体需要改变)

    • 根据激光测量原理得到的点云,包括三维坐标(XYZ)和激光反射强度(Intensity), 强度信息与目标的表面材质、粗糙度、入射角方向,以及仪器的发射能量,激光波长有关。

    • 根据摄影测量原理得到的点云,包括三维坐标(XYZ)和颜色信息(RGB)。

    • 结合激光测量和摄影测量原理得到点云,包括三维坐标(XYZ)、激光反射强度(Intensity)和颜色信息(RGB)。

4.2 点云处理的三个层次

4.2.1 低层次处理方法

  1. 滤波方法:双边滤波、高斯滤波、条件滤波、直通滤波、随机采样一致性滤波。
  2. 关键点:ISS3D、Harris3D、NARF,SIFT3D

4.2.2 中层次处理方法

  1. 特征描述:法线和曲率的计算、特征值分析、SHOT、PFH、FPFH、3D Shape Context、Spin Image

  2. 分割与分类:

    分割:区域生长、Ransac线面提取、全局优化平面提取 、K-Means、Normalize Cut(Context based)、3D Hough Transform(线、面提取)、连通分析

    分类:基于点的分类,基于分割的分类,基于深度学习的分类(PointNet,OctNet)

4.2.3 高层次处理方法

  1. 配准:点云配准分为粗配准(Coarse Registration)和精配准(Fine Registration)两个阶段。

    精配准的目的是在粗配准的基础上让点云之间的空间位置差别最小化。

    粗配准是指在点云相对位姿完全未知的情况下对点云进行配准,可以为精配准提供良好的初始值。

    基于穷举搜索的配准算法:遍历整个变换空间以选取使误差函数最小化的变换关系或者列举出使最多点对满足的变 换关系。如RANSAC配准算法、四点一致集配准算法(4-Point Congruent Set, 4PCS)、Super4PCS算法等

    基于特征匹配的配准算法:通过被测物体本身所具备的形态特性构建点云间的匹配对应,然后采用相关算法对变换 关系进行估计。如基于点FPFH特征的SAC-IA、FGR等算法、基于点SHOT特征的AO算法以及基于线特征的ICL等

  2. SLAM图优化

    Ceres(Google的最小二乘优化库,很强大), g2o、LUM、ELCH、Toro、SPA SLAM方法:ICP、MBICP、IDC、likehood Field、NDT

  3. 三维重建

    泊松重建、 Delaunay triangulations、表面重建,人体重建,建筑物重建,树木重建。

    实时重建:重建植被或者农作物的4D(3D+时间)生长态势;人体姿势识别;表情识别。

  4. 点云数据管理:点云压缩,点云索引(KD、Octree),点云LOD(金字塔),海量点云的渲染。

4.3 Spin image(面试常问)

Spin image是基于点云空间分布的最经典的特征描述方法

算法思想(三维转二维):将一定区域的点云分布转换成二维的spin image,然后对场景和模型的spin images进行相似性度量

在这里插入图片描述

图像解读:

  • 大写P------三维网格某顶点p的切面
  • n-------p点单位法向量
  • x-------p附近的三维网格上的另一个顶点
  • α------x点在P上投影与p的距离
  • β------x点与P点的垂直距离
  • 其中p和n定义为一个定向点(Oriented point)
  • 将p和法向量n作为基底,就能够变成两个维度的坐标系
  • 空间内的所有点都能包含在以pn为基底的圆柱形坐标系中

生成spin image的步骤 (如上图)

  • 1. 定义一个定向点Oriented point

  • 2. 以定向点Oriented point为轴生成一个圆柱坐标系

  • 3. 定义Spin image的参数,Spin image是一个具有一定大小(行数列数)、分辨率(二维网格大小)的 二维图像(或者说网格)。

    spin image的三个关键参数

    • 分辨率: 二维网格的也就是像素的实际尺寸,使用和三维网格相近的尺寸比较合适,因此通常是取 三维网格所有边的平均值 来作为spin image的每个网格尺寸,通常会把网格的长和宽定义成相等,即边长。边长的计算公式(e为三维网格模型中的一条边,N为三维网格模型中的边的总数。)
      r = 1 N ∑ i = 1 N ∣ e i ∣ r=\frac{1}{N}\sum_{i=1}^N|e_i| r=N1i=1Nei

    • 大小:spin image的行数和列数,两者一般也相等。可以参考的大小10x10或20x20等。

    • support angle:法向量夹角的大小限制。空间中顶点的法向量与创建圆柱坐标系所选点法向量之间的夹角。可以降低后续的计算量

      夹角大小的选择:一般角度限制范围为60°~90°的点,其他的舍去,因为三维图像转二维有一些点是不需要的。夹角的角度根据实际情况会有所改变。

  • 4. 投影:将圆柱体内的三维坐标投影到二维Spin image,这一过程可以理解为一个Spin image绕着法向量n旋转360度,Spin image扫到的三维空间的点会落到Spin image的网格中。

    定向点的选择:肉眼选择,各种实验结果

    从三维空间投影到spin-image坐标:使用一张空白纸旋转黏贴(面试常问)

    在这里插入图片描述

  • 5. 根据spin image中的每个网格中落入的点不同,计算每个网格的强度I

    当一个点落入网格(i,j)中时会被双线性插值分散到(i,j)、(i,j+1)、(i+1,j)、(i+1,j+1)四个网格中。(根据权重距离进行分散)

    在这里插入图片描述

    使用双线性插值权重分散提高了噪声平滑

    扩展(不重要):binsize b, 图像尺寸W

    每个点落在哪个格子中遵循以下公式(计算落在哪个bin中)
    i = ∣ W 2 − β b ∣ i=|\frac{\frac{W}{2}-β}{b}| i=b2Wβ

    j = ∣ α β ∣ j=|\frac{α}{β}| j=βα

    α、β为横纵坐标

使用场景:三维重建、三维转二维、分类

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/544702
推荐阅读
相关标签
  

闽ICP备14008679号