int LeastSquaresLineFit(cv::Mat srcImage, cv::Mat& dstImage, vector<Point> points, Mat& result)
{
dstImage = srcImage.clone();
//cv::cvtColor(dstImage, dstImage, COLOR_GRAY2BGR);
for (int i = 0; i < points.size(); i++)
{
//在原图上画出点
circle(dstImage, points[i], 3, Scalar(255, 0, 0), 1, 8);
}
//构建A矩阵
int N = 2;
Mat A = Mat::zeros(N, N, CV_64FC1);
for (int row = 0; row < A.rows; row++)
{
for (int col = 0; col < A.cols; col++)
{
for (int k = 0; k < points.size(); k++)
{
A.at<double>(row, col) = A.at<double>(row, col) + pow(points[k].x, row + col);
}
}
}
//构建B矩阵
Mat B = Mat::zeros(N, 1, CV_64FC1);
for (int row = 0; row < B.rows; row++)
{
for (int k = 0; k < points.size(); k++)
{
B.at<double>(row, 0) = B.at<double>(row, 0) + pow(points[k].x, row) * points[k].y;
}
}
//A*X=B
Mat X;
//cout << A << endl << B << endl;
solve(A, B, X, DECOMP_LU);
cout << "[k;b]=" << X << endl;
result = X;
vector<Point>lines;
for (int x = 0; x < srcImage.size().width; x++)
{ // y = b + ax;
double y = X.at<double>(0, 0) + X.at<double>(1, 0) * x;
printf("(%d,%lf)\n", x, y);
lines.push_back(Point(x, y));
}
polylines(dstImage, lines, false, Scalar(0, 0, 255), 1, 8);
//namedWindow("srcImageLine",0);
//imshow("srcImageLine", dstImage);
return 0;
}
例子调用:
vector<Point>points;
//(27 39) (8 5) (8 9) (16 22) (44 71) (35 44) (43 57) (19 24) (27 39) (37 52)
points.push_back(Point(27, 39));
points.push_back(Point(8, 5));
points.push_back(Point(8, 9));
points.push_back(Point(16, 22));
points.push_back(Point(44, 71));
points.push_back(Point(35, 44));
points.push_back(Point(43, 57));
points.push_back(Point(19, 24));
points.push_back(Point(27, 39));
points.push_back(Point(37, 52));
Mat src = Mat(400, 400, CV_8UC3,Scalar(255,255,255));
Mat dstImage, result;
LeastSquaresLineFit(src, dstImage, points, result);
imwrite("a4.jpg", dstImage);