相机位姿估计

article/2025/10/1 12:13:08

相机位姿估计

  • 前言
  • 旋转角度
    • 欧拉角
    • 相机位姿求解
    • 旋转矩阵和旋转向量之间的转换
    • 旋转矩阵和欧拉角之间的转换
    • 平移量求解
    • 代码

前言

这部分内容博主也不是很熟悉,写下这篇博文想记录下自己当时的求解过程,也想让看到的朋友一起讨论,看看我做的对不对。下面我就开始喽。

旋转角度

欧拉角

首先介绍一个欧拉角的概念。
任何一个旋转都可以表示为依次绕着三个旋转轴旋转三个角度的组合。这三个角称为欧拉角。对于在三维空间里的一个参考系,任何坐标系的取向,都可以用三个欧拉角来表示,如下图(蓝色是起始坐标系,红色是旋转之后的坐标系):

在这里插入图片描述

相机位姿求解

如果场景的三维结构已知,利用多个控制点在三维场景中的坐标及其在图像中的透视投影坐标即可求解出相机坐标系与表示三维场景结构的世界坐标系之间的绝对位姿关系,包括绝对平移向量t以及旋转矩阵R,该类求解方法统称为N点透视位姿求解(Perspective-N-Point,PNP问题)。
在这里我选用的是SolvePnPRansac,SolvePnPRansac是PnP位姿估计鲁棒算法的一种,我没有学习具体的算法过程,直接对比了一下其与SolvePnP之间的区别,就选择了SolvePnPRansac,哈哈哈,原谅我的不严谨。一下是OpenCV里对这个函数的说明:

bool cv::solvePnPRansac(InputArray    objectPoints,InputArray    ,InputArray    cameraMatrix,InputArray    distCoeffs,OutputArray   rvec,OutputArray   tvec,bool  	      useExtrinsicGuess = false,int  	      iterationsCount = 100,float  	      reprojectionError = 8.0,double  	  confidence = 0.99,OutputArray   inliers = noArray(),int  	      flags = SOLVEPNP_ITERATIVE ) 		
参数:
In_objectPoints :参考点在世界坐标系下的点集;
in_imagePoints:参考点在相机像平面的坐标;
in_cameraMatrix :相机内参;
in_distCoeffs :相机畸变系数;
out_rvec:旋转矩阵;
out_tvec:平移向量;
in_useExtrinsicGuess:如果求解PnP使用迭代算法,初始值可以使用猜测的初始值(true),也可以使用解析求解的结果作为初始值(false);
in_iterationsCoun:Ransac算法的迭代次数,这只是初始值,根据估计外点的概率,可以进一步缩小迭代次数;(此值函数内部是会不断改变的),所以一开始可以赋一个大的值;
in_reprojectionErrr: Ransac筛选内点和外点的距离阈值,这个根据估计内点的概率和每个点的均方差(假设误差按照高斯分布)可以计算出此阈值;
in_confidence :此值与计算采样(迭代)次数有关。此值代表从n个样本中取s个点,N次采样可以使s个点全为内点的概率;
out_inliers :返回内点的序列。为矩阵形式;
in_ flags :最小子集的计算模型;SOLVEPNP_ITERATIVE(此方案,最小模型用的EPNP,内点选出之后用了一个迭代);SOLVE_P3P(P3P只用在最小模型上,内点选出之后用了一个EPNP) ;  SOLVE_AP3P(AP3P只用在最小模型上,内点选出之后用了一个EPNP);SOLVE_EPnP(最小模型上&内点选出之后都采用了EPNP)。
返回值:
成功返回true,失败返回false;

旋转矩阵和旋转向量之间的转换

在刚才的相机位姿求解和上两篇博文中详解张正友相机标定原理(一)、详解张正友相机标定原理(二)中,有提到求解相机相对于图像的像素坐标系的旋转向量(注意:很多地方说成是旋转矩阵,其实那个函数求解出来的结果是一个向量,大家可以自行去验证,使用旋转向量的形式来表示旋转关系的),这里我们要先将其转换成旋转矩阵的形式。
旋转向量与旋转矩阵的相互转换可以用罗德里格斯公式来解决,罗得里格斯公式的推导过程网上很容易找得到。罗得里格斯公式:
在这里插入图片描述
OpenCV里自带了罗德里格斯函数,可以直接调用,Rodrigues(),可以实现旋转向量和旋转矩阵的相互转换(数学家真厉害),输入旋转矩阵/向量,输出旋转向量/矩阵。函数比较简单就不单独列出,最后会贴全部程序。

