相对位姿估计

news2024/11/19 17:25:02

相对位姿估计

示意图

在这里插入图片描述

理论推导

离线数据库:

P的位置 P = [ X , Y , Z ] T P=[X,Y,Z]^{T} P=[X,Y,Z]T

相机内参 k 1 k_{1} k1

安卓手机:

相机内参 k 2 k_{2} k2

两个像素点位置 p 1 和 p 2 p_1和p_2 p1p2

公式一:

s 1 p 1 = K 1 P s_1p_1=K_1P s1p1=K1P s 2 p 2 = K 2 ( R P + t ) s_2p_2=K_2(RP+t) s2p2=K2(RP+t)

**公式二:**归一化平面上的坐标

x 1 = K 1 − 1 p 1 x_1=K_1^{-1}p_1 x1=K11p1 x 2 = K 2 − 1 p 2 x_2=K_2^{-1}p2 x2=K21p2

公式三:

x 2 = R x 1 + t x_2=Rx_1+t x2=Rx1+t

公式四:

t ^ x 2 = t ^ R x 1 \hat{t}x_2=\hat{t}Rx_1 t^x2=t^Rx1

公式五

x 2 T t ^ x 2 = x 2 T t ^ R x 1 x_2^{T}\hat{t}x_2=x_2^{T}\hat{t}Rx_1 x2Tt^x2=x2Tt^Rx1

x 2 T t ^ R x 1 = 0 x_2^{T}\hat{t}Rx_1=0 x2Tt^Rx1=0

公式六:

( K 2 − 1 p 2 ) T t ^ R K 1 − 1 p 1 (K_2^{-1}p_2)^{T}\hat{t}RK_1^{-1}p_1 (K21p2)Tt^RK11p1

结论:

本质矩阵: E = t ^ R E=\hat{t}R E=t^R ---------------------已知相机参数的情况下

基础矩阵: F = K 2 − T E K 1 − 1 F=K_2^{-T}EK_1^{-1} F=K2TEK11 -----------未知相机参数的情况下

伪代码

input:image_src,k_src,image_dst,k_dst
output:R,t
1 feature_detect(image_src,image_dst)---->keypoints and deccriptors
2 feature_match(image_src,image_dst)---->matched_features
3 find_essentialmatrix(matched_keypoints,k_src,k_dst)----->essential_matrix
4 decompose_E(essentialmatrix)----->R,t
5 judge "left or right"

实现代码

import cv2
import numpy as np

def find_keypoints_and_descriptors(image):
    # 使用SIFT算法检测关键点和计算描述符
    sift = cv2.SIFT_create()
    keypoints, descriptors = sift.detectAndCompute(image, None)
    return keypoints, descriptors

def match_keypoints(descriptors1, descriptors2):
    # 使用FLANN匹配器进行关键点匹配
    FLANN_INDEX_KDTREE = 0
    index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
    search_params = dict(checks=50)
    flann = cv2.FlannBasedMatcher(index_params, search_params)
    matches = flann.knnMatch(descriptors1, descriptors2, k=2)

    # 保留良好的匹配
    good_matches = []
    for m, n in matches:
        if m.distance < 0.7 * n.distance:
            good_matches.append(m)

    return good_matches

def estimate_relative_pose(keypoints1, keypoints2, good_matches, camera_matrix_src,camera_matrix_dst):
    # 提取匹配点对应的关键点
    src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
    dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)

    # 使用基础矩阵估计相机的相对位姿
    essential_matrix, _ = cv2.findEssentialMat(src_pts, dst_pts, camera_matrix_src, camera_matrix_dst)

    # 从基础矩阵中恢复旋转和平移矩阵
    _, R, t, _ = cv2.recoverPose(essential_matrix, src_pts, dst_pts, camera_matrix_src, camera_matrix_dst)

    return R, t

def determine_camera_direction(t):
    if t[0] > 0:
        print("相机偏向右侧")
    elif t[0] < 0:
        print("相机偏向左侧")
    else:
        print("相机方向正前方")

# # 示例平移向量
# t = np.array([[1.5], [0.2], [0.3]])  # 假设平移向量 t = [1.5, 0.2, 0.3]

# determine_camera_direction(t)

