欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

计算机视觉摄像机定标中投影矩阵的计算(2):特征向量法

程序员文章站 2024-03-25 08:13:28
...

简介

摄像机标定(Camera calibration)中存在的一个关键问题:如何求解投影矩阵
有了投影矩阵,我们便可以把世界坐标系变化到图像坐标系。
本文主要通过特征向量法来求解投影矩阵。

投影矩阵的代码实现

已知条件

n个三维世界坐标点(保存在dat文件中)
n个二维图像坐标点(保存在dat文件中)
使用工具:
环境:windows10+python3.7+pycharm2019
第三方库:numpy
原理见论文链接:(https://wenku.baidu.com/view/db2774d083d049649b66588e.html)

代码实现

1. 读取dat文件
其中文件每一行都是一个三维坐标或二维坐标,因此按行读取,按列存储

# 三维
x3, y3, z3 = [], [], []
with open("data_3.dat") as f:
    for line in f:
        tmp3 = line.split()
        if tmp3:  # 防止文件空行
            x3.append(float(tmp3[0]))
            y3.append(float(tmp3[1]))
            z3.append(float(tmp3[2]))


# 二维
x2, y2 = [], []
with open("data_2.dat") as f:
    for line in f:
        tmp2 = ine.split()
        if tmp2:
            x2.append(float(tmp2[0]))
            y2.append(float(tmp2[1]))

2. 表示矩阵A(矩阵A见论文,大小为2n*12)

# 表示矩阵A(下面的k即为矩阵A)
k = np.zeros((len(x3)*2, 12), dtype=int)
for i in range(len(x3)):
    k[2 * i][0], k[2 * i][1], k[2 * i][2], k[2 * i][3] = x3[i], y3[i], z3[i], 1
    k[2 * i][4], k[2 * i][5], k[2 * i][6], k[2 * i][7] = 0, 0, 0, 0
    k[2 * i][8], k[2 * i][9], k[2 * i][10], k[2 * i][11] = -x2[i]*x3[i], -x2[i]*y3[i], -x2[i]*z3[i], -x2[i]
    k[2 * i + 1][0], k[2 * i + 1][1], k[2 * i + 1][2], k[2 * i + 1][3] = 0, 0, 0, 0
    k[2 * i + 1][4], k[2 * i + 1][5], k[2 * i + 1][6], k[2 * i + 1][7] = x3[i], y3[i], z3[i], 1
    k[2 * i + 1][8], k[2 * i + 1][9], k[2 * i + 1][10],  k[2 * i + 1][11] \
        = -y2[i] * x3[i], -y2[i] * y3[i], -y2[i] * z3[i], -y2[i]

3.计算ATA的特征值与特征向量:

# 计算ATA的特征值与特征向量
eigenvalue, featurevector = np.linalg.eig(np.matmul(k.T, k))

4.获得最小特征值的索引:

index = np.argmin(eigenvalue)

5. 获取最小特征值对应的特征向量并转换成3*4投影矩阵

m_matrix = featurevector[:, index].reshape(3, 4)

6. m(3, 4)元素归一化
由于此时得到的特征向量中的m(3, 4)并不为1,参考另一篇博文得知m(3, 4)元素值为1,因此,将m(3, 4)元素归一化(对投影矩阵操作)
另一篇博文链接:(https://blog.csdn.net/qq_41813454/article/details/105364003)

m_matrix = m_matrix / m_matrix[-1, -1]

7. 验证投影矩阵m是否正确
方法:将投影矩阵与某一个三维世界坐标进行矩阵乘法运算,看看结果是否得到对应的二维图像坐标,若是,则得到正确的投影矩阵m。
由于每个人的坐标数据不一样,因此这一步可自行编写相关代码进行验证。

谢谢大家!