旋转矩阵和欧拉角之间的转换

上一部分求解得到了旋转矩阵,下边将旋转矩阵转换成欧拉角的形式。欧拉角和旋转矩阵之间的关系如下:
在这里插入图片描述

平移量求解

在这里插入图片描述在这里插入图片描述
再上一个步骤中已经求得了绕X轴、Y轴、Z轴的旋转角度,在相机位姿求解时求解出了平移向量。我做的小例子中相机是用的笔记本电脑的摄像头,因此相机的位置是固定不动的,棋盘格标定板的位置是变动的。认为设置的是棋盘格角点的位置,因此求得的是相机相对于棋盘格的位置信息。将上一个步骤中求得的三个方向上的欧拉角以及位姿求解时得到的平移向量,分别一次带入绕X轴、Y轴、Z轴的旋转的式子,要不断更新(x,y,z)的值,循环代入,即可得到平移量。

最后可参考相机位姿估计的文章,写的很详细,我从中借鉴了很多东西。实在太困,写的不清楚,想起来再补充吧。

代码

#旋转矩阵转换成欧拉角,求解相机在世界坐标系中的旋转角度
def rotationMatrixToEulerAngles(rvecs):R = np.zeros((3, 3), dtype=np.float64)cv2.Rodrigues(rvecs, R)sy = math.sqrt(R[0,0] * R[0,0] +  R[1,0] * R[1,0])singular = sy < 1e-6if  not singular:x = math.atan2(R[2,1] , R[2,2])y = math.atan2(-R[2,0], sy)z = math.atan2(R[1,0], R[0,0])else :x = math.atan2(-R[1,2], R[1,1])y = math.atan2(-R[2,0], sy)z = 0X = x*180.0/3.141592653589793Y = y*180.0/3.141592653589793Z = z*180.0/3.141592653589793return X,Y,Z# 经过三次旋转求解相机在世界坐标系中的坐标
def RotateByZ(Cx, Cy, Z):rz = Z*math.pi/180.0outX = math.cos(rz)*Cx - math.sin(rz)*CyoutY = math.sin(rz)*Cx + math.cos(rz)*Cyreturn outX, outY
def RotateByY(Cx, Cz, Y):ry = Y*math.pi/180.0outZ = math.cos(ry)*Cz - math.sin(ry)*CxoutX = math.sin(ry)*Cz + math.cos(ry)*Cxreturn outX, outZ
def RotateByX(Cy, Cz, X):rx = X*math.pi/180.0outY = math.cos(rx)*Cy - math.sin(rx)*CzoutZ = math.sin(rx)*Cy + math.cos(rx)*Czreturn outY, outZcap = cv2.VideoCapture(0) #读入视频文件 
c=1
cap = cv2.VideoCapture(0)
width = int(cap.get(3)) # 读取摄像头分辨率参数
height = int(cap.get(4))
img = np.zeros((width,height,3),dtype=np.uint8) # 创建图像模板  
if cap.isOpened(): #判断是否正常打开 rval ,img = cap.read() 
else: rval = False  
timeF = 150 #视频帧计数间隔频率 ,可根据需求自行调节判断时间间隔  
while rval:  #循环读取视频帧 rval, img = cap.read() cv2.imshow('img',img)if(c%timeF == 0): #每隔timeF帧进行操作 gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)    ret0, corners = cv2.findChessboardCorners(gray, (6,4), flags=3)        if ret0 == True:            criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)            objp = np.zeros((6*4,3),np.float32)             objp[:,:2] = np.mgrid[0:18:3,0:12:3].T.reshape(-1,2)                        objpoints = [] imgpoints = []         objpoints.append(objp)           corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)            if corners2:                imgpoints.append(corners2)else:imgpoints.append(corners)            img = cv2.drawChessboardCorners(img,(6,4),corners2,ret)        ret, rvecs, tvecs, inliers = cv2.solvePnPRansac(objp, corners2, mtx, dist)print("相机的旋转:")R = rotationMatrixToEulerAngles(rvecs)print("请绕X轴逆时针旋转",R[0],"°")print("请绕Y轴逆时针旋转",R[1],"°")print("请绕Z轴逆时针旋转",R[2],"°")                # 相机坐标系下值x = tvecs[0]y = tvecs[1]z = tvecs[2]        (x, y) = RotateByZ(x, y, -1.0*R[2])(x, z) = RotateByY(x, z, -1.0*R[1])(y, z) = RotateByX(y, z, -1.0*R[0])Cx = x*-1Cx = Cx - 7.5Cy = y*-1Cy = Cy - 7.5Cz = z*-1# 输出相机位置print("相机的平移:")print("请沿X轴负方向平移",Cx[0],"cm")print("请沿Y轴负方向平移",Cy[0],"cm")print("请沿Z轴负方向平移",Cz[0],"cm")     c = c + 1cv2.waitKey(1)
cap.release() 

