rodrigues.m

本文介绍了在手眼标定过程中如何利用罗德里格斯公式计算旋转矩阵对应的旋转轴。通过解析rodrigues.m文件的内容,详细探讨了该公式在实际计算中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在手眼标定中需要使用罗德里格斯计算旋转矩阵对应的旋转轴
rodrigues.m文件内容如下:

function	[out,dout]=rodrigues(in)

% RODRIGUES	Transform rotation matrix into rotation vector and viceversa.
%		
%		Sintax:  [OUT]=RODRIGUES(IN)
% 		If IN is a 3x3 rotation matrix then OUT is the
%		corresponding 3x1 rotation vector
% 		if IN is a rotation 3-vector then OUT is the 
%		corresponding 3x3 rotation matrix
%

%%
%%		Copyright (c) March 1993 -- Pietro Perona
%%		California Institute of Technology
%%

%% ALL CHECKED BY JEAN-YVES BOUGUET, October 1995.
%% FOR ALL JACOBIAN MATRICES !!! LOOK AT THE TEST AT THE END !!

%% BUG when norm(om)=pi fixed -- April 6th, 1997;
%% Jean-Yves Bouguet

%% Add projection of the 3x3 matrix onto the set of special ortogonal matrices SO(3) by SVD -- February 7th, 2003;
%% Jean-Yves Bouguet

% BUG FOR THE CASE norm(om)=pi fixed by Mike Burl on Feb 27, 2007


[m,n] = size(in);
%bigeps = 10e+4*eps;
bigeps = 10e+20*eps;

if ((m==1) & (n==3)) | ((m==3) & (n==1)) %% it is a rotation vector
    theta = norm(in);
    if theta < eps
        R = eye(3);

        %if nargout > 1,

        dRdin = [0 0 0;
            0 0 1;
            0 -1 0;
            0 0 -1;
            0 0 0;
            1 0 0;
            0 1 0;
            -1 0 0;
            0 0 0];

        %end;

    else
        if n==length(in)  in=in'; end; 	%% make it a column vec. if necess.

        %m3 = [in,theta]

