卡尔曼滤波预测三维坐标点

在网上找了很多卡尔曼滤波的代码,后来觉得文心一言生成的代码更简单容易理解。

修改了很多遍,勉强能运行,放在这里算是记录。

objectPoints是一个存储三维坐标点的矩阵,遍历矩阵预测更新坐标点。

卡尔曼滤波适用于线性系统,我试了几组数据发现偏差很大,后面溉用扩展卡尔曼滤波了。

// 添加第一个点 (X, Y, Z)  
objectPoints.push_back(cv::Point3f(0.378343f, 0.3473857f, 0.786856f)); // 原点  

// 添加第二个点  
objectPoints.push_back(cv::Point3f(-0.82075f, 0.9275763f, 0.748373f)); // X轴正方向上的一个单位点  

// 添加第三个点  
objectPoints.push_back(cv::Point3f(0.3775489f, -0.24635f, 0.8435f)); // Y轴正方向上的一个单位点  

// 添加第四个点  
objectPoints.push_back(cv::Point3f(-0.47589357f, -0.777578f, 0.3874f)); // Z轴正方向上的一个单位点(尽管在图像平面上Z通常为0)  

cout << "测试数据:" << objectPoints << endl;
int stateSize = 6; // 状态大小:位置(x, y) + 速度(vx, vy)  
int measureSize = 3; // 测量大小:位置(x, y)  
int controlSize = 0; // 没有控制输入 
cv::KalmanFilter kalmanFilter(stateSize, measureSize, controlSize, CV_32F);

// 设置初始状态  
cv::Mat initialState = Mat::zeros(stateSize, 1, CV_32F);
//initialState.setTo(cv::Scalar(0)); // 所有状态设置为0(位置在原点,速度为0)  
kalmanFilter.statePost = initialState;
// 转移矩阵 F  
// 假设dt是时间步长(例如,0.1秒)  
double dt = 0.1;
cv::Mat F = (cv::Mat_<float>(stateSize, stateSize) <<
				1, 0, dt, 0, 0, 0.5 * dt * dt,
				0, 1, 0, dt, 0, 0.5 * dt * dt,
				0, 0, 1, 0, dt, dt * dt,
				0, 0, 0, 1, 0, dt,
				0, 0, 0, 0, 1, 1,
				0, 0, 0, 0, 0, 1);
kalmanFilter.transitionMatrix = F;

// 测量矩阵 H  
cv::Mat H = (cv::Mat_<float>(measureSize, stateSize) <<
				1, 0, 0, 0, 0, 0,
				0, 1, 0, 0, 0, 0);
kalmanFilter.measurementMatrix = H;

// 过程噪声协方差矩阵 Q  
// 根据你的应用调整这些值  
cv::Mat Q = (cv::Mat_<float>(stateSize, stateSize) <<
				0.01, 0, 0, 0, 0, 0,
				0, 0.01, 0, 0, 0, 0,
				0, 0, 0.01, 0, 0, 0,
				0, 0, 0, 0.01, 0, 0,
				0, 0, 0, 0, 0.01, 0,
				0, 0, 0, 0, 0, 0.01);
kalmanFilter.processNoiseCov = Q;

// 测量噪声协方差矩阵 R  
// 根据你的测量设备的精度调整这些值  
cv::Mat R = (cv::Mat_<float>(measureSize, measureSize) <<
				0.01, 0,
				0, 0.01
				);
kalmanFilter.measurementNoiseCov = R;

 初始误差协方差矩阵 P  
 初始时可能不确定,所以设置为较大的值  
cv::Mat P = (cv::Mat_<float>(stateSize, stateSize) <<
				1, 0, 0, 0,
				0, 1, 0, 0,
				0, 0, 1, 0,
				0, 0, 0, 1
				) * 1e3;
kalmanFilter.errorCovPost = P;