http://chatgpt.dhexx.cn/article/XGHkeO4x.shtml

相关文章

iOS 相册多选 相机选择图片

前言 经过几天的断断续续的编写终于把这一个小项目完成了&#xff0c;现在刚刚完成&#xff0c;代码看着不整洁&#xff0c;请多包涵。 前几天要弄个相册多选和照相选图的功能&#xff0c;以前做过单选上传头像之类的。但是多选确实不像那么简单&#xff0c;github找了好多的…

工业相机和镜头选型技巧

工业相机和镜头选型技巧 一、加接圈&#xff0c;视野为什么会变小&#xff1f;1、视野公式理解2、加接圈后视野变小分析 二、在如下试验台中&#xff0c;加了接圈&#xff0c;图像要清晰&#xff0c;那么相机高度应该如何调整&#xff1f;1、试验台场景2、像距、物距和焦距的关…

工业视觉检测如何选择合适的工业相机?

1、根据应用的不同分别选用CCD或CMOS相机CCD工业相机主要应用在运动物体的图像提取&#xff0c;如贴片机机器视觉&#xff0c;当然随着CMOS技术的发展&#xff0c;许多贴片机也在选用CMOS工业相机。用在视觉自动检查的方案或行业中一般用CCD工业相机比较多。CMOS工业相机由成本…

【工业相机】【深度3】相机选择-精度和曝光需求计算 - 输入:1 被测试物体的最小体积 2 被测物体的移动相对速度

前言&#xff1a;本举例&#xff0c;说明&#xff0c;我们在工业场景下&#xff0c;如果需要在某个速度下计算某个尺寸的物体的工业相机的精度计算方法 1 需求定义 本需求定义为测量一个有移动速度的工业被测物体&#xff1a; 输入参数标识输入参数举例FOVFOV12寸&#xff08…

机器视觉-相机选择方法-缺陷检测

主要分为三部分 1.相机示意图及基本结构 2.相机参数确定方法 3.最终选择 1.相机示意图及基本结构 简图↑ 全图↑ 光圈与景深↑ 2.相机基本参数确定 视野与像素确定 被检测石英镜片的最大直径为38.6mm。也就是最大弥散圆直径。 样品↑ 较小划痕样本↑ 划痕测量↑ 如上图&…

iOS相机选择器

最近有很多朋友加我QQ, 说是在iOS8相机遇到问题.http://blog.csdn.net/chenyong05314/article/details/44812085 本人在使用相机这块时, 所有东西都封装到了一个类里面, 外部使用只需要一行代码, 非常方便, 现分享出来供大家使用. 代码示例: // Controller 为弹出的VC [[Ca…

Swift使用UIImagePickerController 从相册选择图片、从相机选择图片

配置&#xff1a; 如果是相机使用&#xff0c;需要在info.plist文件增加使用前应用程序说明&#xff1b;相机使用也是如此。&#xff08;第二个是CALENDARS权限&#xff0c;打错了&#xff1b;图片是Photo Library Usage Description&#xff09; 从相册选择图片&#xff1a…

摄影小白入门相机选择(个人出发)

1.微单与卡片机 在产品质量上&#xff0c;相机的感光器件CMOS这些&#xff0c;可以一概认为&#xff0c;同价同质。 两者的区别主要在镜头的设计&#xff0c;黑卡被设计为不可更换镜头式无反相机&#xff0c;入门级别的一般搭配标准变焦镜头 如16-55这种焦距&#xff0c;旗舰级…

机器视觉系统中相机镜头选型技巧_工业相机在机器视觉系统中的地位和作用

