COLMAP中将旋转矩阵转为四元数的实现

这篇具有很好参考价值的文章主要介绍了COLMAP中将旋转矩阵转为四元数的实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

      instant-ngp中执行scripts/colmap2nerf.py时,在colmap_text目录下会生成cameras.txt、images.txt、points3D.txt三个文件:

      1.cameras.txt:

      (1).该文件包含数据集中所有重构相机(all reconstructed cameras)的内在参数(intrinsic parameters),每个相机占用一行;

      (2).参数的长度是可变的,依赖于相机型号(camera model),如OPENCV、PINHOLE;

      (3).每行内容依次为:CAMERA_ID, MODEL, WIDTH, HEIGHT, PARAMS[];

      2.images.txt:

      (1).该文件包含数据集中所有重建图像(reconstructed images)的位姿和关键点(pose and keypoints),每幅图像占用两行;

      (2).每两行定义一幅图像的信息:

IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME
POINTS2D[] as (X, Y, POINT3D_ID)

      (3).利用四元数(QW, QX, QY, QZ)和平移向量(TX, TY, TZ),将图像的重构位姿(reconstructed pose)指定为图像从世界到相机坐标系的投影。四元数(quaternion)是使用Hamilton约定来定义的;

      (4).关键点的位置以像素坐标指定:若3D点标识符(3D point identifier)为-1,则表明此关键点在重建中没有观察(observe)到3D点;

      3.points3D.txt:

      (1).该文件包含数据集中所有重建的3D点的信息,每个点使用一行

POINT3D_ID, X, Y, Z, R, G, B, ERROR, TRACK[] as (IMAGE_ID, POINT2D_IDX)

      在https://blog.csdn.net/fengbingchun/article/details/130667646 中介绍过已知cameras.txt和images.txt进行3D模型重建的过程,这里介绍下已知相机内外参如何生成cameras.txt和images.txt。

      相机内外参格式如下所示:每个相机的内外参存在于txt文件中:前三行为内参,后三行为外参

8242.163473484103 0 2576.928611903816 0
0 8242.163473484103 1733.503691370957 0
0 0 1 0
2.044289726145588e-004 -0.2587487517264626 -0.9659446369688031 27.59432346095996
-0.9993063898830017 -3.602307923217642e-002 9.438056030485108e-003 -0.6400803719560595
-3.723838540803551e-002 0.9652727185840433 -0.2585766451355823 35.62807466319453

      以下为测试代码:

import os
from inspect import currentframe, getframeinfo
import numpy as np
from pyquaternion import Quaternion

def get_dir_list(path):
    dir_list = []
    txt_list = []

    for x in os.listdir(path):
        if x.startswith("N") and x.endswith(".txt"): # it starts with N and ends with .txt
            dir_list.append(path+"/"+x)
            txt_list.append(x)

    return dir_list, txt_list

def parse_txt(txt_name):
    with open(os.path.join(txt_name), "r") as f:
        elements = [] # 6*4

        for line in f:
            if line[0] == "#":
                continue

            tmp = []
            for v in line.split(" "):
                tmp.append(v.replace("\n", "")) # remove line breaks(\n) at the end of the line
            ret = [float(ele) for ele in tmp] # str to float
            if len(ret) != 4:
                print(f"Error: the number of cols that are not supported:{len(ret)}, LINE: {getframeinfo(currentframe()).lineno}")
                raise
    
            elements.append(ret)

        if len(elements) != 6:
            print(f"Error: the number of rows that are not supported:{len(elements)}, LINE: {getframeinfo(currentframe()).lineno}")
            raise

    return elements

def get_number(name):
    pos = 0
    for index in name:
        if index.isnumeric():
            break
        pos = pos + 1

    number = int(name[pos:])
    #print(f"number:{number}")

    return number

def get_image_id_and_name(txt_name, image_suffix):
    pos = txt_name.rfind("/")
    name = txt_name[pos+1:]
    image_name = name.replace("txt", image_suffix)
    #print(f"image name: {image_name}; name: {name}")

    image_id = str(name[0:-4]) # remove: .txt
    #image_id = str(name[0:-8]) # remove: _KRT.txt
    #print(f"image id: {image_id}")
    image_id = get_number(image_id)

    return image_id, image_name

