Python计算机视觉——第四章 照相机模型与增强现实

引言

为了处理三维图像和平面图像之间的映射,需要在映射中加入照相机产生图像的投影过程,我们将讨论如何确定照相机的参数,以及在增强现实(AR)等方面的具体应用。

4.1 针孔照相机模型

针孔照相机模型(射影照相机模型),在光线投影到图像平面之前,从照相机中心C经过(唯一一个点),模型如下图。

图像坐标轴和三维坐标系中的x轴、y轴对齐平行,光学坐标轴和z轴一致,在投影之前通过旋转和平移变换,在坐标系中加入三维点,会出现完整的投影变换。

针孔照相机中,三维点X投影为图像点x(齐次坐标表示),也就是把一个三维立体图形投影为二维图像,关系可由如下:λx=PX

P为(3,4)的投影矩阵,图像点的系数为逆深度,x=[X,Y,Z,W] (齐次坐标系),根据矩阵运算,行向量应为4。

4.1.1 投影矩阵

投影矩阵可分解为:

P=K[R∣t]

R为旋转矩阵,t为三维平移向量,内标定矩阵K描述照相机的投影性质,大多数情况下,K可表示为:

f是图像平面和C点的距离,即焦距,另一个参数是光心c = [ c x , c y ] ,是z轴和图像平面的交点(在二维平面上),常接近于图像宽度和高度的一半,唯一未知的变量是焦距。

4.1.2 三维点的投影

根据三维点和图像点的关系,及三维投影的定义,可以写出投影的函数。

#导入线性代数部分
from scipy import linalg


class Camera(object):
    """ Class for representing pin-hole cameras. """
    
    def __init__(self,P):
        """ Initialize P = K[R|t] camera model. """
        self.P = P
        # 标定矩阵
        self.K = None # calibration matrix
        self.R = None # rotation
        self.t = None # translation
        # 照相机中心
        self.c = None # camera center
        
    
    def project(self,X):
        """    Project points in X (4*n array) and normalize coordinates. """
        
        #定义和坐标归一化 
        # (3,n)
        x = dot(self.P,X)
        for i in range(3):
            x[i] /= x[2]    
        return x
        

 下载三维几何图像文件,来源于牛津大学的‘Model House’

import camera
# 载入点
points = loadtxt('house.p3d').T
points = vstack((points,ones(points.shape[1])))
# 设置照相机参数
# eye(3)是三阶单位矩阵
P = hstack((eye(3),array([[0],[0],[-10]])))
# 使用类Camera
cam = camera.Camera(P)
# 投影点
x = cam.project(points)
# 绘制投影
figure()
plot(x[0],x[1],'k.')
axis('off')
show()

 

 制作围绕的三维向量,模拟旋转的投影

# 研究相机的移动如何影响投影的效果
# 获得三个随机数
r = 0.05*random.rand(3)
#创建围绕一个向量进行三维旋转的旋转矩阵
rot = camera.rotation_matrix(r)
# 旋转矩阵和投影
figure()
for t in range(20):
    # 可见增减投影是在K的基础上点积
    cam.P = dot(cam.P,rot) 
    x = cam.project(points)
    plot(x[0],x[1],'k.')

show()

rotation_matrix:

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

 4.1.3 照相机矩阵的分解

如已给定照相机矩阵P,我们需要恢复内参数K以及照相机位置t和姿势R。这里使用RQ因子分解矩阵。

def factor(self):
        """    Factorize the camera matrix into K,R,t as P = K[R|t]. """
        
        # 分解前(3,3)
        K,R = linalg.rq(self.P[:,:3])
        
        # make K 对角为正值
        T = diag(sign(diag(K)))
        if linalg.det(T) < 0:
            T[1,1] *= -1
        
        self.K = dot(K,T)
        # 令R为正定矩阵
        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
        
import camera
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())

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值