最近在做基于图像的室内定位方面的研究,于是使用到了百度最新的室内数据库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. [国嵌笔记][033-034][设置svc模式]

    [设置svc模式] 设置CPU为SVC模式 1.因为初始化系统需要有很高的权限,SVC模式具有该权限,所以首先要使系统工作在SVC(0b10011)模式 2.设置cprs为0xd3(0b1101001 ...

  2. Cxf -wsdl2java 使用参数介绍

    wsdl2java -h 可以得到详细的参考文档: G:\cxf\apache-cxf-3.1.6\bin>wsdl2java -h wsdl2java -fe|-frontend <fr ...

  3. YUI 阻止动态css加载

    skinnable动态加载 在YUI Module中,经常采用skinnable参数来动态加载css,如: YUI().use('w-paginator', function(Y) { }, requ ...

  4. 解Linux SSH命令大全,新手必看SSH命令

    下面介绍一些基本的常用的Linux SSH命令,都是一些很简单的Linux SSH命令,新手掌握了这几个,一般管理一般的vps或者linux主机就可以了!     我们的教程介绍了putty的使用方法 ...

  5. PHP怎么获取系统信息和服务器详细信息

    https://zhidao.baidu.com/question/1435990326608475859.html 获取系统类型及版本号: php_uname() (例:Windows NT COM ...

  6. 谈谈Python、Java与AI

    Python好像天生是为AI而生的,随着AI的火热,特别是用Python写的TensorFlow越来越火,Python的热度越来越高,就像当年Java就是随着互联网火起来的感觉.在我的工作中,Pyth ...

  7. sqlite入门基础(一):sqlite3_open,sqlite3_exec,slite3_close

    打开数据库链接sqlite3_open用法 原型: int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sq ...

  8. sudo 无效命令

    mac系统中由于不小心修改了/etc/sudoers下的权限为777,故而sudo命令不能使用. 解决办法 1.重新启动mac并且按command+s进入单用户界面 2.此时默认的系统状态是只读状态, ...

  9. Log4j源码解析--核心类解析

    原文出处:http://www.blogjava.net/DLevin/archive/2012/06/28/381667.html.感谢上善若水的无私分享. 在简单的介绍了Log4J各个模块类的作用 ...

  10. 用Python实现几种排序算法

    #coding=utf-8 # 1 快速排序算法 def qksort(list): if len(list)<=1: return list else: pivot = list[0] les ...