Q3D-Calibration/include/GaussFit.h

81 lines
2.0 KiB
C++

#pragma once
#ifndef gauss_fit_h
#define gauss_fit_h
#include "GaussNewton.h"
#include "LevenbergMarquardt.h"
#include "clip.h"
#include "utils.h"
#include <Eigen/Dense>
#include <iostream>
double Gaussian(double x, double* p) {
return p[0] * std::exp(-(x - p[1]) * (x - p[1]) / (2 * p[2] * p[2]));
}
double* GaussianJacobian(double x, double* p) {
double* resJ = new double[3];
resJ[0] = -Gaussian(x, p) / p[0];
resJ[1] = -(x - p[1]) * Gaussian(x, p) / (p[2] * p[2]);
resJ[2] = -(x - p[1]) * (x - p[1]) * Gaussian(x, p) / (p[2] * p[2] * p[2]);
return resJ;
}
class GaussFit {
public:
GaussFit();
~GaussFit();
public:
void addData(double x, double y);
double* fit(int type_ = 0);
public:
double* parma = new double[3];
std::vector<Eigen::Vector2d> data;
};
GaussFit::GaussFit() {}
GaussFit::~GaussFit() {}
void GaussFit::addData(double x, double y) { data.push_back(Eigen::Vector2d(x, y)); }
double* GaussFit::fit(int type_) {
int n = data.size();
double x, y, sigma;
SigmaClip* SC = new SigmaClip();
data = SC->clip(data);
parma[0] = dataMax(data);
parma[1] = dataAvg(data);
parma[2] = dataStd(data);
// for (int i = 0; i < data.size(); i++) {
// Eigen::Vector2d &point = data.at(i);
// x = point(0), y = point(1);
// std::cout << x << " " << y << std::endl;
// }
// std::cout << parma[0] << " " << parma[1] << ", " << parma[2] << std::endl;
if (type_ == 0) {
LevenbergMarquardt LM(3, parma, Gaussian, GaussianJacobian);
LM.data = data;
parma = LM.solve();
} else if (type_ == 1) {
LevenbergMarquardt LM(3, parma, Gaussian, GaussianJacobian, type_ = type_);
LM.data = data;
parma = LM.solve();
} else {
GaussNewton GN(3, parma, Gaussian, GaussianJacobian);
GN.data = data;
parma = GN.solve();
}
// std::cout << parma[0] << " " << parma[1] << ", " << parma[2] << std::endl;
return parma;
}
#endif