一、什么是工业相机 工业相机是机器视觉系统中的一个关键组件,其最本质的功能就是将光信号转变成有序的电信号。选择合适的相机也是机器视觉系统设计中的重要环节,相机的选择不仅直接决定所采集到的图像分辨率、图像质量等,同时也与整个系统的运行模式直接相关。 二、工业相…

栅格重投影(投影变换)

OpenLayers能够在不同的坐标系统中显示来自WMS、WMTS、静态图像和许多其他源的栅格数据。图像的地图重投影直接发生在web浏览器中。在任何Proj4js支持的坐标参考系统中都是可视的&#xff0c;并且以前不兼容的图层现在可以组合和叠加。 使用&#xff1a; API的使用非常简单。…

坐标系与投影变换

所有空间数据必须纳入到相同空间参考基准下才可以进行空间分析&#xff0c;因此坐标系和投影变换十分重要&#xff0c;这也是地理信息系统的基础。坐标系是数据或地图的属性&#xff0c;而投影是坐标系的属性。 一、地球形状&#xff08;三级逼近&#xff09; 地球表面→ 大地水…

Opencv——几何空间变换(仿射变换和投影变换)

几何空间变换 【1】几何变换&#xff08;空间变换&#xff09;简述【2】变换矩阵知识简述齐次坐标的概念几何运算矩阵 【3】图像的仿射变换1、平移变换2、比例缩放3、旋转4、对称变换&#xff08;不做展示&#xff09;1、关于X轴变换2、关于Y轴变换3、关于直线YX变换4、关于直线…

仿射变换和投影变换

1. 仿射变换 1) 用途 旋转 (线性变换)&#xff0c;平移 (向量加)&#xff0e;缩放(线性变换)&#xff0c;错切&#xff0c;反转 2) 方法 仿射变换是一种二维坐标到二维坐标之间的线性变换&#xff0c;它保持了二维图形的“平直性”&#xff08;直线经过变换之后依然是直线&…

三维图形的投影变换

1.平行投影: 1.1 正轴投影: 我们通常说的三视图是指正视图、俯视图和侧视图, 投影平面分别与 x,y,z 轴垂直。 正视图:(yz) 俯视图:(xy) 侧视图:(xz) 1.2 正轴测投影: 如图: 咱们希望按照这个平面对物体进行平行投影: 首先,先把物体及投影面沿着y轴顺时针旋转,在绕x轴逆时针…

华科_图形学笔记_07_投影变换

计算机图形学_华中科技大学_中国大学MOOC(慕课) 7.1_有趣的投影 由于我们的观察设备是二维的&#xff0c;因此&#xff0c;最终都存在一个三维向二维的映射过程。这个映射过程&#xff0c;按照几何意义来说就是投影。 而在我们之前讲到的观察变换中&#xff0c;其实还有一个隐…

Opengl投影变换理解

坐标到达观察空间之后&#xff0c;我们需要将其投影到裁剪坐标。裁剪坐标会被处理至-1.0到1.0的范围内&#xff0c;并判断哪些顶点将会出现在屏幕上。 而[-1.0,1.0]构成的正方体又叫规则观察体(Canonical View Volume, CVV) 一、流程 计算机显示器是一个 2D 表面。OpenGL 渲染…

图形学-(视图变换,投影变换)

1.视图变换 在 3 维物体变到二维平面的过程中&#xff0c;我们需要规定好相机的位置。对于相机所做的变换就是视图变换 &#xff08;Viewing/Camera transformation&#xff09;。 我们需要对相机位置进行定义&#xff0c;对于一个相机我们要规定下面三个属性&#xff1a; 相…

4.3 投影变换

投影变换的目的就是定义一个视景体,使得视景体外多余的部分裁剪掉,最终图像只是视景体内的有关部分。 投影也是使用矩阵来实现的。计算一个用于实现透视投影或者平行投影的矩阵,并把它与当前的投影矩阵(一般是单位矩阵)相乘。 OpenGL支持两种类型的投影变换,即透视投影…

读书笔记-opencv-投影变换

读书笔记-opencv-投影变换 原理解析 ​ 透视变换是将图片投影到一个新的视平面&#xff0c;也称作投影映射&#xff0e;它是二维&#xff08;x,y&#xff09;到三维(X,Y,Z)&#xff0c;再到另一个二维(x′,y′)空间的映射&#xff0e;相对于仿射变换&#xff0c;它提供了更大…