def main():
    # 加载两张图片
    image1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
    image2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)

    # 假设你已知相机内参
    fx_src = 1000.0  # 举例:相机的焦距
    fy_src = 1000.0
    cx_src = 320.0  # 图像中心点的x坐标
    cy_src = 240.0  # 图像中心点的y坐标
    camera_matrix_src = np.array([[fx_src, 0, cx_src],
                              [0, fy_src, cy_src],
                              [0, 0, 1]])
    
    fx_dst = 1000.0  # 举例:相机的焦距
    fy_dst = 1000.0
    cx_dst = 320.0  # 图像中心点的x坐标
    cy_dst = 240.0  # 图像中心点的y坐标
    camera_matrix_dst = np.array([[fx_dst, 0, cx_dst],
                              [0, fy_dst, cy_dst],
                              [0, 0, 1]])

    # 检测关键点和计算描述符
    keypoints1, descriptors1 = find_keypoints_and_descriptors(image1)
    keypoints2, descriptors2 = find_keypoints_and_descriptors(image2)

    # 匹配关键点
    good_matches = match_keypoints(descriptors1, descriptors2)

    # 估计相机的相对位姿
    R, t = estimate_relative_pose(keypoints1, keypoints2, good_matches, camera_matrix_src,camera_matrix_dst)

    # 计算旋转矩阵的欧拉角
    angles = cv2.Rodrigues(R)[0]
    yaw = np.arctan2(angles[1, 0], angles[0, 0]) * 180.0 / np.pi

    # 判断相机的方向
    if yaw > 0:
        print("相机偏向右侧,您应该向左转")
    elif yaw < 0:
        print("相机偏向左侧,您应该向右转")
    else:
        print("相机方向正前方")
                
        






if __name__ == "__main__":
    main()

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

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

相关文章

java版本知识服务系统-高效知识付费Saaas平台的架构与功能模块设计

知识付费平台&#xff0c;作为我国近年来崭露头角的新型在线教育模式&#xff0c;正迅速改变着传统的学习方式。这种模式紧贴用户需求&#xff0c;将高质量的内容作为核心&#xff0c;借助互联网技术的力量&#xff0c;为用户打造了一个轻松便捷的学习环境。这些平台如同知识的…

【3.vi编辑器使用(上)】

一、vi编辑器的三种模式及切换命令 1、vi是linux中最基本的编辑器。但vi编辑器在系统管理、服务器配置工作中永远都是无可替代的。 2、vi编辑器的三种模式&#xff1a;命令行模式、插入模式、底行模式。 &#xff08;1&#xff09;命令行模式&#xff1a;用户在用vi编辑文件…

同时执行多个python脚本扫描,报如下错误,原因为文件越大读取到内存占用内存越多。

killed nohup python $file unable to fork process cannot allocate memory ls: error while loading shared libraries: libdl.so.2 failed to map segment from shared object cannot allocate memory python进程被系统或者某个用户通过 kill 命令强制终止了

vue3+electron+typescript 项目安装、打包、多平台踩坑记录

环境说明 这里的测试如果没有其他特别说明的&#xff0c;就是在win10/i7环境&#xff0c;64位&#xff0c;node 版本v16.20.2 创建项目 vite官方是直接支持创建electron项目的&#xff0c;所以&#xff0c;这里就简单很多了。我们已经不需要向开始那样自己去慢慢搭建 yarn …

【Linux】centos7编写C语言程序,补充:使用yum安装软件包组

确保已安装gcc编译器 C语言程序&#xff0c;一般使用gcc进行编译&#xff0c;需确保已安装gcc。 若没有&#xff0c;可以使用yum安装gcc&#xff08;版本4.8.5&#xff09;&#xff0c;也可以使用SCL源安装gcc&#xff08;例如&#xff1a;版本9.3&#xff09;。 安装gcc&am…

SpringMVC: 跨线程获取requests请求对象