def generate_cameras_txt(dir_list, cameras_txt_name, images_number, image_size, image_suffix, camera_model):
    f = open(cameras_txt_name, "w")
    f.write("# Camera list with one line of data per camera:\r")
    f.write("#   CAMERA_ID, MODEL, WIDTH, HEIGHT, PARAMS[]\r")
    f.write("# Number of cameras: %d\r" % images_number)

    for x in dir_list:
        elements = parse_txt(x)
        #print(f"{x} elements:\n\t{elements}")

        image_id, image_name = get_image_id_and_name(x, image_suffix)
        #print(f"id:{image_id},name:{image_name}")

        string = str(image_id) + " " + camera_model + " " + str(image_size[0]) + " " + str(image_size[1])
        string = string + " " + str(elements[0][0]) + " " + str(elements[1][1]) + " " + str(elements[0][2]) + " " + str(elements[1][2]) + "\r"
        f.write(string)

    f.close()

def get_rotate_matrix(elements):
    R = [[elements[3][0], elements[3][1], elements[3][2]],
         [elements[4][0], elements[4][1], elements[4][2]],
         [elements[5][0], elements[5][1], elements[5][2]]]
    #print(f"R:\r{R}")

    return np.array(R)

def calculate_quaternion(elements):
    m = get_rotate_matrix(elements)
    # reference: https://github.com/colmap/colmap/issues/434
    m = m.transpose()

    return Quaternion(matrix=m), m

def generate_images_txt(dir_list, images_txt_name, images_number, image_suffix):
    f = open(images_txt_name, "w")
    f.write("# Image list with two lines of data per image:\r")
    f.write("#   IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME\r")
    f.write("#   POINTS2D[] as (X, Y, POINT3D_ID)\r")
    f.write("# Number of images: %d, mean observations per image:\r" % images_number)

    for x in dir_list:
        elements = parse_txt(x)
        quaternion, m = calculate_quaternion(elements)
        #print(f"quaternion:\r\t{quaternion}")
        
        T = np.array([[elements[3][3]], [elements[4][3]], [elements[5][3]]])
        # reference: https://github.com/colmap/colmap/issues/434
        T = np.matmul((-m), T) # 3*1

        image_id, image_name = get_image_id_and_name(x, image_suffix)

        string = str(image_id) + " " + str(quaternion[0]) + " " + str(quaternion[1]) + " " + str(quaternion[2]) + " " + str(quaternion[3]) + " "
        string = string + str(T[0][0]) + " " + str(T[1][0]) + " " + str(T[2][0]) + " " + str(image_id) + " " + str(image_name) + "\r\n"
        f.write(string)

    f.close()

if __name__ == "__main__":
    dir_list, txt_list = get_dir_list("test_data/txt")
    #print(f"dir_list:\n\t{dir_list}\ntxt_list:\n\t{txt_list}")

    cameras_txt_name = "test_data/txt/cameras.txt"
    images_number = 118
    image_size = [5184, 3456] # width, height
    image_suffix = "PNG"
    camera_model = "PINHOLE"
    generate_cameras_txt(dir_list, cameras_txt_name, images_number, image_size, image_suffix, camera_model)
    
    images_txt_name = "test_data/txt/images.txt"
    generate_images_txt(dir_list, images_txt_name, images_number, image_suffix)

    print("test finish")

      注意:

      (1).旋转矩阵转四元数调用的是pyquaternion模块的接口;

      (2).参考https://github.com/colmap/colmap/issues/434 中的说明,不能直接进行转换,旋转矩阵R需要使用transpose(R),平移向量T需要使用-transpose(R) * T。

      生成的cameras.txt内容如下:

# Camera list with one line of data per camera:
#   CAMERA_ID, MODEL, WIDTH, HEIGHT, PARAMS[]
# Number of cameras: 118
1 PINHOLE 5184 3456 8242.163473484103 8242.163473484103 2576.928611903816 1733.503691370957
2 PINHOLE 5184 3456 8131.912069111961 8131.912069111961 2556.374127401603 1752.782750899889

      生成的images.txt内容如下:

# Image list with two lines of data per image:
#   IMAGE_ID, QW, QX, QY, QZ, TX, TY, TZ, CAMERA_ID, NAME
#   POINTS2D[] as (X, Y, POINT3D_ID)
# Number of images: 118, mean observations per image:
1 -0.42000140017768267 0.5689473071692082 -0.5527994973158874 -0.44080664840834116 0.6814544907248062 -27.273869403751362 35.87321789136011 1 N001.PNG

2 0.49895054847423237 -0.5018861154245287 0.48563874859151474 0.5131409973757768 0.6946838348090978 -27.127815150960185 29.108370323558272 2 N002.PNG

      GitHub:https://github.com/fengbingchun/Python_Test文章来源地址https://www.toymoban.com/news/detail-466224.html

到了这里,关于COLMAP中将旋转矩阵转为四元数的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 四元数,旋转矩阵,欧拉角互转(python)

    运行代码之前需要安装pyquaternion和scipy。 pip install pyquaternion pip install scipy 代码之前放下面,main函数有使用的方式

    2024年02月12日
    浏览(30)
  • 四元数,欧拉角和旋转矩阵相互转换

    打印输出: 在线转换网站:1、三维在线旋转变换网站 https://www.andre-gaschler.com/rotationconverter/ 2、 Rotation Conversion Tool https://danceswithcode.net/engineeringnotes/quaternions/conversion_tool.html 3、角度、弧度在线转换工具 https://www.osgeo.cn/app/sc210 参考链接:https://www.jianshu.com/p/4fda4c34b829 https://

    2024年02月14日
    浏览(29)
  • 欧拉角,轴角,四元数与旋转矩阵详解

    入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。 目录 一、欧拉角 1、静态定义 2、欧拉角的表示  3、欧拉角表示的优缺点  4、欧拉角的万向节死锁(静态不存在万向锁的问题) 二、四元数 1、提出意义和定

    2024年01月17日
    浏览(32)
  • 【Eigen库使用】角轴、旋转矩阵、欧拉角、四元数转换

    在slam中经常用到的四种描述机器人orientation的变量,他们之间可以相互转化,使用Eigen库可以很容易的做到这一点, 需要特别关注的是:欧拉角与其余量之间的转换关系 : 1)首先要明确的是, 必须要明确欧拉角的旋转次序 ,你可以选择RPY、YPR等方式,在相同的orientation下,

    2024年01月18日
    浏览(35)
  • 【数理知识】三维空间旋转矩阵的欧拉角表示法,四元数表示法,两者之间的转换,Matlab 代码实现

    序号 内容 1 【数理知识】自由度 degree of freedom 及自由度的计算方法 2 【数理知识】刚体 rigid body 及刚体的运动 3 【数理知识】刚体基本运动,平动,转动 4 【数理知识】向量数乘,内积,外积,matlab代码实现 5 【数理知识】最小二乘法,从线性回归出发,数值举例并用最小

    2024年02月12日
    浏览(39)
  • 欧拉角,四元数和旋转矩阵互转代码【python版】

    欧拉角以 Roll、Pitch、Yaw 的顺序表示 四元数以[ q w q_w q w ​ , q x q_x q x ​ , q y q_y q y ​ , q z q_z q z ​ ]的顺序表示 代码包括了 欧拉角与四元数互转 , 旋转矩阵与四元数互转 , 欧拉角与旋转矩阵互转 ,输入参数均为 np.array 形式 代码内置了角度制和弧度制😃😃 当时因为这块

    2023年04月22日
    浏览(42)
  • 持之以恒(一)位姿转换:姿态 / 四元数 / 旋转矩阵 / 欧拉角 及 位姿矩阵

    姿态的几种表示形式, 姿态角 、 四元数 、 欧拉角 、 旋转矩阵 、 位姿矩阵 。 姿态 说明 表示形式 Eigen 姿态角 指的是机体坐标系与地理坐标系的夹角,即旋转向量 rx,ry,rz Eigen::Vector3f(Degrees) 四元数 四元素不存在万向节死锁问题、利用球面插值可以获得均匀的转速 w,x,y,z

    2024年02月15日
    浏览(42)
  • ROS系列——使用python的transforms3d、numpy库实现四元数、旋转矩阵、欧拉角、轴角等的相互转换

    pip3 install transforms3d 四元数模块在transforms3d.quaternions里,直接导入即可使用 2.1.1四元数转旋转矩阵 2.1.2 旋转矩阵转四元数 2.2.1 四元数转轴角 2.2.2 轴角转四元数 四元数模块在transforms3d.euler里,直接导入即可使用 3.1.1 固定轴欧拉角转四元数 3.1.2 四元数转固定轴欧拉角 3.2.1 固定

    2024年02月07日
    浏览(81)
  • 四元数的理解

    一共三个虚维度来描述空间,实数则在第四个维度,垂直于全部三个虚数轴 四元数可以优雅的描述并计算三维旋转 “四维右手法则” 两个复数Z和W相乘,把z当成一个函数,对w施加某种旋转和拉伸 左边的数作为一种函数,去变换右边的数 原则上将,把所有二维旋转的集合映

    2024年01月18日
    浏览(30)
  • 使用Matlab机器人工具箱完成四元数到旋转矩阵的转换,附程序

    在进行机械臂操作或写论文时,经常需要进行四元数、旋转矩阵、欧拉角等的转换。 此时,我们利用matlab里的机器人工具箱(Peter 开发)内置的函数就可完成,具体程序如下: 环境:Matlab2020b+robotics toolbox(安装方法在前几期文章里有) 此时运行matlab可得以下结果: 重要注

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包