最小二乘法高精度拟合圆 c++
时间: 2023-07-19 11:40:49 浏览: 165
以下是C++实现最小二乘法高精度拟合圆的示例代码:
```c++
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <mpreal.h>
#include <Eigen/Core>
#include <Eigen/SVD>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
using namespace Eigen;
using namespace mpfr;
int main()
{
// 读取点集
vector<Point2d> points;
ifstream fin("points.txt");
double x, y;
while (fin >> x >> y) {
points.push_back(Point2d(x, y));
}
// 对点集进行坐标平移
Point2d mean = Point2d(0, 0);
for (const auto& p : points) {
mean += p;
}
mean /= points.size();
for (auto& p : points) {
p -= mean;
}
// 构造矩阵A和向量b
Matrix<mreal, Dynamic, 3> A(points.size(), 3);
Matrix<mreal, Dynamic, 1> b(points.size(), 1);
for (int i = 0; i < points.size(); ++i) {
A(i, 0) = 2 * points[i].x();
A(i, 1) = 2 * points[i].y();
A(i, 2) = 1;
b(i, 0) = points[i].x() * points[i].x() + points[i].y() * points[i].y();
}
// 解线性方程组
JacobiSVD<Matrix<mreal, Dynamic, 3>> svd(A, ComputeThinU | ComputeThinV);
Matrix<mreal, 3, 1> x = svd.solve(b);
mreal a = x(0), b = x(1), c = x(2);
// 计算圆心坐标和半径
mreal xc = -a, yc = -b;
mreal r = sqrt(a * a + b * b + c);
// 计算误差
mreal err = 0;
for (const auto& p : points) {
err += (p.x() - xc) * (p.x() - xc) + (p.y() - yc) * (p.y() - yc) - r * r;
}
err = fabs(err);
// 绘制拟合圆
Mat img = imread("image.jpg");
circle(img, Point(mean.x() + toFloat(xc), mean.y() + toFloat(yc)), toFloat(r), Scalar(0, 255, 0), 2);
imshow("img", img);
waitKey(0);
return 0;
}
```
在代码中,我们使用了mpfr库进行高精度计算,使用了Eigen库进行矩阵计算,使用了OpenCV库进行图像绘制。需要注意的是,在实际应用中,需要根据具体情况进行调整和优化。
阅读全文