文章目录 引言I RequestContextHolder1.1 用法1.2 跨线程获取requests请求对象II ThreadLocal2.1 采用threadLocal存储token信息,异步线程无法获取。2.2 InheritableThreadLocal解决异步线程,无法获取token信息问题。引言 异步操作的场景: 不影响业务主流程的操作(日志的记…

外企如何有效面对日益严格的跨境数据传输法律?

在当今这个数据驱动的时代&#xff0c;随着全球化步伐的加快&#xff0c;企业跨国界的数据交流已成为常态。但随之而来的&#xff0c;是各国政府对跨境数据传输日益严格的规定和监管&#xff0c;这让众多外资企业&#xff08;简称“外企”&#xff09;在享受全球市场红利的同时…

Java用反射reflect来实例化对象: class.getDeclaredConstructor().newInstance()

Java用反射reflect来实例化对象: class.getDeclaredConstructor().newInstance() 从java9开始, class.newInstance()已过时, 被加上Deprecated强烈反对注解 SuppressWarnings("removal")CallerSensitiveDeprecated(since"9")public T newInstance()throws …

探索RS与AES加密技术:从经典到现代

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、MD5加密技术&#xff1a;经典中的经典 二、非对称加密&#xff1a;RSA技术的魅力 RSA技…

运维开发.MySQL.范式与反范式化

运维开发 MySQL.三大范式 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/artic…

轻松放大图片600%,Topaz Gigapixel AI图片无损清晰放大软件下载安装

Topaz Gigapixel AI 该软件拥有卓越的性能和先进的技术&#xff0c;能够轻松实现图像的精细放大&#xff0c;最多可将图像放大至原始尺寸的六倍&#xff0c;而无需担心图像质量的损失。 相较于传统的图像放大软件&#xff0c;Topaz Gigapixel AI 表现出了明显的优势。传统软件…

学习笔记——动态路由协议——OSPF(简介)

一、 OSPF简介 1、前言 由于静态路由由网络管理员手工配置&#xff0c;因此当网络发生变化时&#xff0c;静态路由需要手动调整&#xff0c;这制约了静态路由在现网大规模的应用。 动态路由协议因其灵活性高、可靠性好、易于扩展等特点被广泛应用于现网。在动态路由协议之中…

Python保存为json中文Unicode乱码解决json.dump()

保存为json中文Unicode乱码&#xff1a; 可以看到&#xff0c;中文字符没有乱码&#xff0c;只是出现了反斜杠&#xff0c;此时解决方法应考虑是否进行了二次序列化。 一、原因1 在dump时加入ensure_asciiFalse 即可解决&#xff0c;即json.dump(json_data, f, indent4, en…

VSCode小技巧,忽略不想格式化的代码行

零&#xff0e;格式化工具文档 1 . Black Ignoring sections功能 2 . autopep8 disabling-line-by-line功能&#xff1b;&#xff1b;–line-range选项 3 . Prettier prettier-ignore功能(例&#xff1a;适用于JS的// prettier-ignore&#xff0c;适用于CSS的/* prettier-igno…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第29课-会员制展厅

【WEB前端2024】开源智体世界&#xff1a;乔布斯3D纪念馆-第29课-会员制展厅 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎&…

前端Vue小兔鲜儿电商项目实战Day02

一、Pinia快速入门 此处见&#xff1a;Vue从入门到实战Day12-CSDN博客 二、创建项目并精细化配置 1. 创建项目 2. src目录调整 ①删除一些初始化的默认文件 清空assets、components、store、views文件夹下的内容&#xff1b; ②修改剩余代码内容 router/index.js import …

常用图像分类预训练模型大小及准确度比较

近年来&#xff0c;深度学习技术的发展使得图像分类任务变得越来越容易。预训练模型的出现更是使得图像分类任务变得更加简单和高效。然而&#xff0c;随着预训练模型的数量和大小的增加&#xff0c;我们需要了解每个模型的特点和优缺点&#xff0c;以便更好地选择和使用它们。…

TalkingData数据统计

一、简介 TalkingData是一家提供移动应用数据统计和分析的公司&#xff0c;专注于移动应用数据的收集、分析和可视化。TalkingData通过收集应用程序的用户行为数据&#xff0c;如应用下载量、用户留存率、用户活跃度等&#xff0c;帮助开发者了解用户行为趋势、优化应用功能、…

甩掉接口文档烦恼!Spring Boot 集成 Knife4j,轻松玩转 API 可视化

一、引言&#xff1a;跟接口文档说拜拜 &#x1f44b; 作为一名 Java 开发者&#xff0c;你是否还在为编写繁琐的 API 文档而头疼&#xff1f;传统的手动编写方式不仅耗时费力&#xff0c;而且容易出错&#xff0c;难以维护。今天&#xff0c;我们就来介绍一款神器 Knife4j&am…

力扣:101. 对称二叉树

101. 对称二叉树 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false提示&#xff1a; …