Colmap多视角标定(内参、外参)与验证

一、Colmap安装

        Linux中直接输入命令行sudo apt install colmap即可

        输入colmap gui即可打开图形化界面 

二、标定

   2.1 准备工作

        创建工作文件夹~/calibration,其中创建images文件夹,存放有从左到右拍摄的三视角视图,分别依次为cam0.png,cam1.png,cam2.png。作者的图像内容是点云在unity中的虚拟环拍图像,故相机有相同的内参。点云素材来自:091 Aya Free 3D Model - .obj .c4d .max - Free3D

        菜单栏—File—New Project:

        ①Database栏点击New,进入创建的~/calibration文件夹里,上方输入框内输入数据库名称database,右上角选Save返回;

        ②Images栏点击Select,进入创建的~/calibration/images文件夹里,右上角点击Open返回。

        操作完点击Save。

   2.2 特征提取

        菜单栏— Processing—Feature extraction(左图):

        ①Camera model选择PINHOLE,普通相机一般是针孔相机模型,即透视投影;

        ②因为相当于是完全相同的相机拍摄的,所以对于内参fx,fy,cx,cy,勾选Shared for all Images。

        点击Extract,主界面右边就会显示特征提取Log(右图)。

                           

        2.1+2.2 等效命令行指令:colmap feature_extractor --database_path calibration/database.db --image_path calibration/images --ImageReader.single_camera 1 --ImageReader.camera_model PINHOLE

   2.3 特征匹配

         菜单栏— Processing—Feature matching(左图):直接点击Run就行,主界面右侧继续输出Log(右图)。

        

        等效命令行指令:colmap exhaustive_matcher --database_path calibration/database.db

   2.4 稀疏重建

        菜单栏—Reconstruction—Automatic reconstruction(左图):

        ①和一开始类似,上面两个文件夹分别选择~/calibration和~/calibration/images文件夹;

        ②因为是相同的相机,中间勾选Shared intrinsics。

        点击Run,弹出的对话框选OK,主界面右侧继续输出Log(右图)。主界面通过鼠标操作,可以看到三个相机的相对位置。还有一些极其稀疏的点云,得相机比较多,才能看得出目标轮廓。

     

        等效命令行指令:colmap automatic_reconstructor  --workspace_path calibration --image_path calibration/images --single_camera 1

   2.5 结果处理

        上述操作完成,可以发现出现了~/calibration/sparse/0文件夹,里面有一些bin文件:

        

        通过命令行指令将这些bin文件转换为txt文件:

        colmap model_converter --input_path calibration/sparse/0 --output_path calibration/sparse/0 --output_type TXT

        ①cameras.txt里面保存了内参信息:

        相机序号:1        相机模型:PINHOLE        图像分辨率:512x512

        内参矩阵里的参数:fx=372.xxx  fy=1094.xxx   cx=256   cy=256

        ②images.txt里的偶数行保存了外参信息,Ctrl+F搜索图片名称可以看到:

        图像序号:1  旋转四元数(后面【第三部分】使用一些函数转换成外参中的旋转矩阵R):

QW= 0.993xxx  QX= 0.000xxx  QY=-0.116xxx QZ=0.000xxx  

平移向量T的三个参数:Tx=4.886xxx  Ty=0.012xxx  Tz=0.963xxx

三、结果验证

        节选并修改了一段github上的代码,python环境需要pip install numpy、python-opencv和transforms3d包,可针对其中两张图片,作为左、右视图进行双视角对极几何验证,将得到的内、外参粘贴到下述camera_k、left_ext_params和right_ext_params矩阵/数组里。

#caliVerify.py
import cv2
import numpy as np
from numpy.linalg import inv
import transforms3d as t3d

left_image = cv2.imread("cam0.png")
right_image = cv2.imread("cam1.png")

left_ext_params=[0.99323752127112763, 0.00048400511993752782, \
    -0.11609558712727755, 0.00089818027310631496,\
    4.8869005188993357, 0.012992987731095574, 0.96380285804213284]
left_pose=np.zeros([4,4])
left_pose[:3,:3]=t3d.quaternions.quat2mat(left_ext_params[:4])
left_pose[:3,3]=left_ext_params[4:]
left_pose[3,3]=1

right_ext_params=[0.99999870258601886, -0.00020446045335147645, \
    -0.0015852453856825995, 0.00020004816728340241,\
    0.028774206458871632, -0.018549169482988754, 0.36068280018336535]
right_pose=np.zeros([4,4])
right_pose[:3,:3]=t3d.quaternions.quat2mat(right_ext_params[:4])
right_pose[:3,3]=right_ext_params[4:]
right_pose[3,3]=1

camera_k = np.asarray([ [372.38171888682245, 0, 256],
                        [0, 1094.9517220661564, 256],
                        [0, 0, 1]]) 

# test the epipolar line
left2right = np.dot(inv(right_pose), left_pose)
test_point = np.asarray([left_image.shape[1] //2, left_image.shape[0] *9 //10, 1])
far_point = np.dot(inv(camera_k), test_point) * 50.0
far_point = np.append(far_point, 1)
far_point = np.dot(left2right, far_point)
far_pixel = np.dot(camera_k, far_point[0:3])
far_pixel = (far_pixel / far_pixel[2])[0:2]
near_point = np.dot(inv(camera_k), test_point) * 0.1
near_point = np.append(near_point, 1)
near_point = np.dot(left2right, near_point)
near_pixel = np.dot(camera_k, near_point[0:3])
near_pixel = (near_pixel / near_pixel[2])[0:2]
cv2.line(right_image, 
        (int(far_pixel[0] + 0.5), int(far_pixel[1] + 0.5)),
        (int(near_pixel[0] + 0.5), int(near_pixel[1] + 0.5)), [0,0,255], 4)
cv2.circle(left_image,(int(test_point[0]), int(test_point[1])), 4, [0,0,255], -1)


result_image = np.concatenate((left_image, right_image), axis=1)
cv2.imshow("result", result_image)
cv2.waitKey(0)

​

        显示结果中,左图中的红点所示内容在右图中要被红线穿过,标定才较为准确。可以更改代码中的test_point位置,多试几次。

  

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值