【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。
参考书籍:《人工智能点云处理及深度学习算法》
本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“【python三维深度学习】python三维点云从基础到深度学习_python3d点云从基础到深度学习-优快云博客”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。
在计算机视觉和机器人领域中,对于图像或空间坐标之间的变换关系进行建模和拟合是非常常见的任务。在这篇文章中,我们将介绍如何使用 Python 中的 Scipy 库进行XY平面的RT矩阵拟合。
1. 简介
RT矩阵通常用于描述二维平面上的旋转和平移变换关系。我们首先定义了几个函数来构建和计算XY平面上的RT矩阵,并编写了误差函数来衡量拟合结果与真实值之间的差异。
2. 函数定义
我们定义了以下几个函数:
getRTXY(theta, tx, ty):获取XY平面的RT矩阵。
getPredictRTXY(params, x):根据参数预测XY平面上的RT矩阵结果。
errorRTXY(params, x, y):定义了XY平面RT矩阵的误差函数。
getRXY(theta):获取XY平面的R矩阵。
getPredictRXY(params, x):根据参数预测XY平面上的R矩阵结果。
errorRXY(params, x, y):定义了XY平面R矩阵的误差函数。
errorTXY(params, x, y):定义了XY平面T矩阵的误差函数。
getRTXYL(paras):获取包含所有参数的XY平面RT矩阵。
getPredictRTXYL(params, x):根据参数预测包含所有参数的XY平面RT矩阵结果。
errorRTXYL(params, x, y):定义了包含所有参数的XY平面RT矩阵的误差函数。
3. 主要拟合函数
我们编写了几个主要的拟合函数来处理不同的拟合需求:
get_M_RTXY(x, y):通过拟合XY平面RT矩阵来获得单个M矩阵。
get_M_RTXY_RT(x, y):通过分别拟合R和T来获得XY平面RT矩阵。
get_M_RTXY_R_T(x, y):通过同时拟合R和T来获得XY平面RT矩阵。
get_M_RTXY_L(x, y):直接拟合包含所有参数的XY平面RT矩阵。
除了上述方法之外,opencv也提供相应函数,例如“cv2.findHomography”,其效果类似get_M_RTXY_L(x, y)。由于没有角度theta的约束限制,如果同名点对偏差较大,那最终求解的变换矩阵会使图片发生严重变形。
4. 示例与结果
在主程序中,我们生成随机数据作为待拟合的数据,并展示了不同拟合函数的结果。每个拟合函数返回一个成功标志和最终的拟合矩阵M。
4.1 示例程序
'''
更多python与C++技巧、三维算法、深度学习算法总结、大模型请关注我的博客,欢迎讨论与交流:https://blog.youkuaiyun.com/suiyingy,或”乐乐感知学堂“公众号。Python三维领域专业书籍推荐:《人工智能点云处理及深度学习算法》。
'''
from scipy.optimize import leastsq
import numpy as np
# 获取XY平面RT矩阵
def getRTXY(theta, tx, ty):
RT = np.array([[np.cos(theta), np.sin(theta), tx], [-np.sin(theta), np.cos(theta), ty], [0, 0, 1]])
return RT
# 获取XY平面RT矩阵预测结果
def getPredictRTXY(params, x):
RT = getRTXY(*params)
return RT @ x
# 定义XY平面RT矩阵误差函数
def errorRTXY(params, x, y):
predictions = getPredictRTXY(params, x) # 预测值
return (predictions.flatten() - y.flatten()) # 将 y 展平后与预测值相减
# 获取XY平面R矩阵
def getRXY(theta):
RT = np.array([[np.cos(theta), np.sin(theta)], [-np.sin(theta), np.cos(theta)]])
return RT
# 获取XY平面RT矩阵预测结果
def getPredictRXY(params, x):
RT = getRXY(*params)
return RT @ x
# 定义XY平面R矩阵误差函数
def errorRXY(params, x, y):
predictions = getPredictRXY(params, x) # 预测值
return (predictions.flatten() - y.flatten()) # 将 y 展平后与预测值相减
# 定义XY平面T矩阵误差函数
def errorTXY(params, x, y):
predictions = x + np.array(params).reshape(2, 1) # 预测值
return (predictions.flatten() - y.flatten()) # 将 y 展平后与预测值相减
# 获取XY平面RT全部参数矩阵
def getRTXYL(paras):
RT = np.array([[paras[0], paras[1], paras[2]], [paras[3], paras[4], paras[5]], [0, 0, 1]])
return RT
# 获取XY平面RT矩阵预测结果
def getPredictRTXYL(params, x):
RT = getRTXYL(params)
return RT @ x
# 定义XY平面RT矩阵误差函数
def errorRTXYL(params, x, y):
predictions = getPredictRTXYL(params, x) # 预测值
return (predictions.flatten() - y.flatten()) # 将 y 展平后与预测值相减
def get_M_RTXY(x, y):
initial_params = [1.0, 1.0, 1.0]
M = np.eye(3)
result, success = leastsq(errorRTXY, initial_params, args=(x, y))
if success > 0: M = getRTXY(*result)
# print('RT拟合参数结果:', result)
# print('RT拟合矩阵:', M)
return success, M
def get_M_RTXY_RT(x, y):
initial_params = [1.0, 1.0, 1.0]
M = np.eye(3)
x_mean =np.mean(x, axis=1)[:2].reshape(2, 1)
y_mean =np.mean(y, axis=1)[:2].reshape(2, 1)
initial_params = [1.0]
result, success = leastsq(errorRXY, initial_params, args=(x[:2]-x_mean, y[:2]-y_mean))
if success > 0: M[:2, :2] = getRXY(*result)
# print('R拟合参数结果:', result)
# print('R拟合矩阵:', M[:2, :2])
# print('中心平移误差:', y_mean - getRXY(*result) @ x_mean)
initial_params = [1.0, 1.0]
result, success = leastsq(errorTXY, initial_params, args=(getRXY(*result) @ x[:2], y[:2]))
if success > 0: M[:2, 2] = result
# print('T拟合参数结果:', result)
# print('RT拟合矩阵:', M)
return success, M
def get_M_RTXY_R_T(x, y):
initial_params = [1.0, 1.0, 1.0]
M = np.eye(3)
x_mean =np.mean(x, axis=1)[:2].reshape(2, 1)
y_mean =np.mean(y, axis=1)[:2].reshape(2, 1)
initial_params = [1.0]
result, success = leastsq(errorRXY, initial_params, args=(x[:2]-x_mean, y[:2]-y_mean))
if success > 0:
M[:2, :2] = getRXY(*result)
M[:2, 2] = (y_mean - getRXY(*result) @ x_mean).T
# print('R拟合参数结果:', result)
# print('R拟合矩阵:', M[:2, :2])
# print('中心平移误差:', y_mean - getRXY(*result) @ x_mean)
return success, M
def get_M_RTXY_L(x, y):
initial_params = [1.0, 1.0, 1.0]
M = np.eye(3)
initial_params = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
result, success = leastsq(errorRTXYL, initial_params, args=(x, y))
if success > 0: M = getRTXYL(result)
# print('RT直接拟合参数结果:', result)
# print('RT直接拟合矩阵:', M)
return success, M
if __name__ == '__main__':
# 待拟合的数据
x_data = np.vstack((np.random.rand(2, 4), np.ones((1, 4))))
y_data = np.vstack((np.random.rand(2, 4), np.ones((1, 4))))
print(get_M_RTXY(x_data, y_data))
print(get_M_RTXY_RT(x_data, y_data))
print(get_M_RTXY_R_T(x_data, y_data))
print(get_M_RTXY_L(x_data, y_data))
4.2 运行结果
5. 结论
通过本文的介绍,您可以了解如何利用Scipy库进行XY平面RT矩阵的拟合,以及如何根据具体需求选择合适的拟合方法。这些技术在计算机视觉和机器人领域中具有重要的应用,希望本文能为您在相关领域的工作和研究中提供帮助。
以上就是本文关于使用Python中的Scipy库进行XY平面RT矩阵拟合的介绍,希望对您有所帮助!
【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。
更多python与C++技巧、计算机视觉基础到实践完整指南、三维算法、深度学习算法总结、大模型请关注我的博客,欢迎讨论与交流:https://blog.youkuaiyun.com/suiyingy,或”乐乐感知学堂“公众号。Python三维领域专业书籍推荐:《人工智能点云处理及深度学习算法》。
本文为专栏《Python三维点云实战宝典》系列文章,专栏介绍地址“【python三维深度学习】python三维点云从基础到深度学习_python3d点云从基础到深度学习-优快云博客”。配套书籍《人工智能点云处理及深度学习算法》提供更加全面和系统的解析。