OpenCV从3D-2D 点对应中查找对象姿势solvePnP

news2025/1/12 19:06:11

1.概述:

在使用相机拍照片时,大多数人会考虑拍的好不好看,关注相机中物体坐标的并不多,但是对于地信学科来说,如果能从照片中获取物体的真实位置,对地理信息获取大有帮助,在这里面,十分关键的一步就是相机标定。

相机标定的基本原理也是相对简单的,看官网中的一个示意图,很容易发现,物点P(Xw,Yw,Zw),像点(u,v)和相机点三点在同一条线上(红线),如果知道多对物点和像点,画出他们的连线,找到的焦点就是相机的位置,同时还可以根据这些线的走向解算相机的旋转角,旋转角和坐标偏移共同构成了相机的外参。(实际上,这里的像点并不是照片中物体的坐标,而是相机中感光片上的坐标,他们的转化需要一定的几何变化)

2.基本假设

影响上面相机外参精度的变量有很多,例如镜头畸变,像主点跟感光片的相对位置等等,这些可以归纳为相机的内参。

在此仅使用OpenCV-Python中的函数做一个小实验,拍摄工具是手机,所以也不方便找到这些参数,因此不考虑内参的影响,假设相机内参是完美的,即没有畸变和偏移。

所以它的内参矩阵可以假设为下面的样子,27是我手机拍照时显示的焦距,单位mm,8.17是用宽度的像素个数除以照片宽度得到的,也就是1mm有多少像素:

假设没有畸变,因此畸变参数全部设置为0

参考了这个文章;

https://blog.csdn.net/weixin_44671418/article/details/109386911

3.坐标获取

基于上面的假设,问题就简单多了,需要的数据只有物点坐标,像点坐标,在这里拍摄了一个照片,用来提供上面的数据,A4纸上画的是X轴和Y轴,电脑屏幕的棋盘作为Z轴刻度,电脑屏幕棋盘的第一条线距离桌面8.5cm。

下面的代码可帮助获取屏幕坐标,在输入真实坐标后,保存这些坐标

import numpy as np
import cv2 as cv
import glob
#定义两个列表,realcoo存储真实坐标,imacoo存储相片坐标
imacoo=[]
realcoo=[]
#OpenCV点击相片的事件相应函数,左键双击提示输入三维坐标,右键双击保存输入的点为numpy的一种文件格式,便于后续使用
def GetCoordinate(event,x,y,flags,param):
    #event判断事件类型,右键双击保存为cooimfoText.npz文件
    if event == cv.EVENT_RBUTTONDBLCLK:
        np.savez('cooimfoText.npz', imacoo=imacoo, realcoo=realcoo)
    #如果是左键双击,就键入物体的真实坐标
    if event == cv.EVENT_LBUTTONDBLCLK:
        print(x,y)
        strcoo = input("请输入三维坐标,以逗号隔开")
        coo = strcoo.split(',')
        realcoo.append((float(coo[0]), float(coo[1]), float(coo[2])))
        imacoo.append((x,y))
#打开图像
img = cv.imread("IMG_20221028_151422.jpg")
width,height=img.shape[:2]
#由于手机分辨率太高了,电脑屏幕显示不下,所以缩放一下
imgresize = cv.resize(img,(int(0.2*height), int(0.2*width)), interpolation = cv.INTER_CUBIC)
#窗口命名
cv.namedWindow('room')
#事件绑定
cv.setMouseCallback('room',GetCoordinate)
#打开图像,开始采集点坐标
cv.imshow('room',imgresize)
key=cv.waitKey(0)

4. 外参解算

解算主要用到了OpenCV的这个函数solvePnP(),看下图它的参数,第一个就是上面的物点坐标,第二个是像点坐标,第三个是相机参数A(在上面已经做了假设),第四个是畸变参数(假设为[0,0,0,0,0]),它的返回值就是rvec:相机旋转参数,tvec相机平移参数

使用下面的代码完成解算过程

import numpy as np
import cv2 as cv
 
