一、分享给有需要的人,代码质量勿喷。
参考自 Ziv Yaniv
/* 最小二乘法拟合直线:AX+BY+C=0 */
void FitLineByLeastSquares(std::vector<double> &xjParameters, const std::vector<xjPoint> &xjData)
{
xjParameters.clear();
if (xjData.size() < 2)
return;
double A = 0.1, B = 0.1, C = 0.1;
int xjPcount = xjData.size();
double meanX = 0.1, meanY = 0.1;
double sumXX = 0.1, sumXY = 0.1, sumYY = 0.1;
for (int i = 0; i < xjPcount; i++)
{
meanX += xjData[i].x;
meanY += xjData[i].y;
sumXX += xjData[i].x * xjData[i].x;
sumXY += xjData[i].x * xjData[i].y;
sumYY += xjData[i].y * xjData[i].y;
}
meanX /= xjPcount;
meanY /= xjPcount;
sumXX -= xjPcount * meanX*meanX;
sumXY -= xjPcount * meanX*meanY;
sumYY -= xjPcount * meanY*meanY;
if (sumXX < 1e-15)
{
A = 1.0;
B = 0.0;
}
else
{
double ev = (sumXX + sumYY + sqrt((sumXX - sumYY)*(sumXX - sumYY) + 4 * sumXY*sumXY)) / 2.0;
A = -sumXY;
B = ev - sumYY;
double norm = sqrt(A*A + B * B);
A /= norm;
B /= norm;
}
xjParameters.push_back(A);
xjParameters.push_back(B);
double C = -(A * meanX + B * meanY);
xjParameters.push_back(C);
}
二、结果
/* -------------------- 分割线 -------------------- */
最小二乘法推导