照相机模型与增强现实

Posted LuoY、

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了照相机模型与增强现实相关的知识,希望对你有一定的参考价值。

第四章 照相机模型与增强现实

4.1针孔照相机模型

    针孔照相机模型(有时称为射影照相机模型)是计算机视觉中广泛使用的照相机模型。对于大多数应用来说,针孔照相机模型简单,并且具有足够的精确度。在针孔照相机模型中,在光线投影到图像平面之前,从唯一一个点经过,也就是照相机中心C。下图为照相机中心前画出图像平面的图解。

4.1.1 照相机矩阵

    照相机矩阵可以分解为:
P = K [ R ∣ t ] P=K\\left [ R\\mid t \\right ] P=K[Rt]
    其中, R R R是描述照相机方向的旋转矩阵, t t t是描述照相机中心位置的三维平移向量, 内标定矩阵 K K K描述照相机的投影性质。
    标定矩阵仅和照相机自身的情况相关,通常情况下可以写成:
K = [ α f s c x 0 f c y 0 0 1 ] K=\\beginbmatrix \\alpha f & s& c_x\\\\ 0 & f& c_y\\\\ 0 & 0& 1 \\endbmatrix K= αf00sf0cxcy1
    图像平面和照相机中心间的距离为焦距 f f f。当像素数组在传感器上偏斜的时候,需要用到倾斜参数 s s s。在大多数情况下, s s s可以设置成0。也就是说:
K = [ f x 0 c x 0 f y c y 0 0 1 ] , 其中 f x = α f y K=\\beginbmatrix f_x & 0& c_x\\\\ 0 & f_y& c_y\\\\ 0 & 0& 1 \\endbmatrix,其中f_x=\\alpha f_y K= fx000fy0cxcy1 ,其中fx=αfy
    纵横比例参数 α 是在像素元素非正方形的情况下使用的。通常情况下,我们可以默认设置 α = 1 \\alpha =1 α=1。经过这些假设,标定矩阵变为:
K = [ f 0 c x 0 f c y 0 0 1 ] K=\\beginbmatrix f & 0& c_x\\\\ 0 & f& c_y\\\\ 0 & 0& 1 \\endbmatrix K= f000f0cxcy1
    除焦距之外,标定矩阵中剩余的唯一参数为光心(有时称主点)的坐标 c = [ c x , c y ] c=[c_x,c_y] c=[cx,cy]也就是光线坐标轴和图像平面的交点。因为光通常在图像的中心,并且图像的坐标是从左上角开始计算的,所以光心的坐标常接近于图像宽度和高度的一半。特别强调一点,在这个例子中,唯一未知的变量是焦距 f f f

4.1.2三维点的投影

    下面来创建照相机的类,用于处理我们对照相机和投影建模所需要的全部操作。
    创建一个Camera.py文件,并添加下列代码:

from scipy import linalg
import numpy as np

