python+opencv2相机位姿估计
最近在做基于图像的室内定位方面的研究,于是使用到了百度最新的室内数据库Image-based Localization (IBL) 。由于该数据库给出的数据是每幅图像和其对应相机的内外参数和光心投影方向,所以我需要先求出其6DOF预估姿态。再利用PoseNet网络对其实现基于图像的定位估计。好了,问题就很明确了:
(1)根据图像和激光雷达参数的3D点云实现2D-3D的匹配,找到每张图像上的至少四个特征点。即找到至少4个二维像素和3D点云点的对应点。
(2)根据这四组对应点和相机内外参数估计相机6DOF,即相机姿态。
今天先实现第二个问题。很幸运网上有这样几篇博客已经将相机位姿整个过程讲的比较清楚了http://www.cnblogs.com/singlex/p/pose_estimation_1.html。
但这篇文章是由c++写的,我在python上简单的对其进行了验证。
这是这张图给出的数据。
import cv2
import numpy as np
import math
object_3d_points = np.array(([0, 0, 0],
[0, 200, 0],
[150, 0, 0],
[150, 200, 0]), dtype=np.double)
object_2d_point = np.array(([2985, 1688],
[5081, 1690],
[2997, 2797],
[5544, 2757]), dtype=np.double)
camera_matrix = np.array(([6800.7, 0, 3065.8],
[0, 6798.1, 1667.6],
[0, 0, 1.0]), dtype=np.double)
dist_coefs = np.array([-0.189314, 0.444657, -0.00116176, 0.00164877, -2.57547], dtype=np.double)
# 求解相机位姿
found, rvec, tvec = cv2.solvePnP(object_3d_points, object_2d_point, camera_matrix, dist_coefs)
rotM = cv2.Rodrigues(rvec)[0]
camera_postion = -np.matrix(rotM).T * np.matrix(tvec)
print(camera_postion.T)
# 验证根据博客http://www.cnblogs.com/singlex/p/pose_estimation_1.html提供方法求解相机位姿
# 计算相机坐标系的三轴旋转欧拉角,旋转后可以转出世界坐标系。旋转顺序z,y,x
thetaZ = math.atan2(rotM[1, 0], rotM[0, 0])*180.0/math.pi
thetaY = math.atan2(-1.0*rotM[2, 0], math.sqrt(rotM[2, 1]**2 + rotM[2, 2]**2))*180.0/math.pi
thetaX = math.atan2(rotM[2, 1], rotM[2, 2])*180.0/math.pi
# 相机坐标系下值
x = tvec[0]
y = tvec[1]
z = tvec[2]
# 进行三次旋转
def RotateByZ(Cx, Cy, thetaZ):
rz = thetaZ*math.pi/180.0
outX = math.cos(rz)*Cx - math.sin(rz)*Cy
outY = math.sin(rz)*Cx + math.cos(rz)*Cy
return outX, outY
def RotateByY(Cx, Cz, thetaY):
ry = thetaY*math.pi/180.0
outZ = math.cos(ry)*Cz - math.sin(ry)*Cx
outX = math.sin(ry)*Cz + math.cos(ry)*Cx
return outX, outZ
def RotateByX(Cy, Cz, thetaX):
rx = thetaX*math.pi/180.0
outY = math.cos(rx)*Cy - math.sin(rx)*Cz
outZ = math.sin(rx)*Cy + math.cos(rx)*Cz
return outY, outZ
(x, y) = RotateByZ(x, y, -1.0*thetaZ)
(x, z) = RotateByY(x, z, -1.0*thetaY)
(y, z) = RotateByX(y, z, -1.0*thetaX)
Cx = x*-1
Cy = y*-1
Cz = z*-1
# 输出相机位置
print(Cx, Cy, Cz)
# 输出相机旋转角
print(thetaX, thetaY, thetaZ)
# 对第五个点进行验证
Out_matrix = np.concatenate((rotM, tvec), axis=1)
pixel = np.dot(camera_matrix, Out_matrix)
pixel1 = np.dot(pixel, np.array([0, 100, 105, 1], dtype=np.double))
pixel2 = pixel1/pixel1[2]
print(pixel2)
输出结果
[[ 528.66321122 -2.88452091 358.60341802]]
[ 528.66321122] [-2.88452091] [ 358.60341802]
178.3558701005234 56.02221316618043 88.63218026484252
[ 4.15960851e+03 6.73694373e+02 1.00000000e+00]
验证结果证明确实python代码6行就求解出了相机6DOF位姿估计,厉害!通过验证第5个点[0, 100, 105]对应像素点[4159.6, 673.69]和真实像素位置[4146, 673]相差不大。
python+opencv2相机位姿估计的更多相关文章
- 相机位姿估计1_1:OpenCV:solvePnP二次封装与性能测试
关键词:OpenCV::solvePnP 文章类型:方法封装.测试 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-27 @Lab: CvLab20 ...
- 相机位姿估计0:基本原理之如何解PNP问题
关键词:相机位姿估计 PNP问题求解 用途:各种位姿估计 文章类型:原理 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-18 @Lab: CvLa ...
- 相机位姿求解——P3P问题
1.位姿求解是计算机视觉中经常遇到的,Perspective-n-Points, PnP(P3P)提供了一种解决方案,它是一种由3D-2D的位姿求解方式,即需要已知匹配的3D点和图像2D点.目前遇到的 ...
- Python + OpenCV2 系列:1 - 配置
Python+OpenCV2+Eclipse+Windos 8.1(32bits): 最初的目的是做图像处理,opencv强大的社区支持,让我想从matlab转到opencv框架下进行试验,而Pyth ...
- 物体的三维识别与6D位姿估计:PPF系列论文介绍(三)
作者:仲夏夜之星 Date:2020-04-08 来源:物体的三维识别与6D位姿估计:PPF系列论文介绍(三) 文章“A Method for 6D Pose Estimation of Free-F ...
- cv2.solvepnp 相机的位姿估计
预备知识 图像坐标系: 理想的图像坐标系原点O1和真实的O0有一定的偏差,由此我们建立了等式(1)和(2),可以用矩阵形式(3)表示. 相机坐标系(C)和世界坐标系(W): 通过相机与图像的投 ...
- 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态
https://blog.csdn.net/kyjl888/article/details/71305149
- Python + OpenCV2 系列:3 - python 字符串,类,编码规范
首先,强烈推荐<<简明 Python 教程>> Swaroop, C. H. 著 沈洁元 译 其实,这本书里已经把python的最基本的用法,编码等等介绍的很好,这里把我用到的 ...
- Python + OpenCV2 系列:2 - 图片操作
这些相当于我的学习笔记,所以并没有很强的结构性和很全的介绍,请见谅. 1 读取.写入图像 下面是一个简短的载入图像.打印尺寸.转换格式及保存图像为.png的例子: # -*- coding: utf- ...
随机推荐
- Java入门篇(四)——数组
上篇在foreach中有引入一个数组的概念,数组是最为常见的一种数据结构,是相同类型的.用一个标识符封装到一起的基本类型数据序列或对象序列. 数组是具有相同数据类型的一组数据的集合,根据维数不同可以分 ...
- POJ 1426 Find The Multiple(数论——中国同余定理)
题目链接: http://poj.org/problem?id=1426 Description Given a positive integer n, write a program to find ...
- SDP(1):ScalikeJDBC-基本操作介绍
简单来说:JDBC是一种开放标准的跨编程语言.跨数据库类型编程API.各类型数据库产品厂商都会按它的标准要求来提供针对自身产品的JDBC驱动程序.最主要的这是一套成熟的工具,在编程人员中使用很普及.既 ...
- angularjs+ionic+'h5+'实现二维码扫描功能
今天给大家分享一下基于angularjs与ionic框架实现手机二维码扫描的功能.没有用到cordova等任何插件,h5+实现的. 开发工具:hbuilder 首先,需要在hbuilder项目下面的配 ...
- 百度编辑器ueditor
,怎么将上传的图片路径改到项目的public/uploads文件夹呢?哪位大神改过
- github设置添加SSH
很多朋友在用github管理项目的时候,都是直接使用https url克隆到本地,当然也有有些人使用 SSH url 克隆到本地.然而,为什么绝大多数人会使用https url克隆呢? 这是因为,使用 ...
- PHPMailer发送邮件中文附件名是乱码
可能使用了PHPMailer发送邮件的朋友带中文附件名时会出现乱码,下面我来介绍一个解决办法. 比如我们要发送的附件是"测试.txt",如果在添加附件的时候强制使用指定文件名的方式 ...
- 【开发技术】Get请求和Post请求区别
a.Get请求是通过URL请求来提交表单数据的:Post是通过HTTP中的POST机制将表单中的数据提交到Action所定制的程序,如果有附件需要用Post方式. b.Get适用于传输数据量小于1K数 ...
- Android 问题
1.Cannot refer to a non-final variable 解决方法 内部类如果要引用外部类的变量,则该变量必须为final,这是规定 2.error: No resource id ...
- eclipse怎么修改工作空间路径
1.打开eclipse,在eclipse界面中的菜单栏中点击“文件”,如果您的eclipse是英文版,那么应该是file,打开后点击“切换工作空间" 2.如果您的eclipsehi英文版,则 ...