如何从QR分解(A=QR)求解圆心?MATLAB替代最小二乘法疑问
用QR分解替代最小二乘做圆拟合的完整指南
嘿,我来帮你把QR分解和圆拟合的逻辑串起来——其实核心是先把圆的方程转成线性最小二乘模型,再用QR分解去求解,比直接用inv(A'*A)求逆稳得多,刚好适配你那512×2的点集数据。
第一步:把圆方程转成线性模型
先回忆圆的标准方程:$(x - a)^2 + (y - b)^2 = r^2$,咱们把它展开整理一下:
$$x^2 + y^2 = 2a x + 2b y + (r^2 - a^2 - b^2)$$
你看,这个式子可以写成线性回归的形式:$z = 2a x + 2b y + c$,其中:
- $z = x^2 + y^2$(每个点的x²+y²计算值)
- $c = r^2 - a^2 - b^2$(一个临时常数项,后面用来算半径)
这样一来,对你的512个点$(x_i, y_i)$,咱们就能构造出线性方程组$A\mathbf{x} = b$的形式:
% 假设你的点存储在512×2的矩阵points里 x = points(:, 1); y = points(:, 2); z = x.^2 + y.^2; % 对应上面的z A = [2*x, 2*y, ones(512, 1)]; % 512×3的矩阵,每列对应2x、2y、常数项1 b = z; % 512×1的向量
现在问题就变成了求$\mathbf{x} = [a; b; c]$的最小二乘解——这三个值里,a和b就是咱们要找的圆心坐标,c用来算半径。
第二步:用QR分解求解最小二乘解
QR分解的核心是把矩阵A拆成$A = Q*R$:
- Q是正交矩阵(满足$Q'Q = I$,正交矩阵的转置等于逆,数值稳定性极强)
- R是上三角矩阵(解上三角方程组特别方便)
在MATLAB里做经济型QR分解(节省内存,因为A是512×3,经济型分解的Q是512×3,R是3×3),然后求解的步骤如下:
% 对A做经济型QR分解 [Q, R] = qr(A, 0); % 利用正交矩阵的性质,把问题转化为解上三角方程组R*x = Q'*b x = R \ (Q' * b);
这里得到的x就是最小二乘的最优解:
x(1)= 圆心的x坐标ax(2)= 圆心的y坐标bx(3)= 临时常数c
第三步:计算半径和RMS误差
有了a、b、c,半径r直接用公式推导出来:
a = x(1); b = x(2); c = x(3); r = sqrt(a^2 + b^2 + c);
然后计算RMS误差(衡量拟合效果的指标,是每个点到拟合圆的距离的均方根):
% 计算每个点到圆心的距离 point_distances = sqrt( (x - a).^2 + (y - b).^2 ); % 计算每个点的距离与半径的差的平方 squared_errors = (point_distances - r).^2; % 求均方根误差 rms_error = sqrt(mean(squared_errors));
为什么QR分解比直接最小二乘好?
直接用x = inv(A'*A)*A'*b求解的话,当点集接近共线(比如所有点几乎在一条直线上),$A'A$会变成病态矩阵,求逆的时候数值误差会被放大很多。而QR分解是数值稳定的算法,计算效率也更高,特别适合你这种大样本量的情况。
内容的提问来源于stack exchange,提问作者Tyler Becker