class Camera(object):
    """表示针孔照相机的类"""

    def __init__(self, P):  # 注意:需要左右各需要两个下划线
        """初始化P=K[R|t]照相机模型"""
        self.P = P
        self.K = None  # 标定矩阵
        self.R = None  # 旋转
        self.t = None  # 平移
        self.c = None  # 照相机中心

    def project(self, X):
        """X(4*n的数组)的投影点,并且进行坐标归一化"""

        x = np.dot(self.P, X)
        for i in range(3):
            x[i] /= x[2]
        return x

    def rotation_matrix(a):
        """    Creates a 3D rotation matrix for rotation
            around the axis of the vector a. """
        R = np.eye(4)
        R[:3, :3] = linalg.expm([[0, -a[2], a[1]], [a[2], 0, -a[0]], [-a[1], a[0], 0]])
        return R

    # 该函数是一种矩阵因子分解方法,称为RQ因子分解。其结果不是唯一的,结果存在符号二义性。
    def factor(self):
        """将照相机矩阵分解为K、R、t,其中,P=K[R|t]"""

        # 分解前3*3的部分
        K, R = linalg.rq(self.P[:, : 3])

        # 将K的对角线元素设为正值
        T = np.diag(np.sign(np.diag(K)))
        if linalg.det(T) < 0:
            T[1, 1] *= -1
        self.K = np.dot(K, T)
        self.R = np.dot(T, R)  # T的逆矩阵为其自身
        self.t = np.dot(linalg.inv(self.K), self.P[:, 3])

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

    # 计算照相机的中心
    def center(self):
        """计算并返回照相机的中心"""

        if self.c is not None:
            return self.c
        else:
            # 通过因子分解计算c
            self.factor()
            self.c = -np.dot(self.R.T, self.t)
            return self.c

    我们使用牛津多视图数据集中的“Model Housing”数据集,可以从https://www.robots.ox.ac.uk/~vgg/data/dunster/3D.tar.gz下载,下载完成后将需要使用的house.p3d复制到项目中即可。
    为了研究照相机的移动会如何改变投影的效果,可以使用rotation_matrix()函数创建一个向量进行三维旋转的旋转矩阵。

测试代码:

from Camera import *
from pylab import *
from numpy import *

points = loadtxt('house.p3d').T
points = vstack((points, ones(points.shape[1])))

# 设置相机参数
P = hstack((eye(3), array([[0], [0], [-10]])))
cam = Camera(P)
x = cam.project(points)
# 创建变换
r = 0.05 * random.random(3)
rot = Camera.rotation_matrix(r)

"""
# 绘制投影
figure()
plot(x[0], x[1], 'k.')
axis('off')
show()
"""

# 旋转矩阵和投影
figure()
for t in range(20):
    cam.P = dot(cam.P, rot)
    x = cam.project(points)
    plot(x[0], x[1], 'k.')
show()

结果:



分析:
    图像依次为样本图像、图像视图中投影后的点、照相机旋转后投影点的轨迹。多运行代码几次,进行不同的随机旋转之后,对点在投影中如何旋转有一些感觉。
    在实验过程中,产生了如下图所示的错误:

    搜索发现linalg模块不只在scipy中包含,同样也在numpy中包含。而我对scipy和numpy的调用方式如下如所示:

    不过scipy中的linalg包括了numpy的线性代数求解模块,而且expm函数是scipy中特有的,因此在调用linalg最好用scipy中的。因此将调用方式改为:

    这样对numpy中的模块单独调用,此时linalg即为scipy中的模块。

4.1.3照相机矩阵的分解

    如果给定如方程 P = K [ R ∣ t ] P=K\\left [ R\\mid t \\right ] P=K[Rt]所示的照相机矩阵 P P P,我们需要恢复内参数 K K K以及照相机的位置 t t t和姿势 R R R,将矩阵分块操作称为因子分解。这里我们将使用 R Q RQ RQ因子分解。
测试代码:

from Camera import *
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(dot(K, Rt))
print(K, Rt)
print(cam.factor())

结果:

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

4.1.4计算照相机中心

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

读书笔记iOS-照相机与摄像头

一,增强现实

增强现实(AR)是一种实时地计算摄影机影像的位置及角度并加上相应图像的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。这种技术估计由1990年提出。随着随身电子产品运算能力的提升,预期增强现实的用途将会越来越广。

二,视频捕获

捕获视频的方法有两个,一个方法是录制视频保存到设备中,方便以后观看和分享给其他人;另一个方法是只是捕获视频数据流,不保存文件,使用它来开发一些增强现实的应用或游戏。

 

以上是关于照相机模型与增强现实的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV-Python实战(12)——一文详解AR增强现实

AR增强现实技术需要啥专业的知识

Augment Reality(AR)现实增强的原理

读书笔记iOS-照相机与摄像头

AR Sandbox:增强现实与互动沙盘结合,让自然科学更有趣

AR增强现实实景导航