|
#include <ceres/ceres.h>
#include <Eigen/Core>
// 定义残差类
struct OrthogonalDistanceResidual {
OrthogonalDistanceResidual(double observed_x, double observed_y)
: observed_x(observed_x), observed_y(observed_y) {}
template <typename T>
bool operator()(const T* const params, T* residual) const {
T xc = params[0];
T yc = params[1];
T slope = params[2];
T intercept = params[3];
// 计算点 (observed_x, observed_y) 到直线 y = slope * x + intercept 的正交距离
T predicted_y = slope * observed_x + intercept;
T dx = observed_x - xc;
T dy = observed_y - yc;
// 正交距离平方
residual[0] = dx * dx + dy * dy;
return true;
}
private:
const double observed_x;
const double observed_y;
};
int main(int argc, char** argv) {
google::InitGoogleLogging(argv[0]);
// 模拟数据点
std::vector<double> x_data = {1.0, 2.0, 3.0};
std::vector<double> y_data = {2.0, 2.9, 4.1};
// 初始参数:xc, yc, slope, intercept
double params[4] = {0.0, 0.0, 1.0, 1.0};
ceres::Problem problem;
for (size_t i = 0; i < x_data.size(); ++i) {
problem.AddResidualBlock(
new ceres::AutoDiffCostFunction<OrthogonalDistanceResidual, 1, 4>(
new OrthogonalDistanceResidual(x_data[i], y_data[i])),
nullptr,
params);
}
ceres::Solver::Options options;
options.linear_solver_type = ceres::DENSE_QR;
options.minimizer_progress_to_stdout = true;
ceres::Solver::Summary summary;
ceres::Solve(options, &problem, &summary);
std::cout << summary.FullReport() << "\n";
std::cout << "Estimated parameters: "
<< "xc=" << params[0] << ", yc=" << params[1]
<< ", slope=" << params[2] << ", intercept=" << params[3] << "\n";
return 0;
}
|
|