#根据假设,定义的相机内部参数和畸变参数
M = np.asarray([[27 * 8.17, 0, 0], [0, 27 * 8.17, 0], [0, 0, 1]], dtype=float)
C = np.asarray([0, 0, 0, 0, 0], dtype=float)
#打开刚获取到的坐标文件
with np.load('cooimfoText.npz') as X:
    imacoo = X['imacoo']
    realcoo = X['realcoo']
    #屏幕坐标转迪卡尔坐标
    for i in range(0,len(imacoo)):
        imacoo[i][1]=793-imacoo[i][1]
    #转化为浮点型
    realcoo = realcoo.astype(np.float32)
    imacoo = imacoo.astype(np.float32)
    #解算相机外参
    retval, rvec, tvec = cv.solvePnP(realcoo, imacoo,M, C)
    #打印结果
    print("解算结果:",retval)
    print("旋转角度:",rvec)
    print("偏移距离:",tvec)
 

输出结果为:

比对照片,可以大概判断结果结果基本符合实际情况,距离大致相同。

5.问题解决

问题1:solvePnP()与calibrateCamera()的异同?

calibrateCamera():从校准模式的多个视图中查找相机的内在和外在参数。

solvePnP():从 3D-2D 点对应中查找对象姿势,它需要的参数更简单,需要二维和三维对应的点,同时要输入相机的内参。

在最初的计算中,计划使用的是calibrateCamera()函数,它的介绍是从校准模式的多个视图中查找相机的内在和外在参数。在计算是,它频繁报错,后来查看官网的介绍,发现更适合使用solvePnP()计算本例。

他们需要输入的类型都是浮点型的坐标,如果输入int会报错:objectPoints should contain vector of vectors of points of type Point3f in function

问题2:相机内参矩阵矩阵对结果影响有多大?

按照经验来看,手机相机畸变参数并不大,因此假设为0也对结果影响较小,但是焦距和像主点偏移就不一定了,在完成本例时,由于开始对概念不清晰,试了多次焦距参数,略微改变都会带来很大的结果差别,因此要注意这个参数尽量精细。

https://blog.csdn.net/JJSXBL/article/details/127574206

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

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

相关文章

深入分析Linux PCI驱动框架(三)

说明: Kernel版本:4.14ARM64处理器使用工具:Source Insight 3.5, Visio 1. 概述 先回顾一下PCIe的架构图: 本文将讲PCIe Host的驱动,对应为Root Complex部分,相当于PCI的Host Bridge部分&…

Vue 总结四 (ref, mixin, 插件, 插槽, VueX)

目录 ref 混入 mixin 插件 插槽 使用插槽的情景 使用方法 VueX 使用场景 使用 state 存放共享数据 actions 操作共享数据的API mutations 操作共享数据的API 生命周期图 ref 和id的区别 对于传统标签来说没有区别 都拿到的是 html内容 对于自定义的vue 的标签…

Spring事务源码分析

1. 前言 Spring支持两种事务管理的方式:声明式事务和编程式事务。编程式事务的优点是可以在代码里控制事务的粒度,实现细粒度的事务控制,缺点是对业务代码存在侵入性,代码复杂度较高,一般很少使用。声明式事务的优点是…

Linux下的动静态库

目录 认识动静态库 如何制作动静态库? 静态库 动态库 使用库 使用静态库 使用动态库 为什么动态链接是如此呢? 认识动静态库 我们在使用标准库的时候,需要有系统的头文件和系统的库文件,这个库文件是什么呢? …

Databend 借助对象存储帮你实现降本增效

本篇文章围绕着: 什么是对象存储当 Databend 遇到对象存储2022 年 Databend 利用对象存储降本的案例国内优秀的对象存储产品基于对象存储创业的产品 什么是对象存储 对象存储是一种可以非结构化存储和管理数据的技术。 可以简单理解为 NoSQL 接口方式存储和访问数…

linux系统中使用QT实现多媒体的功能方法

大家好,今天主要和大家聊一聊,如何使用QT中的多媒体的功能。 目录 第一:多媒体基本简介 第二:应用实例实现 第三:程序运行效果 第一:多媒体基本简介 QT的多媒体模块提供了音频,视频&#xff…

分布式系统-CAP 理论

在前一篇分布式系统–拜占庭将军问题(The Byzantine Generals Problem) 我们理解了共识问题的背景,这一节主要讨论如何解决或者理解自己系统中的共识问题,通过什么来分辨自己的系统需要哪一种共识。 这个理论就是 CAP 理论,先想下面几个问题…

