最小二乘法拟合椭圆的csharp完整代码
时间: 2023-10-17 07:06:13 浏览: 149
椭圆最小二乘拟合
以下是使用最小二乘法拟合椭圆的C#完整代码:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace EllipseFitting
{
class Program
{
static void Main(string[] args)
{
// 生成随机点坐标
Random random = new Random();
List<PointF> points = new List<PointF>();
for (int i = 0; i < 100; i++)
{
float x = (float)random.NextDouble() * 200 + 50;
float y = (float)random.NextDouble() * 200 + 50;
points.Add(new PointF(x, y));
}
// 拟合椭圆
Ellipse ellipse = EllipseFitting(points);
// 绘制拟合的椭圆和原始点
Bitmap bmp = new Bitmap(300, 300);
Graphics g = Graphics.FromImage(bmp);
Pen pen = new Pen(Color.Red);
g.DrawEllipse(pen, ellipse.X - ellipse.A, ellipse.Y - ellipse.B, ellipse.A * 2, ellipse.B * 2);
pen = new Pen(Color.Blue);
foreach (PointF point in points)
{
g.DrawRectangle(pen, point.X, point.Y, 1, 1);
}
bmp.Save("ellipse.bmp");
}
// 最小二乘法拟合椭圆
static Ellipse EllipseFitting(List<PointF> points)
{
// 将点坐标转换为二次型的形式
List<double[]> data = new List<double[]>();
foreach (PointF point in points)
{
double[] item = new double[6];
item[0] = point.X * point.X;
item[1] = point.X * point.Y;
item[2] = point.Y * point.Y;
item[3] = point.X;
item[4] = point.Y;
item[5] = 1.0;
data.Add(item);
}
// 计算二次型的协方差矩阵
double[,] cov = new double[6, 6];
for (int i = 0; i < 6; i++)
{
for (int j = 0; j < 6; j++)
{
double sum = 0;
for (int k = 0; k < points.Count; k++)
{
sum += data[k][i] * data[k][j];
}
cov[i, j] = sum;
}
}
// 计算协方差矩阵的逆矩阵
double[,] inv = MatrixInverse(cov);
// 计算中心点坐标
double[] center = new double[6];
for (int i = 0; i < 6; i++)
{
double sum = 0;
for (int j = 0; j < points.Count; j++)
{
sum += data[j][i];
}
center[i] = sum / points.Count;
}
// 计算椭圆参数
double a = inv[0, 0] * center[0] + inv[0, 1] * center[1] + inv[0, 2] * center[2];
double b = inv[0, 1] * center[0] + inv[1, 1] * center[1] + inv[1, 2] * center[2];
double c = inv[0, 2] * center[0] + inv[1, 2] * center[1] + inv[2, 2] * center[2];
double d = inv[0, 3] * center[0] + inv[1, 3] * center[1] + inv[2, 3] * center[2];
double e = inv[0, 4] * center[0] + inv[1, 4] * center[1] + inv[2, 4] * center[2];
double f = inv[0, 5] * center[0] + inv[1, 5] * center[1] + inv[2, 5] * center[2];
// 计算椭圆的中心坐标和长短半轴长度
double delta = b * b - 4 * a * c;
double x0 = (2 * c * d - b * e) / delta;
double y0 = (2 * a * e - b * d) / delta;
double A = Math.Sqrt((2 * (a * x0 * x0 + c * y0 * y0 + b * x0 * y0 - f)) / ((a + c) + Math.Sqrt(delta)));
double B = Math.Sqrt((2 * (a * x0 * x0 + c * y0 * y0 + b * x0 * y0 - f)) / ((a + c) - Math.Sqrt(delta)));
return new Ellipse(x0, y0, A, B);
}
// 计算矩阵的逆矩阵
static double[,] MatrixInverse(double[,] matrix)
{
int size = matrix.GetLength(0);
double[,] inv = new double[size, size];
double det = MatrixDeterminant(matrix);
if (det == 0) throw new Exception("The matrix is singular.");
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
double[,] subMatrix = SubMatrix(matrix, i, j);
inv[j, i] = MatrixDeterminant(subMatrix) / det * Math.Pow(-1, i + j);
}
}
return inv;
}
// 计算矩阵的行列式
static double MatrixDeterminant(double[,] matrix)
{
int size = matrix.GetLength(0);
if (size == 1) return matrix[0, 0];
if (size == 2) return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
double det = 0;
for (int i = 0; i < size; i++)
{
double[,] subMatrix = SubMatrix(matrix, 0, i);
det += matrix[0, i] * MatrixDeterminant(subMatrix) * Math.Pow(-1, i);
}
return det;
}
// 计算矩阵的子矩阵
static double[,] SubMatrix(double[,] matrix, int row, int col)
{
int size = matrix.GetLength(0);
double[,] subMatrix = new double[size - 1, size - 1];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
if (i < row && j < col) subMatrix[i, j] = matrix[i, j];
if (i < row && j > col) subMatrix[i, j - 1] = matrix[i, j];
if (i > row && j < col) subMatrix[i - 1, j] = matrix[i, j];
if (i > row && j > col) subMatrix[i - 1, j - 1] = matrix[i, j];
}
}
return subMatrix;
}
}
// 椭圆类
class Ellipse
{
public double X, Y, A, B;
public Ellipse(double x, double y, double a, double b)
{
X = x;
Y = y;
A = a;
B = b;
}
}
}
注意:本代码仅供参考,实际使用时需要根据具体情况进行调整和优化。
阅读全文