gpt4 book ai didi

c++ - 如何围绕一组二维点拟合边界椭圆

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:45:14 31 4
gpt4 key购买 nike

给定一组二维点(笛卡尔形式),我需要找到最小面积的椭圆,使得集合中的每个点都位于椭圆上或椭圆内。

我有found the solution在此站点上以伪代码的形式出现,但我尝试用 C++ 实现该解决方案没有成功。

下图以图形方式说明了我的问题的解决方案:

a set of points with a bounding ellipse

在我的尝试中,我使用了 Eigen用于矩阵各种操作的库。

//The tolerance for error in fitting the ellipse
double tolerance = 0.2;
int n = 10; // number of points
int d = 2; // dimension
MatrixXd p = MatrixXd::Random(d,n); //Fill matrix with random points

MatrixXd q = p;
q.conservativeResize(p.rows() + 1, p.cols());

for(size_t i = 0; i < q.cols(); i++)
{
q(q.rows() - 1, i) = 1;
}

int count = 1;
double err = 1;

const double init_u = 1.0 / (double) n;
MatrixXd u = MatrixXd::Constant(n, 1, init_u);


while(err > tolerance)
{
MatrixXd Q_tr = q.transpose();
cout << "1 " << endl;
MatrixXd X = q * u.asDiagonal() * Q_tr;
cout << "1a " << endl;
MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();
cout << "1b " << endl;



int j_x, j_y;
double maximum = M.maxCoeff(&j_x, &j_y);
double step_size = (maximum - d - 1) / ((d + 1) * (maximum + 1));

MatrixXd new_u = (1 - step_size) * u;
new_u(j_x, 0) += step_size;

cout << "2 " << endl;

//Find err
MatrixXd u_diff = new_u - u;
for(size_t i = 0; i < u_diff.rows(); i++)
{
for(size_t j = 0; j < u_diff.cols(); j++)
u_diff(i, j) *= u_diff(i, j); // Square each element of the matrix
}
err = sqrt(u_diff.sum());
count++;
u = new_u;
}

cout << "3 " << endl;
MatrixXd U = u.asDiagonal();
MatrixXd A = (1.0 / (double) d) * (p * U * p.transpose() - (p * u) * (p * u).transpose()).inverse();
MatrixXd c = p * u;

错误发生在以下行:

MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();

内容如下:

    run: /usr/include/eigen3/Eigen/src/Core/DenseBase.h:261: void Eigen::DenseBase<Derived>::resize(Eigen::Index, Eigen::Index) [with Derived = Eigen::Diagonal<Eigen::Matrix<double, -1, -1>, 0>; Eigen::Index = long int]: Assertion `rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize."' failed.
Aborted (core dumped)

有人可以指出为什么会发生这个错误,或者更好的是,给我一些关于如何使用 C++ 将椭圆拟合到一组点的建议?

最佳答案

使用 Eigen,您可以使用 .diagonal() 从矩阵中获取对角 vector ;您可以使用 .asDiagonal() 将 vector 视为对角矩阵;但您不能将密集矩阵视为对角矩阵。所以那一行应该是

MatrixXd M = (Q_tr * X.inverse() * q).diagonal(); 

关于c++ - 如何围绕一组二维点拟合边界椭圆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37911213/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com