34 Optimization::Optimization(
int n_params,
int n_meas)
37 J = cvCreateMat(n_meas, n_params, CV_64F); cvZero(J);
38 JtJ = cvCreateMat(n_params, n_params, CV_64F); cvZero(JtJ);
39 tmp = cvCreateMat(n_params, n_meas, CV_64F); cvZero(tmp);
40 W = cvCreateMat(n_meas, n_meas, CV_64F); cvZero(W);
41 diag = cvCreateMat(n_params, n_params, CV_64F); cvZero(diag);
42 err = cvCreateMat(n_meas, 1, CV_64F); cvZero(err);
43 delta = cvCreateMat(n_params, 1, CV_64F); cvZero(delta);
44 x_minus = cvCreateMat(n_params, 1, CV_64F); cvZero(x_minus);
45 x_plus = cvCreateMat(n_params, 1, CV_64F); cvZero(x_plus);
46 x_tmp1 = cvCreateMat(n_meas, 1, CV_64F); cvZero(x_tmp1);
47 x_tmp2 = cvCreateMat(n_meas, 1, CV_64F); cvZero(x_tmp2);
48 tmp_par = cvCreateMat(n_params, 1, CV_64F); cvZero(tmp_par);
51 Optimization::~Optimization()
60 cvReleaseMat(&x_plus);
61 cvReleaseMat(&x_minus);
62 cvReleaseMat(&x_tmp1);
63 cvReleaseMat(&x_tmp2);
64 cvReleaseMat(&tmp_par);
68 double Optimization::CalcTukeyWeight(
double residual,
double c)
73 if(fabs(residual) <= c)
75 double tmp = 1.0-((residual/c)*(residual/c));
76 ret = ((c*c)/6.0)*(1.0-tmp*tmp*tmp);
82 ret = fabs(sqrt(ret)/residual);
89 double Optimization::CalcTukeyWeightSimple(
double residual,
double c)
94 double x2 = residual*residual;
95 if(x2<c*c)
return residual;
99 void Optimization::CalcJacobian(CvMat* x, CvMat* J, EstimateCallback
Estimate)
101 const double step = 0.001;
104 for (
int i=0; i<J->cols; i++)
107 cvGetCol(J, &J_column, i);
110 cvmSet(delta, i, 0, step);
111 cvAdd(x, delta, x_plus);
112 cvmSet(delta, i, 0, -step);
113 cvAdd(x, delta, x_minus);
115 Estimate(x_plus, x_tmp1, estimate_param);
116 Estimate(x_minus, x_tmp2, estimate_param);
117 cvSub(x_tmp1, x_tmp2, &J_column);
118 cvScale(&J_column, &J_column, 1.0/(2*step));
123 double Optimization::Optimize(CvMat* parameters,
130 CvMat* parameters_mask,
135 int n_params = parameters->rows;
136 int n_meas = measurements->rows;
137 double error_new = 0;
138 double error_old = 0;
141 estimate_param = param;
147 CalcJacobian(parameters, J, Estimate);
154 for (
int i=0; i<parameters_mask->rows; i++) {
155 if (cvGet2D(parameters_mask, i, 0).val[0] == 0) {
157 rect.height = J->rows; rect.width = 1;
158 rect.y = 0; rect.x = i;
160 cvGetSubRect(J, &foo, rect);
165 Estimate(parameters, x_tmp1, estimate_param);
166 cvSub(measurements, x_tmp1, err);
167 error_old = cvNorm(err, 0, CV_L2);
173 cvMulTransposed(J, JtJ, 1);
174 cvInv(JtJ, JtJ, CV_SVD);
175 cvGEMM(JtJ, J, 1.0, 0, 0, tmp, CV_GEMM_B_T);
176 cvMatMul(tmp, err, delta);
177 cvAdd(delta, parameters, parameters);
181 n2 = cvNorm(parameters);
183 if( ((n1/n2) < stop) ||
189 case (LEVENBERGMARQUARDT) :
191 cvSetIdentity(diag, cvRealScalar(lambda));
194 for(
int k = 0; k < W->rows; ++k)
195 cvmSet(W, k, k, weights->data.db[k]);
200 cvGEMM(J, W, 1, 0, 0, tmp, CV_GEMM_A_T);
201 cvGEMM(tmp, J, 1, 0, 0, JtJ, 0);
204 cvMulTransposed(J, JtJ, 1);
208 cvAdd(JtJ, diag, JtJ);
209 cvInv(JtJ, JtJ, CV_SVD);
210 cvGEMM(JtJ, J, 1.0, 0, 0, tmp, CV_GEMM_B_T);
213 cvGEMM(tmp, W, 1, 0, 0, tmp, 0);
215 cvMatMul(tmp, err, delta);
216 cvAdd(delta, parameters, tmp_par);
218 Estimate(tmp_par, x_tmp1, estimate_param);
219 cvSub(measurements, x_tmp1, err);
221 error_new = cvNorm(err, 0, CV_L2);
223 if(error_new < error_old)
225 cvCopy(tmp_par, parameters);
226 lambda = lambda/10.0;
230 lambda = lambda*10.0;
232 if(lambda>10) lambda = 10;
233 if(lambda<0.00001) lambda = 0.00001;
236 n2 = cvNorm(parameters);
238 if( (n1/n2) < stop ||
248 cvSetIdentity(diag, cvRealScalar(lambda));
251 for(
int k = 0; k < W->rows; ++k)
254 if(weights->data.db[k] != -1.0)
255 cvmSet(W, k, k, weights->data.db[k]);
257 cvmSet(W, k, k, CalcTukeyWeight(err->data.db[k], 3));
259 cvmSet(W, k, k, CalcTukeyWeight(err->data.db[k], 3));
262 cvGEMM(J, W, 1, 0, 0, tmp, CV_GEMM_A_T);
263 cvGEMM(tmp, J, 1, 0, 0, JtJ, 0);
264 cvAdd(JtJ, diag, JtJ);
265 cvInv(JtJ, JtJ, CV_SVD);
266 cvGEMM(JtJ, J, 1.0, 0, 0, tmp, CV_GEMM_B_T);
267 cvGEMM(tmp, W, 1, 0, 0, tmp, 0);
268 cvMatMul(tmp, err, delta);
269 cvAdd(delta, parameters, tmp_par);
271 Estimate(tmp_par, x_tmp1, estimate_param);
272 cvSub(measurements, x_tmp1, err);
274 error_new = cvNorm(err, 0, CV_L2);
276 if(error_new < error_old)
278 cvCopy(tmp_par, parameters);
279 lambda = lambda/10.0;
283 lambda = lambda*10.0;
285 if(lambda>10) lambda = 10;
286 if(lambda<0.00001) lambda = 0.00001;
289 n2 = cvNorm(parameters);
291 if( ((n1/n2) < stop) ||
void Estimate(CvMat *state, CvMat *projection, void *param)
OptimizeMethod
Selection between the algorithm used in optimization. Following should be noticed: ...
This file implements several optimization algorithms.
This file defines library export definitions, version numbers and build information.