linux 线程详解

前言 程序运行在内存空间中叫进程,进程中包含有若干线程,线程是系统调度和执行的基本单位。线程才是程序运行的实体,通常程序里的main()函数就相当于主线程,把进程理解成一个容器,里面可以包含有若干线程和若干资源&am…

6)Mybatis启动流程

1. 首先Mybatis会加载配置文件mybatis-config.xml, 主要实现在Mybatis的builder模块,包路径org.apache.ibatis.builder,解析入口XMLConfigBuilder private void settingsElement(Properties props) {configuration.setAutoMappingBehavior(Au…

指针进阶篇(2)

进阶指针 🤔前言🤔 一、😊函数指针😊 二、😜函数指针数组😜 三 、😝指向函数指针数组的指针😝 四、🌝回调函数🌝 🍀小结🍀 &…

摩丝-题解

看到题目,怀疑是莫尔斯电码,打开发现果然是莫尔斯电码的点和划.. .-.. --- ...- . -.-- --- ..-简单说一下电报的原理最简单的电报模型就是一个电源,一个开关和一个电磁铁当需要长距离使用时候,需要用到继电器按下开关&#xff0c…

【BP靶场portswigger-服务端10】XML外部实体注入(XXE注入)-9个实验(全)

前言: 介绍: 博主:网络安全领域狂热爱好者(承诺在CSDN永久无偿分享文章)。 殊荣:CSDN网络安全领域优质创作者,2022年双十一业务安全保卫战-某厂第一名,某厂特邀数字业务安全研究员&…

C#【必备技能篇】使用NPOI实现对excel的读取和写入

文章目录1、Winform界面布局2、引用NPOI的dll3、源码4、运行效果5、NPOI的dll下载地址6、补充【以上步骤只能打开.xls文件(97-2003版本),打不开.xlsx文件(2007版本)】1、Winform界面布局 2、引用NPOI的dll 3、源码 us…

(十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置

前言 本节内容我们主要介绍一下在jenkins中如何集成sonar qube代码质量检查工具,sonar qube可以在流水化项目集成部署前对我们的代码质量检查。开始本节内容前我们需要先搭建好sonar qube服务,关于sonar qube服务的搭建可参考作者往期博客内容&#xff…

P4391 [BOI2009]Radio Transmission 无线传输

题目描述 给你一个字符串 s_1s1​,它是由某个字符串 s_2s2​ 不断自我连接形成的。但是字符串 s_2s2​ 是不确定的,现在只想知道它的最短长度是多少。 输入格式 第一行一个整数 LL,表示给出字符串的长度。 第二行给出字符串 s_1s1​ 的一个子…

【linux入门】基础知识学习笔记

文章目录【第一章-宏观知识】1.硬件和软件的关系2.操作系统 是什么、作用是什么3.常见的操作系统4.Linux的诞生5.Linux内核 是什么6.Linux发行版 是什么7.WSL是什么8.虚拟机快照9.FinalShell(Xshell替代品)【第二章-Linux基础命令】1.Linux目录结构2.什么…

Linux---权限

目录 1.文件访问者的分类(人/用户) 2.文件类型和访问权限(事物属性) 3.文件权限值的表示方法 a)字符表示方法 b)8进制数值表示方法 4.文件访问权限的相关设置方法 4.1 改属性 4.2 改人(改拥有者/所属组)…

数组常用方法总结 (3) :map / forEach / every / some

map 遍历数组的每一项。如果是简单数组,不改变原始数组(值类型)。如果是对象数组,原始数组可以被改变(引用类型)。遍历原始数组,返回值为原始数组的每一项,最终可组合成新数组。 简…

LeetCode 78 子集 | 解题思路分享

原题链接:78. 子集 - 力扣(LeetCode) 题目难度:中等 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。 解集 不能 包含重复的子集。你可以按 任…

忆享聚焦|5G投资、网络安全市场、云计算、Web3技术……近期热点资讯一览

“忆享聚焦”栏目第11期来啦!本栏目汇集近期互联网最新资讯,聚焦前沿科技,关注行业发展动态,筛选高质量讯息,拓宽用户视野,让您以最低的时间成本获取最有价值的行业资讯。目录行业资讯1. SA:全球…