最近在做基于图像的室内定位方面的研究,于是使用到了百度最新的室内数据库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_1:OpenCV:solvePnP二次封装与性能测试

    关键词:OpenCV::solvePnP 文章类型:方法封装.测试 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-27 @Lab: CvLab20 ...

  2. 相机位姿估计0:基本原理之如何解PNP问题

    关键词:相机位姿估计 PNP问题求解 用途:各种位姿估计 文章类型:原理 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-18 @Lab: CvLa ...

  3. 相机位姿求解——P3P问题

    1.位姿求解是计算机视觉中经常遇到的,Perspective-n-Points, PnP(P3P)提供了一种解决方案,它是一种由3D-2D的位姿求解方式,即需要已知匹配的3D点和图像2D点.目前遇到的 ...

  4. Python + OpenCV2 系列:1 - 配置

    Python+OpenCV2+Eclipse+Windos 8.1(32bits): 最初的目的是做图像处理,opencv强大的社区支持,让我想从matlab转到opencv框架下进行试验,而Pyth ...

  5. 物体的三维识别与6D位姿估计:PPF系列论文介绍(三)

    作者:仲夏夜之星 Date:2020-04-08 来源:物体的三维识别与6D位姿估计:PPF系列论文介绍(三) 文章“A Method for 6D Pose Estimation of Free-F ...

  6. cv2.solvepnp 相机的位姿估计

    预备知识   图像坐标系:   理想的图像坐标系原点O1和真实的O0有一定的偏差,由此我们建立了等式(1)和(2),可以用矩阵形式(3)表示. 相机坐标系(C)和世界坐标系(W): 通过相机与图像的投 ...

  7. 【转】【计算机视觉】opencv靶标相机姿态解算2 根据四个特征点估计相机姿态 及 实时位姿估计与三维重建相机姿态

    https://blog.csdn.net/kyjl888/article/details/71305149

  8. Python + OpenCV2 系列:3 - python 字符串,类,编码规范

    首先,强烈推荐<<简明 Python 教程>> Swaroop, C. H. 著 沈洁元 译 其实,这本书里已经把python的最基本的用法,编码等等介绍的很好,这里把我用到的 ...

  9. Python + OpenCV2 系列:2 - 图片操作

    这些相当于我的学习笔记,所以并没有很强的结构性和很全的介绍,请见谅. 1 读取.写入图像 下面是一个简短的载入图像.打印尺寸.转换格式及保存图像为.png的例子: # -*- coding: utf- ...

随机推荐

  1. 微信小程序 PHP后端form表单提交实例详解

    微信小程序php后端form表单 https://www.cnblogs.com/tdalcn/p/7092716.html 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了 ...

  2. QQ邮箱开启SMTP服务的步骤

    首先要确保你的QQ邮箱已经要开启超过一个月.对于新开启的邮箱,腾讯是不开放这些功能的. 方法/步骤 首先点QQ头像旁边的信封符号进入邮箱. 当然你也可以使用 mail.qq.com进邮箱 进入邮箱后点 ...

  3. 怎样实现给DEDE的栏目增加栏目图片(1)

    http://www.genban.org/news/dedecms-7577.html 前两天用DEDE做二次开发的时候,遇到一个问题,领导让给每个栏目增加一个栏目图片的功能,网上找了些东西,结合自 ...

  4. OKMX6Q ffmpeg & ffserver

    通过ltib在根文件系统中增加mplayer和ffmpeg后,拟使用ffmpeg从摄像头(/dev/video0)采集视频. 刚开始使用了: ffmpeg -f video4linux2 -s 320 ...

  5. __block __weak

    IOS BLOCK收集 在ios,blocks是对象,它封装了一段代码,这段代码可以在任何时候执行.Blocks可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.它和传统的函数指针很 ...

  6. P1345 [USACO5.4]奶牛的电信Telecowmunication

    P1345 [USACO5.4]奶牛的电信Telecowmunication 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流.这些机器用如下的方式发送电邮 ...

  7. 重温吕鑫MFC教学视频(一)

    重温吕鑫MFC教学视频(一)1. picture控件的使用,可以显示icon和bitmap2. WM_Create窗口的创建3. 创建的销毁消息及区别WM_SYSCOMMAND WM_CLOSE WM ...

  8. Java为什么需要保留基本数据类型

    基本数据类型对以数值计算为主的应用程序来说是必不可少的. 自从1996年Java发布以来,基本数据类型就是Java语言的一部分.John Moore通过对使用基本类型和不使用基本类型做java基准测试 ...

  9. Java常用类--数字常用类

    math java提供了基本的 + - * / %等基本算术运算的运算符,但对于更复杂的数学运算比如:三角函数,对数运算,指数运算就无能为力了.Java提供了Math工具类来完成这些复杂的运算,Mat ...

  10. MySQL模糊查询中通配符的转义

    sql中经常用like进行模糊查询,而模糊查询就要用到百分号“%”,下划线“_”这些通配符,其中“%”匹配任意多个字符,“_”匹配单个字符.如果我们想要模糊查询带有通配符的字符串,如“60%”,“us ...