import numpy as np import cv2 import math class CDomPho: def __init__(self): self.m_f = self.m_Pxz = self.m_k1 = self.m_k2 = self.m_p1 = self.m_p2 = 0.0 self.m_X0 = self.m_Y0 = 0.0 self.m_cols = self.m_rows = 0 self.m_rotM = [0.0] * 9 self.m_ref = [0.0] * 6 def POK2M(self, p, o, k): cosp = math.cos(p) cosw = math.cos(o) cosk = math.cos(k) sinp = math.sin(p) sinw = math.sin(o) sink = math.sin(k) self.m_rotM[0] = cosp * cosk - sinp * sinw * sink self.m_rotM[1] = -cosp * sink - sinp * sinw * cosk self.m_rotM[2] = -sinp * cosw self.m_rotM[3] = cosw * sink self.m_rotM[4] = cosw * cosk self.m_rotM[5] = -sinw self.m_rotM[6] = sinp * cosk + cosp * sinw * sink self.m_rotM[7] = -sinp * sink + cosp * sinw * cosk self.m_rotM[8] = cosp * cosw def SetPara(self, aopX, aopY, aopZ, aopP, aopO, aopK, f, pxz, cols, rows, k1, k2, p1, p2, X0, Y0): self.POK2M(aopP, aopO, aopK) self.m_aopX = aopX self.m_aopY = aopY self.m_aopZ = aopZ self.m_f = f self.m_Pxz = pxz self.m_k1 = k1 self.m_k2 = k2 self.m_p1 = p1 self.m_p2 = p2 self.m_X0 = X0 self.m_Y0 = Y0 self.m_cols = cols self.m_rows = rows self.m_ref[0] = -(cols / 2) * pxz self.m_ref[1] = pxz self.m_ref[2] = 0 self.m_ref[3] = -(rows / 2) * pxz self.m_ref[4] = 0 self.m_ref[5] = -pxz def ImgZ2Grd(self, xyz, sum): for i in range(sum): px, py = self.Scan2Pho(xyz[i * 3], xyz[i * 3 + 1]) self.PhoZ2Grd(px, py, xyz[i * 3 + 2], xyz, i * 3) def Scan2Pho(self, scX, scY): phoX = self.m_ref[0] + self.m_ref[1] * scX - self.m_ref[2] * scY phoY = self.m_ref[3] + self.m_ref[4] * scX - self.m_ref[5] * scY if abs(self.m_k1) > 1e-12: x, y = phoX, phoY r2 = x * x + y * y r4 = r2 * r2 dx = x * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p1 * (r2 + 2 * x * x) + self.m_p2 * 2 * x * y dy = y * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p2 * (r2 + 2 * y * y) + self.m_p1 * 2 * x * y phoX -= dx phoY -= dy return phoX, phoY def Grd2Img(self, gx, gy, gz): px, py = self.Grd2Pho_(gx, gy, gz) scX, scY = self.Pho2Scan(px, py) return scX, scY def Grd2Pho_(self, gx, gy, gz): R = self.m_rotM dx = gx - self.m_aopX dy = gy - self.m_aopY dz = gz - self.m_aopZ denominator = R[2] * dx + R[5] * dy + R[8] * dz fm = -self.m_f / denominator if abs(denominator) > 1e-12 else 0 px = (R[0] * dx + R[3] * dy + R[6] * dz) * fm py = (R[1] * dx + R[4] * dy + R[7] * dz) * fm return px, py def Pho2Scan(self, phoX, phoY): if abs(self.m_k1) > 1e-12: x, y = phoX, phoY for _ in range(2): # 两次迭代近似矫正 r2 = x * x + y * y r4 = r2 * r2 dx = x * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p1 * (r2 + 2 * x * x) + self.m_p2 * 2 * x * y dy = y * (self.m_k1 * r2 + self.m_k2 * r4) + self.m_p2 * (r2 + 2 * y * y) + self.m_p1 * 2 * x * y x = phoX + dx y = phoY + dy phoX, phoY = x, y tt = self.m_ref[1] * self.m_ref[5] - self.m_ref[2] * self.m_ref[4] phoX -= self.m_ref[0] phoY -= self.m_ref[3] scX = (self.m_ref[5] * phoX - self.m_ref[2] * phoY) / tt scY = -(-self.m_ref[4] * phoX + self.m_ref[1] * phoY) / tt return scX, scY def PhoZ2Grd(self, px, py, gz, xyz, idx): R = self.m_rotM A = R[0] * px + R[1] * py - R[2] * self.m_f B = R[3] * px + R[4] * py - R[5] * self.m_f C = R[6] * px + R[7] * py - R[8] * self.m_f N = (gz - self.m_aopZ) / C if abs(C) > 1e-12 else 0 xyz[idx] = self.m_aopX + A * N xyz[idx + 1] = self.m_aopY + B * N def main(): # 从文件读取参数 (示例路径) with open(r'D:\shuiwei\para3.txt') as f: lines = f.readlines() params = list(map(float, lines[1].split())) # 假设第二行是参数 aopX, aopY, aopZ, aopP, aopO, aopK, f, Pxz, k1, k2, p1, p2, X0, Y0 = params[:14] # 读取原始影像 m_img = cv2.imread(r'D:\shuiwei\9.jpg') if m_img is None: print("Error: Image not found") return rows, cols = m_img.shape[:2] dompho = CDomPho() dompho.SetPara(aopX, aopY, aopZ, aopP, aopO, aopK, f, Pxz, cols, rows, k1, k2, p1, p2, X0, Y0) # 四个角点坐标 (x,y,高程) corPt = [0.0, 0.0,400, cols, 0,400, 0, rows,400, cols, rows,400] dompho.ImgZ2Grd(corPt, 4) # 计算地面坐标 # 计算地面范围 gxs = corPt[0::3] gys = corPt[1::3] mingx, maxgx = min(gxs), max(gxs) mingy, maxgy = min(gys), max(gys) # 创建正射影像 resolution = 0.3 domCols = int((maxgx - mingx) / resolution) + 1 domRows = int((maxgy - mingy) / resolution) + 1 domImg = np.zeros((domRows, domCols, 3), dtype=np.uint8) # 生成正射影像 h = 400# 地面高程 for r in range(domRows): gy = mingy + r * resolution for c in range(domCols): gx = mingx + c * resolution ix, iy = dompho.Grd2Img(gx, gy, h) # 最近邻插值 i = int(ix + 0.5) j = int(iy + 0.5) if 0 <= i < cols and 0 <= j < rows: # 注意坐标翻转 (OpenCV原点在左上角) domImg[domRows - 1 - r, c] = m_img[rows - 1 - j, i] # 显示并保存结果 cv2.imshow('DOM', domImg) cv2.waitKey(0) cv2.imwrite(r'D:\shuiwei\current_view2.jpg', domImg) cv2.destroyAllWindows() if __name__ == "__main__": main() 这段代码输入的参数都是什么,是否可以用旋转向量和平移向量,内参矩阵和畸变参数代替
最新发布
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值