cvLevenbergMarquardtOptimizationで最小化

#contents

*void cvLevenbergMarquardtOptimization [#o8253b9f]
void cvLevenbergMarquardtOptimization(pointer_LMJac JacobianFunction, pointer_LMFunc function, 
CvMat *X0, CvMat *observRes, CvMat *resultX, 
int maxIter, double epsilon);

な,長い・・・

*引数 [#y9be9d8f]

-JacobianFunction:pointer_LMJac型のヤコビアン行列を返す関数のポインタ
-function:pointer_LMJac型の計算値を返す関数のポインタ
-X0:CvMat*型の初期値
-observRes:CvMat*型の観測値
-resultX:CvMat*型の結果
-maxIter:int型の最大反復回数
-epsilon:double型の収束しきい値

*解説 [#n08a6e9f]

-pointer_LMJac型とはfunction( const CvMat*src, CvMat* dst)という形の関数
-関数を2つ作る
--srcを引数としてdstに計算値を代入する関数
--srcを引数としてdstに編微分を羅列した関数行列を返す関数
-X0には初期値,observResは観測値,あとは反復回数と収束しきい値を指定する

-関数について
--例えばP行列は未知数11の行列で,計算値は2次元座標
--''PX''='''x'''
--ここで''P''が未知で''X''が既知,'''x'''が観測できる値
--例えば10点の座標から''P''を推定する場合,srcは11行1列のベクトルになり,dstは10*2(次元)で20行1列のベクトルとなる.
--既知の3次元座標はあらかじめ何とか渡しておかなければならない.
-ヤコビ行列を返す関数は理論的には要らないはず(Levenberg-Marquradt法は本来そういうもの)なのだが,何故か関数を求められる上に,NULLポインタでごまかすこともできない.

//なーんも分からん.
//ただ,OpenCVにLevenbergMarquardt法による最小化が実装されていたことしか分からん.
//使い方・・・ヘルプ

*返り値 [#sb0c5fef]

-voidなので返さない

*サンプルコード [#vf411e8b]

#geshi(c++,number){{
 //cvaux/src/cvlevmartif.cppにTriFocalを求める過程でLevenbergMarqurdtが求められている.
 #include <cvlevmar.cpp>
 #include <cv.h>
 #include <cvaux.h>
 #include <cxcore.h>
 #include <highgui.h>
 #include <stdio.h>
 #include <math.h>
 #define	A	100
 #define	B	102
 #define	PRECISION	100
 #define	DERIV_STEP	0.00001
 
 void	CalcDiff( const CvMat *src, CvMat *dst);
 void	CalcDerivDiff( const CvMat *src, CvMat *dst);
 double	coreCalculation( const CvMat *src, double x);
 
 int	main(){
 	CvMat	*src, *dst, *X0, *res;
 	FILE *fp = fopen("./data", "w");
 	fclose(fp);
 	X0	= cvCreateMat(2, 1, CV_64F);
 	src	= cvCreateMat(2, 1, CV_64F);
 	dst	= cvCreateMat(PRECISION, 1, CV_64F);
 	res	= cvCreateMat(X0->rows, X0->cols, CV_64F);
 	cvmSet(X0, 0, 0, 100);
 	cvmSet(X0, 1, 0, 102);
 	CalcDiff(X0, dst);
 	cvmSet(X0, 0, 0, 0);
 	cvmSet(X0, 1, 0, 0);
 	cvLevenbergMarquardtOptimization((pointer_LMJac)CalcDerivDiff, (pointer_LMFunc)CalcDiff, X0, dst, res, 50, 0.01);
 	return 0;
 }
 
 void	CalcDiff( const CvMat *src, CvMat *dst){
 	int	i;
 	double	x, val;
 	FILE *fp = fopen("./data", "a");
 	static	count = 0;
 	printf("%d repeat\n", count++);
 	for(i = 0;i < PRECISION;i++){
 		x = CV_PI * ((double)i / PRECISION);
 		val = coreCalculation(src, x);
 		cvmSet(dst, i, 0, val);
 		fprintf(fp, "%f\t", cvmGet(dst, i, 0));
 	}
 	fprintf(fp, "\n");
 }
 
 void	CalcDerivDiff( const CvMat *src, CvMat *dst){
 	int	i, j;
 	double	x, val, nextval;
 	CvMat	*next = cvCreateMat(src->rows,src->cols,src->type);
 	for(j = 0;j < 2;j++){
 		cvCopy( src, next);
 		cvmSet(next, j, 0, cvmGet(src, j, 0) + DERIV_STEP);
 		for(i = 0;i < PRECISION;i++){
 			x = CV_PI * ((double)i / PRECISION);
 			val = coreCalculation(src, x);
 			nextval = coreCalculation(next, x);
 			cvmSet(dst, i, j, nextval - val);
 		}
 	}
 }
 
 double	coreCalculation( const CvMat *src, double x){
 	double a = cvmGet(src, 0, 0);
 	double b = cvmGet(src, 1, 0);
 	//return a*cos(b*x) + b*sin(a*x);
 	return a*cos(3*x) + b*sin(60*x);
 }
}} 

*実体ファイル [#ubfd0697]
-OpenCV 1.1以前
--cvaux/src/cvlevmartif.cpp
--cvaux/src/cvlevmar.cpp
-OpenCV 2.1
--src/cv/cvcalibcation.cpp
--include/cv.hpp
-OpenCV 2.2以降
--opencv2/calib3d/calib3d.hpp
--modules/calib3d/src/calibration.cpp

ジャンル[[:OpenCV]][[:OpenCV 1.0]][[:OpenCV 2.1]][[:OpenCV 2.2]][[:OpenCV 2.3]]準拠

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS