可视化相机pose colmap形式的相机内参外参

news2025/2/2 13:13:48

目录

内参外参转换

可视化相机pose colmap形式的相机内参外参


内参外参转换

def visualize_cameras(cameras, images):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    for image_id, image_data in images.items():
        qvec = image_data['qvec']
        tvec = image_data['tvec']

        # Convert quaternion to rotation matrix
        rotation = R.from_quat(qvec).as_matrix()

        # Plot camera position
        ax.scatter(tvec[0], tvec[1], tvec[2], c='r', marker='o')

        # Plot camera orientation
        camera_direction = rotation @ np.array([0, 0, 1])
        ax.quiver(tvec[0], tvec[1], tvec[2], camera_direction[0], camera_direction[1], camera_direction[2], length=0.5, normalize=True)

    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()

这段代码用于在3D坐标系中可视化相机的位置和朝向。以下是逐行解释:

  1. 提取参数

    qvec = image_data['qvec']  # 相机的旋转四元数 (w, x, y, z 或 x, y, z, w,需确认顺序)
    tvec = image_data['tvec']  # 相机的平移向量 (x, y, z 坐标)
  2. 四元数转旋转矩阵

    rotation = R.from_quat(qvec).as_matrix()  # 将四元数转换为3x3旋转矩阵
    • 假设 R 来自 scipy.spatial.transform.Rotation

    • 需确认 qvec 的顺序是否为库预期的格式(通常 R.from_quat 接受 (x, y, z, w))。

  3. 绘制相机位置

    ax.scatter(tvec[0], tvec[1], tvec[2], c='r', marker='o')  # 在3D图中用红点标记相机位置
  4. 计算并绘制相机朝向

    camera_direction = rotation @ np.array([0, 0, 1])  # 旋转矩阵乘以Z轴单位向量,得到相机在世界坐标系中的朝向
    ax.quiver(tvec[0], tvec[1], tvec[2], 
              camera_direction[0], camera_direction[1], camera_direction[2], 
              length=0.5, normalize=True)
    • 原理:相机坐标系中默认朝向为Z轴正方向(通常指向拍摄方向),通过旋转矩阵将其转换到世界坐标系。

    • 箭头参数

      • 起点为相机位置 (tvec[0], tvec[1], tvec[2])

      • 方向向量为 camera_direction

      • length=0.5 控制箭头显示长度(实际长度可能因归一化调整)。

      • normalize=True 确保箭头方向正确,长度统一。

注意事项

  • 四元数顺序:确认 qvec 是否与 R.from_quat 兼容(SciPy需 (x, y, z, w))。

  • 坐标系定义:假设相机朝向为Z轴正方向,若实际定义相反(如OpenGL使用-Z),需调整为 [0, 0, -1]

  • 3D绘图设置:确保 ax 是3D轴(例如通过 fig.add_subplot(111, projection='3d') 创建)。

效果:在3D图中,红色圆点表示相机位置,箭头指示其拍摄方向。

可视化相机pose colmap形式的相机内参外参

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.spatial.transform import Rotation as R
def read_cameras(file_path):
    cameras = {}
    with open(file_path, 'r') as file:
        for line in file:
            if line[0] == '#':
                continue
            parts = line.strip().split()
            camera_id = int(parts[0])
            model = parts[1]
            width = int(parts[2])
            height = int(parts[3])
            params = np.array([float(p) for p in parts[4:]])
            cameras[camera_id] = {
                'model': model,
                'width': width,
                'height': height,
                'params': params
            }
    return cameras

def read_images(file_path):
    images = {}
    with open(file_path, 'r') as file:
        for line in file:
            if line[0] == '#':
                continue
            parts = line.strip().split()
            if len(parts) == 15:
                continue
            image_id = int(parts[0])
            qvec = np.array([float(p) for p in parts[1:5]])
            tvec = np.array([float(p) for p in parts[5:8]])
            camera_id = int(parts[8])
            file_name = parts[9]
            images[image_id] = {
                'qvec': qvec,
                'tvec': tvec,
                'camera_id': camera_id,
                'file_name': file_name
            }
    return images

def visualize_cameras(cameras, images):
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    for image_id, image_data in images.items():
        qvec = image_data['qvec']
        tvec = image_data['tvec']

        # Convert quaternion to rotation matrix
        rotation = R.from_quat(qvec).as_matrix()

        # Plot camera position
        ax.scatter(tvec[0], tvec[1], tvec[2], c='r', marker='o')

        # Plot camera orientation
        camera_direction = rotation @ np.array([0, 0, 1])
        ax.quiver(tvec[0], tvec[1], tvec[2], camera_direction[0], camera_direction[1], camera_direction[2], length=0.5, normalize=True)

    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    plt.show()

# 示例使用
cameras = read_cameras('./cameras.txt')
images = read_images('./images.txt')
visualize_cameras(cameras, images)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2289788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库内存与Buffer Pool

数据库内存与Buffer Pool 文章目录 数据库内存与Buffer Pool一:MySQL内存结构1:MySQL工作组件2:工作线程的本地内存3:共享内存区域4:存储引擎缓冲区 二:InnoDB的核心:Buffer Pool1:数…

程序员学英文之At the Airport Customs

Dialogue-1 Making Airline Reservation预定机票 My cousin works for Xiamen Airlines. 我表哥在厦航上班。I’d like to book an air ticket. 我想预定一张机票。Don’t judge a book by its cover. 不要以貌取人。I’d like to book / re-serve a table for 10. 我想预定一…

Redis代金卷(优惠卷)秒杀案例-单应用版

优惠卷表:优惠卷基本信息,优惠金额,使用规则 包含普通优惠卷和特价优惠卷(秒杀卷) 优惠卷的库存表:优惠卷的库存,开始抢购时间,结束抢购时间.只有特价优惠卷(秒杀卷)才需要填写这些信息 优惠卷订单表 卷的表里已经有一条普通优惠卷记录 下面首先新增一条秒杀优惠卷记录 { &quo…

51单片机 01 LED

一、点亮一个LED 在STC-ISP中单片机型号选择 STC89C52RC/LE52RC;如果没有找到hex文件(在objects文件夹下),在keil中options for target-output- 勾选 create hex file。 如果要修改编程 :重新编译-下载/编程-单片机重…

MusicFree-开源的第三方音乐在线播放和下载工具, 支持歌单导入[对标落雪音乐]

MusicFree 链接:https://pan.xunlei.com/s/VOI0RrVLTTWE9kkpt0U7ofGBA1?pwd4ei6#

消息队列篇--原理篇--常见消息队列总结(RabbitMQ,Kafka,ActiveMQ,RocketMQ,Pulsar)

1、RabbitMQ 特点: AMQP协议:RabbitMQ是基于AMQP(高级消息队列协议)构建的,支持多种消息传递模式,如发布/订阅、路由、RPC等。多语言支持:支持多种编程语言的客户端库,包括Java、P…

nacos 配置管理、 配置热更新、 动态路由

文章目录 配置管理引入jar包添加 bootstrap.yaml 文件配置在application.yaml 中添加自定义信息nacos 配置信息 配置热更新采用第一种配置根据服务名确定配置文件根据后缀确定配置文件 动态路由DynamicRouteLoaderNacosConfigManagerRouteDefinitionWriter 路由配置 配置管理 …

(笔记+作业)书生大模型实战营春节卷王班---L0G2000 Python 基础知识

学员闯关手册:https://aicarrier.feishu.cn/wiki/QtJnweAW1iFl8LkoMKGcsUS9nld 课程视频:https://www.bilibili.com/video/BV13U1VYmEUr/ 课程文档:https://github.com/InternLM/Tutorial/tree/camp4/docs/L0/Python 关卡作业:htt…

SpringBoot中Excel表的导入、导出功能的实现

文章目录 一、easyExcel简介二、Excel表的导出2.1 添加 Maven 依赖2.2 创建导出数据的实体类4. 编写导出接口5. 前端代码6. 实现效果 三、excel表的导出1. Excel表导入的整体流程1.1 配置文件存储路径 2. 前端实现2.1 文件上传组件 2.2 文件上传逻辑3. 后端实现3.1 文件上传接口…

动态规划DP 背包问题 完全背包问题(题目分析+C++完整代码)

概览检索 动态规划DP 概览(点击链接跳转) 动态规划DP 背包问题 概览(点击链接跳转) 完全背包问题 原题链接 AcWiing 3. 完全背包问题 题目描述 有 N种物品和一个容量是 V的背包,每种物品都有无限件可用。 第 i种物…

【cocos creator】【模拟经营】餐厅经营demo

下载:【cocos creator】模拟经营餐厅经营

【深度学习】softmax回归的从零开始实现

softmax回归的从零开始实现 (就像我们从零开始实现线性回归一样,)我们认为softmax回归也是重要的基础,因此(应该知道实现softmax回归的细节)。 本节我们将使用Fashion-MNIST数据集,并设置数据迭代器的批量大小为256。 import torch from IP…

【Redis】set 和 zset 类型的介绍和常用命令

1. set 1.1 介绍 set 类型和 list 不同的是,存储的元素是无序的,并且元素不允许重复,Redis 除了支持集合内的增删查改操作,还支持多个集合取交集,并集,差集 1.2 常用命令 命令 介绍 时间复杂度 sadd …

程序诗篇里的灵动笔触:指针绘就数据的梦幻蓝图<3>

大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 今天我们来对上一节做一些小补充,了解学习一下assert断言,指针的使用和传址调用…

神经网络的数据流动过程(张量的转换和输出)

文章目录 1、文本从输入到输出,经历了什么?2、数据流动过程是张量,如何知道张量表达的文本内容?3、词转为张量、张量转为词是唯一的吗?为什么?4、如何保证词张量的质量和合理性5、总结 🍃作者介…

爬取鲜花网站数据

待爬取网页: 代码: import requestsfrom lxml import etree import pandas as pdfrom lxml import html import xlwturl "https://www.haohua.com/xianhua/"header {"accept":"image/avif,image/webp,image/apng,image/sv…

vue框架技术相关概述以及前端框架整合

vue框架技术概述及前端框架整合 1 node.js 介绍:什么是node.js Node.js就是运行在服务端的JavaScript。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎。 作用 1 运行java需要安装JDK,而Node.js是JavaScript的运行环…

数据结构 树2

文章目录 前言 一,二叉搜索树的高度 二,广度优先VS深度优先 三,广度优先的代码实现 四,深度优先代码实现 五,判断是否为二叉搜索树 六,删除一个节点 七,二叉收索树的中序后续节点 总结 …

NeetCode刷题第19天(2025.1.31)

文章目录 099 Maximum Product Subarray 最大乘积子数组100 Word Break 断字101 Longest Increasing Subsequence 最长递增的子序列102 Maximum Product Subarray 最大乘积子数组103 Partition Equal Subset Sum 分区等于子集和104 Unique Paths 唯一路径105 Longest Common Su…

Google Chrome-便携增强版[解压即用]

Google Chrome-便携增强版 链接:https://pan.xunlei.com/s/VOI0OyrhUx3biEbFgJyLl-Z8A1?pwdf5qa# a 特点描述 √ 无升级、便携式、绿色免安装,即可以覆盖更新又能解压使用! √ 此增强版,支持右键解压使用 √ 加入Chrome增强…