// 用于存储预测的坐标点  
std::vector<cv::Point2f> predictedPoints;
// 准备测量值(仅位置,速度为0,因为卡尔曼滤波器将基于位置进行预测) 
for (size_t i = 0; i < objectPoints.size(); ++i)
{
				cv::Mat measurement = (cv::Mat_<float>(measureSize, 1) << objectPoints[i].x, objectPoints[i].y,0);
				
				// 预测  
				cv::Mat prediction = kalmanFilter.predict();
				cout <<"prediction" << prediction << endl;
				//计算测量值
				measurement.at<float>(0) = (float)objectPoints[i].x;
				measurement.at<float>(1) = (float)objectPoints[i].y;
				cout << "measurement" <<measurement.at<float>(0) << "\t" << measurement.at<float>(1)<< endl;
				// 校正(使用当前测量值)  
				kalmanFilter.correct(measurement);
				
				// 现在kalmanFilter.statePost包含校正后的状态估计(位置和速度)  
				// 提取位置信息  
				float predictedX = kalmanFilter.statePost.at<float>(0);
				float predictedY = kalmanFilter.statePost.at<float>(1);
				cout << "xxxx" << predictedX << "yyyy" << predictedY << endl;
				predictedPoints.push_back(cv::Point2f(predictedX, predictedY));
				// 确保预测的位置在图像范围内  
				predictedX = std::max(0.0f, std::min(predictedX, copy.cols - 1.0f));
				predictedY = std::max(0.0f, std::min(predictedY, copy.rows - 1.0f));
				// 在图像上绘制点  
				// 存储预测的坐标点以供后续绘制  
}
// 在图像上绘制一系列的点以显示轨迹  
for (const auto& point : predictedPoints)
{
				cv::circle(copy, point, 5, cv::Scalar(0, 255, 255), -1); // 黄色圆点,-1表示填充  
				std::cout << "Predicted point: (" << point.x << ", " << point.y << ")" << std::endl;
}

objectPoints.clear();

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python 中使用滤波(Kalman Filter)处理稀疏点云数据通常用于估计物体的运动轨迹或姿态,特别是在机器人学、无人机导航和计算机视觉等领域。滤波是一种递归最小二乘估计算法,特别适合处理动态系统中的噪声数据。 以下是使用 Python 和一些库(如`numpy`、`scipy`、`pykalman`等)实现滤波处理稀疏点云的简单步骤: 1. **安装依赖库**: ```bash pip install numpy scipy pykalman ``` 2. **导入所需模块**: ```python import numpy as np from scipy.linalg import inv, sqrtm from pykalman import KalmanFilter ``` 3. **准备数据**: - 点云数据通常表示为一系列二维或三维坐标点,每帧数据视为一维向量。 - 同时,需要定义系统的状态模型(如移动方程)和观测方程。 4. **初始化滤波器**: ```python kf = KalmanFilter( transition_matrices=[...], # 移动方程矩阵 observation_matrices=[...], # 观测方程矩阵 initial_state_mean=[...], # 初始状态估计 initial_state_covariance=[...], # 初始状态协方差矩阵 observation_covariance=[...], # 观测噪声协方差矩阵 transition_covariance=[...], # 状态转移噪声协方差矩阵 em_vars=None # 可选参数,用于自适应估计 ) ``` 5. **数据预处理**: - 稀疏点云可能包含缺失值,需要填充或删除这些部分。 - 对于滤波,可能需要对数据进行平滑处理,以便更好地适应滤波器假设。 6. **运行滤波过程**: ```python for point_cloud in data: prediction, kalman_gain = kf.predict() updated_state = prediction + kalman_gain @ (point_cloud - kf.observation_matrix @ prediction) kf.update(updated_state) ``` 7. **获取滤波后的结果**: - `kf.state_mean`将给出估计的当前状态(例如位置和速度)。 相关问题: 1. 滤波的基本原理是什么? 2. 如何根据点云数据的特点调整观测方程和移动方程? 3. 在处理稀疏点云时,如何处理数据缺失的情况? 4. 滤波如何处理高维数据或复杂系统?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值