Eigen и SVD, чтобы найти наилучшую плоскость подгонки с учетом набора точек
учитывая набор из N точек в 3D-пространстве, я пытаюсь найти наилучшую подходящую плоскость, используя SVD и Eigen.
мой алгоритм:
- центр данных указывает вокруг (0,0,0).
- форма 3XN матрица координат точек.
- вычислить SVD матрицы.
- установите наименьший сингулярный вектор, соответствующий наименьшему сингулярному значению, как Нормаль плоскости.
- установить расстояние от источника до плоскости нормальный∙центроид.
Я не могу понять, как использовать модуль SVD Eigen найти наименьший сингулярный вектор, соответствующий наименьшему сингулярному значению матрицы координат точек.
пока у меня есть этот код (шаги 1, 2 и 5 алгоритма):
Eigen::Matrix<float, 3, 1> mean = points.rowwise().mean();
const Eigen::Matrix3Xf points_centered = points.colwise() - mean;
int setting = Eigen::ComputeThinU | Eigen::ComputeThinV;
Eigen::JacobiSVD<Eigen::Matrix3Xf> svd = points_centered.jacobiSvd(setting);
Eigen::Vector3d normal = **???**
double d = normal.dot(mean);
2 ответов
обозначив U = svd.matrixU()
векторы U.col(0)
и U.col(1)
определяет основание вашей плоскости и U.col(2)
- это нормально для вашего самолета.
U.col(0)
также определяет направление с наибольшим стандартным отклонением.
вы должны использовать флаг ComputeFullU
вместо ComputeThinU
чтобы иметь правильные размеры, даже если ваши точки являются копланарными.
ваша проблема заключается в том, как сделать наименее квадратную подгонку с помощью модуля Eigen JacobiSVD. Вот ссылке С более полезным примером. Основная идея наименьшего квадрата заключается в том, что вы сначала берете разность векторов всех N-1 точек с одной из N точек, а затем пытаетесь аппроксимировать все такие N-1 векторы как линейную комбинацию двух базисных векторов, которые определяют 2D-плоскость.