1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
43 #include "precomp.hpp"
48 void icvReconstructPoints4DStatus(CvMat** projPoints, CvMat **projMatrs, CvMat** presPoints, CvMat *points4D,int numImages,CvMat **projError=0);
52 /* If you want to save internal debug info to files uncomment next lines and set paths to files if need */
53 /* Note these file may be very large */
56 #define TRACK_BUNDLE_FILE "d:\\test\\bundle.txt"
57 #define TRACK_BUNDLE_FILE_JAC "d:\\test\\bundle.txt"
58 #define TRACK_BUNDLE_FILE_JACERRPROJ "d:\\test\\JacErrProj.txt"
59 #define TRACK_BUNDLE_FILE_JACERRPNT "d:\\test\\JacErrPoint.txt"
60 #define TRACK_BUNDLE_FILE_MATRW "d:\\test\\matrWt.txt"
61 #define TRACK_BUNDLE_FILE_DELTAP "d:\\test\\deltaP.txt"
63 #define TRACK_BUNDLE_FILE "d:\\test\\bundle.txt"
65 void cvOptimizeLevenbergMarquardtBundle( CvMat** projMatrs, CvMat** observProjPoints,
66 CvMat** pointsPres, int numImages,
67 CvMat** resultProjMatrs, CvMat* resultPoints4D,int maxIter,double epsilon );
70 /* ============== Bundle adjustment optimization ================= */
71 static void icvComputeDerivateProj(CvMat *points4D,CvMat *projMatr, CvMat *status, CvMat *derivProj)
73 /* Compute derivate for given projection matrix points and status of points */
75 CV_FUNCNAME( "icvComputeDerivateProj" );
79 /* ----- Test input params for errors ----- */
80 if( points4D == 0 || projMatr == 0 || status == 0 || derivProj == 0)
82 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
85 if( !CV_IS_MAT(points4D) )
87 CV_ERROR( CV_StsUnsupportedFormat, "points4D must be a matrix 4xN" );
90 /* Compute number of points */
92 numPoints = points4D->cols;
96 CV_ERROR( CV_StsOutOfRange, "Number of points4D must be more than zero" );
99 if( points4D->rows != 4 )
101 CV_ERROR( CV_StsOutOfRange, "Number of coordinates of points4D must be 4" );
104 if( !CV_IS_MAT(projMatr) )
106 CV_ERROR( CV_StsUnsupportedFormat, "projMatr must be a matrix 3x4" );
109 if( projMatr->rows != 3 || projMatr->cols != 4 )
111 CV_ERROR( CV_StsOutOfRange, "Size of projection matrix (projMatr) must be 3x4" );
114 if( !CV_IS_MAT(status) )
116 CV_ERROR( CV_StsUnsupportedFormat, "Status must be a matrix 1xN" );
119 if( status->rows != 1 || status->cols != numPoints )
121 CV_ERROR( CV_StsOutOfRange, "Size of status of points must be 1xN" );
124 if( !CV_IS_MAT(derivProj) )
126 CV_ERROR( CV_StsUnsupportedFormat, "derivProj must be a matrix VisN x 12" );
129 if( derivProj->cols != 12 )
131 CV_ERROR( CV_StsOutOfRange, "derivProj must be a matrix VisN x 12" );
133 /* ----- End test ----- */
135 /* Allocate memory for derivates */
138 /* Copy projection matrix */
139 for(int i = 0; i < 12; i++ )
141 p[i] = cvmGet(projMatr,i/4,i%4);
144 /* Fill deriv matrix */
149 for( currPoint = 0; currPoint < numPoints; currPoint++ )
151 if( cvmGet(status,0,currPoint) > 0 )
154 X[0] = cvmGet(points4D,0,currVisPoint);
155 X[1] = cvmGet(points4D,1,currVisPoint);
156 X[2] = cvmGet(points4D,2,currVisPoint);
157 X[3] = cvmGet(points4D,3,currVisPoint);
159 /* Compute derivate for this point */
162 piX[0] = X[0]*p[0] + X[1]*p[1] + X[2]*p[2] + X[3]*p[3];
163 piX[1] = X[0]*p[4] + X[1]*p[5] + X[2]*p[6] + X[3]*p[7];
164 piX[2] = X[0]*p[8] + X[1]*p[9] + X[2]*p[10] + X[3]*p[11];
166 /* fill derivate by point */
168 double tmp3 = 1/(piX[2]*piX[2]);
170 double tmp1 = -piX[0]*tmp3;
171 double tmp2 = -piX[1]*tmp3;
173 /* fill derivate by projection matrix */
174 for(int i = 0; i < 4; i++ )
177 cvmSet(derivProj,currVisPoint*2,i,X[i]/piX[2]);//x' p1i
178 cvmSet(derivProj,currVisPoint*2,4+i,0);//x' p1i
179 cvmSet(derivProj,currVisPoint*2,8+i,X[i]*tmp1);//x' p3i
182 cvmSet(derivProj,currVisPoint*2+1,i,0);//y' p2i
183 cvmSet(derivProj,currVisPoint*2+1,4+i,X[i]/piX[2]);//y' p2i
184 cvmSet(derivProj,currVisPoint*2+1,8+i,X[i]*tmp2);//y' p3i
191 if( derivProj->rows != currVisPoint * 2 )
193 CV_ERROR( CV_StsOutOfRange, "derivProj must be a matrix 2VisN x 12" );
200 /*======================================================================================*/
202 static void icvComputeDerivateProjAll(CvMat *points4D, CvMat **projMatrs, CvMat **pointPres, int numImages,CvMat **projDerives)
204 CV_FUNCNAME( "icvComputeDerivateProjAll" );
207 /* ----- Test input params for errors ----- */
210 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
212 if( projMatrs == 0 || pointPres == 0 || projDerives == 0 )
214 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
216 /* ----- End test ----- */
219 for( currImage = 0; currImage < numImages; currImage++ )
221 icvComputeDerivateProj(points4D,projMatrs[currImage], pointPres[currImage], projDerives[currImage]);
227 /*======================================================================================*/
229 static void icvComputeDerivatePoints(CvMat *points4D,CvMat *projMatr, CvMat *presPoints, CvMat *derivPoint)
232 CV_FUNCNAME( "icvComputeDerivatePoints" );
235 /* ----- Test input params for errors ----- */
236 if( points4D == 0 || projMatr == 0 || presPoints == 0 || derivPoint == 0)
238 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
241 if( !CV_IS_MAT(points4D) )
243 CV_ERROR( CV_StsUnsupportedFormat, "points4D must be a matrix N x 4" );
247 numPoints = presPoints->cols;
251 CV_ERROR( CV_StsOutOfRange, "Number of points must be more than zero" );
254 if( points4D->rows != 4 )
256 CV_ERROR( CV_StsOutOfRange, "points4D must be a matrix N x 4" );
259 if( !CV_IS_MAT(projMatr) )
261 CV_ERROR( CV_StsUnsupportedFormat, "projMatr must be a matrix 3x4" );
264 if( projMatr->rows != 3 || projMatr->cols != 4 )
266 CV_ERROR( CV_StsOutOfRange, "Size of projection matrix (projMatr) must be 3x4" );
269 if( !CV_IS_MAT(presPoints) )
271 CV_ERROR( CV_StsUnsupportedFormat, "Status must be a matrix 1xN" );
274 if( presPoints->rows != 1 || presPoints->cols != numPoints )
276 CV_ERROR( CV_StsOutOfRange, "Size of presPoints status must be 1xN" );
279 if( !CV_IS_MAT(derivPoint) )
281 CV_ERROR( CV_StsUnsupportedFormat, "derivPoint must be a matrix 2 x 4VisNum" );
283 /* ----- End test ----- */
285 /* Compute derivates by points */
288 for(int i = 0; i < 12; i++ )
290 p[i] = cvmGet(projMatr,i/4,i%4);
297 for( currProjPoint = 0; currProjPoint < numPoints; currProjPoint++ )
299 if( cvmGet(presPoints,0,currProjPoint) > 0 )
302 X[0] = cvmGet(points4D,0,currProjPoint);
303 X[1] = cvmGet(points4D,1,currProjPoint);
304 X[2] = cvmGet(points4D,2,currProjPoint);
305 X[3] = cvmGet(points4D,3,currProjPoint);
308 piX[0] = X[0]*p[0] + X[1]*p[1] + X[2]*p[2] + X[3]*p[3];
309 piX[1] = X[0]*p[4] + X[1]*p[5] + X[2]*p[6] + X[3]*p[7];
310 piX[2] = X[0]*p[8] + X[1]*p[9] + X[2]*p[10] + X[3]*p[11];
312 double tmp3 = 1/(piX[2]*piX[2]);
314 for(int j = 0; j < 2; j++ )//for x and y
316 for(int i = 0; i < 4; i++ )// for X,Y,Z,W
320 (p[j*4+i]*piX[2]-p[8+i]*piX[j]) * tmp3 );
327 if( derivPoint->rows != 2 || derivPoint->cols != currVisPoint*4 )
329 CV_ERROR( CV_StsUnsupportedFormat, "derivPoint must be a matrix 2 x 4VisNum" );
336 /*======================================================================================*/
337 static void icvComputeDerivatePointsAll(CvMat *points4D, CvMat **projMatrs, CvMat **pointPres, int numImages,CvMat **pointDerives)
339 CV_FUNCNAME( "icvComputeDerivatePointsAll" );
342 /* ----- Test input params for errors ----- */
345 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
347 if( projMatrs == 0 || pointPres == 0 || pointDerives == 0 )
349 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
351 /* ----- End test ----- */
354 for( currImage = 0; currImage < numImages; currImage++ )
356 icvComputeDerivatePoints(points4D, projMatrs[currImage], pointPres[currImage], pointDerives[currImage]);
362 /*======================================================================================*/
363 static void icvComputeMatrixVAll(int numImages,CvMat **pointDeriv,CvMat **presPoints, CvMat **matrV)
367 CV_FUNCNAME( "icvComputeMatrixVAll" );
370 /* ----- Test input params for errors ----- */
373 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
375 if( pointDeriv == 0 || presPoints == 0 || matrV == 0 )
377 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
379 /* !!! not tested all parameters */
380 /* ----- End test ----- */
382 /* Compute all matrices U */
386 numPoints = presPoints[0]->cols;
387 CV_CALL(shifts = (int*)cvAlloc(sizeof(int)*numImages));
388 memset(shifts,0,sizeof(int)*numImages);
390 for( currPoint = 0; currPoint < numPoints; currPoint++ )//For each point (matrix V)
394 for( i = 0; i < 4; i++ )
396 for( j = 0; j < 4; j++ )
399 for( currImage = 0; currImage < numImages; currImage++ )
401 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
403 sum += cvmGet(pointDeriv[currImage],0,shifts[currImage]*4+i) *
404 cvmGet(pointDeriv[currImage],0,shifts[currImage]*4+j);
406 sum += cvmGet(pointDeriv[currImage],1,shifts[currImage]*4+i) *
407 cvmGet(pointDeriv[currImage],1,shifts[currImage]*4+j);
411 cvmSet(matrV[currPoint],i,j,sum);
416 /* shift position of visible points */
417 for( currImage = 0; currImage < numImages; currImage++ )
419 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
431 /*======================================================================================*/
432 static void icvComputeMatrixUAll(int numImages,CvMat **projDeriv,CvMat** matrU)
434 CV_FUNCNAME( "icvComputeMatrixVAll" );
436 /* ----- Test input params for errors ----- */
439 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
441 if( projDeriv == 0 || matrU == 0 )
443 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
445 /* !!! Not tested all input parameters */
446 /* ----- End test ----- */
448 /* Compute matrices V */
450 for( currImage = 0; currImage < numImages; currImage++ )
452 cvMulTransposed(projDeriv[currImage],matrU[currImage],1);
458 /*======================================================================================*/
459 static void icvComputeMatrixW(int numImages, CvMat **projDeriv, CvMat **pointDeriv, CvMat **presPoints, CvMat *matrW)
461 CV_FUNCNAME( "icvComputeMatrixW" );
464 /* ----- Test input params for errors ----- */
467 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
469 if( projDeriv == 0 || pointDeriv == 0 || presPoints == 0 || matrW == 0 )
471 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
474 numPoints = presPoints[0]->cols;
477 CV_ERROR( CV_StsOutOfRange, "Number of points must more than zero" );
479 if( !CV_IS_MAT(matrW) )
481 CV_ERROR( CV_StsUnsupportedFormat, "matrW must be a matrix 12NumIm x 4NumPnt" );
483 if( matrW->rows != numImages*12 || matrW->cols != numPoints*4 )
485 CV_ERROR( CV_StsOutOfRange, "matrW must be a matrix 12NumIm x 4NumPnt" );
487 /* !!! Not tested all input parameters */
488 /* ----- End test ----- */
490 /* Compute number of points */
491 /* Compute matrix W using derivate proj and points */
495 for( currImage = 0; currImage < numImages; currImage++ )
497 for( int currLine = 0; currLine < 12; currLine++ )
500 for( int currPoint = 0; currPoint < numPoints; currPoint++ )
502 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
505 for( int currCol = 0; currCol < 4; currCol++ )
508 sum = cvmGet(projDeriv[currImage],currVis*2+0,currLine) *
509 cvmGet(pointDeriv[currImage],0,currVis*4+currCol);
511 sum += cvmGet(projDeriv[currImage],currVis*2+1,currLine) *
512 cvmGet(pointDeriv[currImage],1,currVis*4+currCol);
514 cvmSet(matrW,currImage*12+currLine,currPoint*4+currCol,sum);
519 {/* set all sub elements to zero */
520 for( int currCol = 0; currCol < 4; currCol++ )
522 cvmSet(matrW,currImage*12+currLine,currPoint*4+currCol,0);
532 file = fopen( TRACK_BUNDLE_FILE_MATRW ,"w");
533 int currPoint,currImage;
534 for( currPoint = 0; currPoint < numPoints; currPoint++ )
536 fprintf(file,"\nPoint=%d\n",currPoint);
538 for( currRow = 0; currRow < 4; currRow++ )
540 for( currImage = 0; currImage< numImages; currImage++ )
543 for( i = 0; i < 12; i++ )
545 double val = cvmGet(matrW, currImage * 12 + i, currPoint * 4 + currRow);
546 fprintf(file,"%lf ",val);
560 /*======================================================================================*/
561 /* Compute jacobian mult projection matrices error */
562 static void icvComputeJacErrorProj(int numImages,CvMat **projDeriv,CvMat **projErrors,CvMat *jacProjErr )
564 CV_FUNCNAME( "icvComputeJacErrorProj" );
567 /* ----- Test input params for errors ----- */
570 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
572 if( projDeriv == 0 || projErrors == 0 || jacProjErr == 0 )
574 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
576 if( !CV_IS_MAT(jacProjErr) )
578 CV_ERROR( CV_StsUnsupportedFormat, "jacProjErr must be a matrix 12NumIm x 1" );
580 if( jacProjErr->rows != numImages*12 || jacProjErr->cols != 1 )
582 CV_ERROR( CV_StsOutOfRange, "jacProjErr must be a matrix 12NumIm x 1" );
584 /* !!! Not tested all input parameters */
585 /* ----- End test ----- */
588 for( currImage = 0; currImage < numImages; currImage++ )
590 for( int currCol = 0; currCol < 12; currCol++ )
592 int num = projDeriv[currImage]->rows;
594 for( int i = 0; i < num; i++ )
596 sum += cvmGet(projDeriv[currImage],i,currCol) *
597 cvmGet(projErrors[currImage],i%2,i/2);
599 cvmSet(jacProjErr,currImage*12+currCol,0,sum);
606 file = fopen( TRACK_BUNDLE_FILE_JACERRPROJ ,"w");
608 for( currImage = 0; currImage < numImages; currImage++ )
610 fprintf(file,"\nImage=%d\n",currImage);
612 for( currRow = 0; currRow < 12; currRow++ )
614 double val = cvmGet(jacProjErr, currImage * 12 + currRow, 0);
615 fprintf(file,"%lf\n",val);
628 /*======================================================================================*/
629 /* Compute jacobian mult points error */
630 static void icvComputeJacErrorPoint(int numImages,CvMat **pointDeriv,CvMat **projErrors, CvMat **presPoints,CvMat *jacPointErr )
634 CV_FUNCNAME( "icvComputeJacErrorPoint" );
637 /* ----- Test input params for errors ----- */
640 CV_ERROR( CV_StsOutOfRange, "Number of images must more than zero" );
643 if( pointDeriv == 0 || projErrors == 0 || presPoints == 0 || jacPointErr == 0 )
645 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
649 numPoints = presPoints[0]->cols;
652 CV_ERROR( CV_StsOutOfRange, "Number of points must more than zero" );
655 if( !CV_IS_MAT(jacPointErr) )
657 CV_ERROR( CV_StsUnsupportedFormat, "jacPointErr must be a matrix 4NumPnt x 1" );
660 if( jacPointErr->rows != numPoints*4 || jacPointErr->cols != 1 )
662 CV_ERROR( CV_StsOutOfRange, "jacPointErr must be a matrix 4NumPnt x 1" );
664 /* !!! Not tested all input parameters */
665 /* ----- End test ----- */
669 CV_CALL(shifts = (int*)cvAlloc(sizeof(int)*numImages));
670 memset(shifts,0,sizeof(int)*numImages);
671 for( currPoint = 0; currPoint < numPoints; currPoint++ )
673 for( int currCoord = 0; currCoord < 4; currCoord++ )
678 for( currImage = 0; currImage < numImages; currImage++ )
680 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
682 sum += cvmGet(pointDeriv[currImage],0,shifts[currImage]*4+currCoord) *
683 cvmGet(projErrors[currImage],0,shifts[currImage]);//currVis);
685 sum += cvmGet(pointDeriv[currImage],1,shifts[currImage]*4+currCoord) *
686 cvmGet(projErrors[currImage],1,shifts[currImage]);//currVis);
693 cvmSet(jacPointErr,currPoint*4+currCoord,0,sum);
696 /* Increase shifts */
697 for( currImage = 0; currImage < numImages; currImage++ )
699 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
710 file = fopen(TRACK_BUNDLE_FILE_JACERRPNT,"w");
712 for( currPoint = 0; currPoint < numPoints; currPoint++ )
714 fprintf(file,"\nPoint=%d\n",currPoint);
716 for( currRow = 0; currRow < 4; currRow++ )
718 double val = cvmGet(jacPointErr, currPoint * 4 + currRow, 0);
719 fprintf(file,"%lf\n",val);
733 /*======================================================================================*/
736 /* Reconstruct 4D points using status */
737 void icvReconstructPoints4DStatus(CvMat** projPoints, CvMat **projMatrs, CvMat** presPoints,
738 CvMat *points4D,int numImages,CvMat **projError)
741 double* matrA_dat = 0;
742 double* matrW_dat = 0;
744 CV_FUNCNAME( "icvReconstructPoints4DStatus" );
748 /* ----- Test input params for errors ----- */
751 CV_ERROR( CV_StsOutOfRange, "Number of images must be more than one" );
754 if( projPoints == 0 || projMatrs == 0 || presPoints == 0 || points4D == 0 )
756 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
760 numPoints = points4D->cols;
763 CV_ERROR( CV_StsOutOfRange, "Number of points4D must be more than zero" );
766 if( points4D->rows != 4 )
768 CV_ERROR( CV_StsOutOfRange, "Points must have 4 cordinates" );
772 /* !!! Not tested all input parameters */
773 /* ----- End test ----- */
778 /* Allocate maximum data */
781 double matrV_dat[4*4];
782 CvMat matrV = cvMat(4,4,CV_64F,matrV_dat);
784 CV_CALL(matrA_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double)));
785 CV_CALL(matrW_dat = (double*)cvAlloc(3*numImages * 4 * sizeof(double)));
787 /* reconstruct each point */
788 for( currPoint = 0; currPoint < numPoints; currPoint++ )
790 /* Reconstruct current point */
791 /* Define number of visible projections */
793 for( currImage = 0; currImage < numImages; currImage++ )
795 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
803 /* This point can't be reconstructed */
807 /* Allocate memory and create matrices */
809 matrA = cvMat(3*numVisProj,4,CV_64F,matrA_dat);
812 matrW = cvMat(3*numVisProj,4,CV_64F,matrW_dat);
815 for( currImage = 0; currImage < numImages; currImage++ )/* For each view */
817 if( cvmGet(presPoints[currImage],0,currPoint) > 0 )
820 x = cvmGet(projPoints[currImage],0,currPoint);
821 y = cvmGet(projPoints[currImage],1,currPoint);
822 for( int k = 0; k < 4; k++ )
824 matrA_dat[currVisProj*12 + k] =
825 x * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],0,k);
827 matrA_dat[currVisProj*12+4 + k] =
828 y * cvmGet(projMatrs[currImage],2,k) - cvmGet(projMatrs[currImage],1,k);
830 matrA_dat[currVisProj*12+8 + k] =
831 x * cvmGet(projMatrs[currImage],1,k) - y * cvmGet(projMatrs[currImage],0,k);
837 /* Solve system for current point */
839 cvSVD(&matrA,&matrW,0,&matrV,CV_SVD_V_T);
841 /* Copy computed point */
842 cvmSet(points4D,0,currPoint,cvmGet(&matrV,3,0));//X
843 cvmSet(points4D,1,currPoint,cvmGet(&matrV,3,1));//Y
844 cvmSet(points4D,2,currPoint,cvmGet(&matrV,3,2));//Z
845 cvmSet(points4D,3,currPoint,cvmGet(&matrV,3,3));//W
851 {/* Compute projection error */
852 for( currImage = 0; currImage < numImages; currImage++ )
856 double point3D_dat[3];
857 point3D = cvMat(3,1,CV_64F,point3D_dat);
860 double totalError = 0;
861 for(int curPoint = 0; curPoint < numPoints; curPoint++ )
863 if( cvmGet(presPoints[currImage],0,curPoint) > 0)
866 cvGetCol(points4D,&point4D,curPoint);
867 cvmMul(projMatrs[currImage],&point4D,&point3D);
868 double w = point3D_dat[2];
869 double x = point3D_dat[0] / w;
870 double y = point3D_dat[1] / w;
872 dx = cvmGet(projPoints[currImage],0,curPoint) - x;
873 dy = cvmGet(projPoints[currImage],1,curPoint) - y;
876 cvmSet(projError[currImage],0,curPoint,dx);
877 cvmSet(projError[currImage],1,curPoint,dy);
879 totalError += sqrt(dx*dx+dy*dy);
884 //double meanError = totalError / (double)numVis;
898 /*======================================================================================*/
900 static void icvProjPointsStatusFunc( int numImages, CvMat *points4D, CvMat **projMatrs, CvMat **pointsPres, CvMat **projPoints)
902 CV_FUNCNAME( "icvProjPointsStatusFunc" );
905 /* ----- Test input params for errors ----- */
908 CV_ERROR( CV_StsOutOfRange, "Number of images must be more than zero" );
911 if( points4D == 0 || projMatrs == 0 || pointsPres == 0 || projPoints == 0 )
913 CV_ERROR( CV_StsNullPtr, "Some of parameters is a NULL pointer" );
917 numPoints = points4D->cols;
920 CV_ERROR( CV_StsOutOfRange, "Number of points4D must be more than zero" );
923 if( points4D->rows != 4 )
925 CV_ERROR( CV_StsOutOfRange, "Points must have 4 cordinates" );
928 /* !!! Not tested all input parameters */
929 /* ----- End test ----- */
933 double point4D_dat[4];
934 double point3D_dat[3];
935 point4D = cvMat(4,1,CV_64F,point4D_dat);
936 point3D = cvMat(3,1,CV_64F,point3D_dat);
941 file = fopen( TRACK_BUNDLE_FILE ,"a");
942 fprintf(file,"\n----- test 14.01 icvProjPointsStatusFunc -----\n");
948 for( currImage = 0; currImage < numImages; currImage++ )
950 /* Get project matrix */
951 /* project visible points using current projection matrix */
952 int currVisPoint = 0;
953 for( int currPoint = 0; currPoint < numPoints; currPoint++ )
955 if( cvmGet(pointsPres[currImage],0,currPoint) > 0 )
957 /* project current point */
958 cvGetSubRect(points4D,&point4D,cvRect(currPoint,0,1,4));
963 file = fopen( TRACK_BUNDLE_FILE ,"a");
964 fprintf(file,"\n----- test 14.02 point4D (%lf, %lf, %lf, %lf) -----\n",
965 cvmGet(&point4D,0,0),
966 cvmGet(&point4D,1,0),
967 cvmGet(&point4D,2,0),
968 cvmGet(&point4D,3,0));
973 cvmMul(projMatrs[currImage],&point4D,&point3D);
974 double w = point3D_dat[2];
975 cvmSet(projPoints[currImage],0,currVisPoint,point3D_dat[0]/w);
976 cvmSet(projPoints[currImage],1,currVisPoint,point3D_dat[1]/w);
981 file = fopen( TRACK_BUNDLE_FILE ,"a");
982 fprintf(file,"\n----- test 14.03 (%lf, %lf, %lf) -> (%lf, %lf)-----\n",
1000 /*======================================================================================*/
1001 static void icvFreeMatrixArray(CvMat ***matrArray,int numMatr)
1003 /* Free each matrix */
1006 if( *matrArray != 0 )
1008 for( currMatr = 0; currMatr < numMatr; currMatr++ )
1010 cvReleaseMat((*matrArray)+currMatr);
1017 /*======================================================================================*/
1018 static void *icvClearAlloc(int size)
1022 CV_FUNCNAME( "icvClearAlloc" );
1027 CV_CALL(ptr = cvAlloc(size));
1035 /*======================================================================================*/
1037 void cvOptimizeLevenbergMarquardtBundleWraper( CvMat** projMatrs, CvMat** observProjPoints,
1038 CvMat** pointsPres, int numImages,
1039 CvMat** resultProjMatrs, CvMat* resultPoints4D,int maxIter,double epsilon )
1041 /* Delete al sparse points */
1043 int icvDeleteSparsInPoints( int numImages,
1046 CvMat *wasStatus)/* status of previous configuration */
1051 /*======================================================================================*/
1052 /* !!! may be useful to return norm of error */
1053 /* !!! may be does not work correct with not all visible 4D points */
1054 void cvOptimizeLevenbergMarquardtBundle( CvMat** projMatrs, CvMat** observProjPoints,
1055 CvMat** pointsPres, int numImages,
1056 CvMat** resultProjMatrs, CvMat* resultPoints4D,int maxIter,double epsilon )
1059 CvMat *vectorX_points4D = 0;
1060 CvMat **vectorX_projMatrs = 0;
1062 CvMat *newVectorX_points4D = 0;
1063 CvMat **newVectorX_projMatrs = 0;
1065 CvMat *changeVectorX_points4D = 0;
1066 CvMat *changeVectorX_projMatrs = 0;
1068 CvMat **observVisPoints = 0;
1069 CvMat **projVisPoints = 0;
1070 CvMat **errorProjPoints = 0;
1071 CvMat **DerivProj = 0;
1072 CvMat **DerivPoint = 0;
1074 CvMat **matrsUk = 0;
1075 CvMat **workMatrsUk = 0;
1076 CvMat **matrsVi = 0;
1077 CvMat *workMatrVi = 0;
1078 CvMat **workMatrsInvVi = 0;
1079 CvMat *jacProjErr = 0;
1080 CvMat *jacPointErr = 0;
1082 CvMat *matrTmpSys1 = 0;
1083 CvMat *matrSysDeltaP = 0;
1084 CvMat *vectTmpSys3 = 0;
1085 CvMat *vectSysDeltaP = 0;
1088 CvMat *vectTmpSysM = 0;
1093 CV_FUNCNAME( "cvOptimizeLevenbergMarquardtBundle" );
1096 /* ----- Test input params for errors ----- */
1099 CV_ERROR( CV_StsOutOfRange, "Number of images must be more than zero" );
1102 if( maxIter < 1 || maxIter > 2000 )
1104 CV_ERROR( CV_StsOutOfRange, "Maximum number of iteration must be in [1..1000]" );
1109 CV_ERROR( CV_StsOutOfRange, "Epsilon parameter must be >= 0" );
1112 if( !CV_IS_MAT(resultPoints4D) )
1114 CV_ERROR( CV_StsUnsupportedFormat, "resultPoints4D must be a matrix 4 x NumPnt" );
1117 numPoints = resultPoints4D->cols;
1120 CV_ERROR( CV_StsOutOfRange, "Number of points must be more than zero" );//!!!
1123 if( resultPoints4D->rows != 4 )
1125 CV_ERROR( CV_StsOutOfRange, "resultPoints4D must have 4 cordinates" );
1128 /* ----- End test ----- */
1130 /* Optimization using bundle adjustment */
1131 /* work with non visible points */
1133 CV_CALL( vectorX_points4D = cvCreateMat(4,numPoints,CV_64F));
1134 CV_CALL( vectorX_projMatrs = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages));
1136 CV_CALL( newVectorX_points4D = cvCreateMat(4,numPoints,CV_64F));
1137 CV_CALL( newVectorX_projMatrs = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages));
1139 CV_CALL( changeVectorX_points4D = cvCreateMat(4,numPoints,CV_64F));
1140 CV_CALL( changeVectorX_projMatrs = cvCreateMat(3,4,CV_64F));
1142 /* ----- Test input params ----- */
1143 for(int currImage = 0; currImage < numImages; currImage++ )
1145 /* Test size of input initial and result projection matrices */
1146 if( !CV_IS_MAT(projMatrs[currImage]) )
1148 CV_ERROR( CV_StsUnsupportedFormat, "each of initial projMatrs must be a matrix 3 x 4" );
1150 if( projMatrs[currImage]->rows != 3 || projMatrs[currImage]->cols != 4 )
1152 CV_ERROR( CV_StsOutOfRange, "each of initial projMatrs must be a matrix 3 x 4" );
1156 if( !CV_IS_MAT(observProjPoints[currImage]) )
1158 CV_ERROR( CV_StsUnsupportedFormat, "each of observProjPoints must be a matrix 2 x NumPnts" );
1160 if( observProjPoints[currImage]->rows != 2 || observProjPoints[currImage]->cols != numPoints )
1162 CV_ERROR( CV_StsOutOfRange, "each of observProjPoints must be a matrix 2 x NumPnts" );
1165 if( !CV_IS_MAT(pointsPres[currImage]) )
1167 CV_ERROR( CV_StsUnsupportedFormat, "each of pointsPres must be a matrix 1 x NumPnt" );
1169 if( pointsPres[currImage]->rows != 1 || pointsPres[currImage]->cols != numPoints )
1171 CV_ERROR( CV_StsOutOfRange, "each of pointsPres must be a matrix 1 x NumPnt" );
1174 if( !CV_IS_MAT(resultProjMatrs[currImage]) )
1176 CV_ERROR( CV_StsUnsupportedFormat, "each of resultProjMatrs must be a matrix 3 x 4" );
1178 if( resultProjMatrs[currImage]->rows != 3 || resultProjMatrs[currImage]->cols != 4 )
1180 CV_ERROR( CV_StsOutOfRange, "each of resultProjMatrs must be a matrix 3 x 4" );
1184 /* ----- End test ----- */
1186 /* Copy projection matrices to vectorX0 */
1187 for(int currImage = 0; currImage < numImages; currImage++ )
1189 CV_CALL( vectorX_projMatrs[currImage] = cvCreateMat(3,4,CV_64F));
1190 CV_CALL( newVectorX_projMatrs[currImage] = cvCreateMat(3,4,CV_64F));
1191 cvCopy(projMatrs[currImage],vectorX_projMatrs[currImage]);
1194 /* Reconstruct points4D using projection matrices and status information */
1195 icvReconstructPoints4DStatus(observProjPoints, projMatrs, pointsPres, vectorX_points4D, numImages);
1197 /* ----- Allocate memory for work matrices ----- */
1198 /* Compute number of good points on each images */
1200 CV_CALL( observVisPoints = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1201 CV_CALL( projVisPoints = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1202 CV_CALL( errorProjPoints = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1203 CV_CALL( DerivProj = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1204 CV_CALL( DerivPoint = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1205 CV_CALL( matrW = cvCreateMat(12*numImages,4*numPoints,CV_64F) );
1206 CV_CALL( matrsUk = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1207 CV_CALL( workMatrsUk = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numImages) );
1208 CV_CALL( matrsVi = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numPoints) );
1209 CV_CALL( workMatrVi = cvCreateMat(4,4,CV_64F) );
1210 CV_CALL( workMatrsInvVi = (CvMat**)icvClearAlloc(sizeof(CvMat*)*numPoints) );
1212 CV_CALL( jacProjErr = cvCreateMat(12*numImages,1,CV_64F) );
1213 CV_CALL( jacPointErr = cvCreateMat(4*numPoints,1,CV_64F) );
1217 for( i = 0; i < numPoints; i++ )
1219 CV_CALL( matrsVi[i] = cvCreateMat(4,4,CV_64F) );
1220 CV_CALL( workMatrsInvVi[i] = cvCreateMat(4,4,CV_64F) );
1223 for(int currImage = 0; currImage < numImages; currImage++ )
1225 CV_CALL( matrsUk[currImage] = cvCreateMat(12,12,CV_64F) );
1226 CV_CALL( workMatrsUk[currImage] = cvCreateMat(12,12,CV_64F) );
1228 int currVisPoint = 0, currPoint, numVisPoint;
1229 for( currPoint = 0; currPoint < numPoints; currPoint++ )
1231 if( cvmGet(pointsPres[currImage],0,currPoint) > 0 )
1237 numVisPoint = currVisPoint;
1239 /* Allocate memory for current image data */
1240 CV_CALL( observVisPoints[currImage] = cvCreateMat(2,numVisPoint,CV_64F) );
1241 CV_CALL( projVisPoints[currImage] = cvCreateMat(2,numVisPoint,CV_64F) );
1243 /* create error matrix */
1244 CV_CALL( errorProjPoints[currImage] = cvCreateMat(2,numVisPoint,CV_64F) );
1246 /* Create derivate matrices */
1247 CV_CALL( DerivProj[currImage] = cvCreateMat(2*numVisPoint,12,CV_64F) );
1248 CV_CALL( DerivPoint[currImage] = cvCreateMat(2,numVisPoint*4,CV_64F) );
1250 /* Copy observed projected visible points */
1252 for( currPoint = 0; currPoint < numPoints; currPoint++ )
1254 if( cvmGet(pointsPres[currImage],0,currPoint) > 0 )
1256 cvmSet(observVisPoints[currImage],0,currVisPoint,cvmGet(observProjPoints[currImage],0,currPoint));
1257 cvmSet(observVisPoints[currImage],1,currVisPoint,cvmGet(observProjPoints[currImage],1,currPoint));
1262 /*---------------------------------------------------*/
1264 CV_CALL( matrTmpSys1 = cvCreateMat(numPoints*4, numImages*12, CV_64F) );
1265 CV_CALL( matrSysDeltaP = cvCreateMat(numImages*12, numImages*12, CV_64F) );
1266 CV_CALL( vectTmpSys3 = cvCreateMat(numPoints*4,1,CV_64F) );
1267 CV_CALL( vectSysDeltaP = cvCreateMat(numImages*12,1,CV_64F) );
1268 CV_CALL( deltaP = cvCreateMat(numImages*12,1,CV_64F) );
1269 CV_CALL( deltaM = cvCreateMat(numPoints*4,1,CV_64F) );
1270 CV_CALL( vectTmpSysM = cvCreateMat(numPoints*4,1,CV_64F) );
1273 //#ifdef TRACK_BUNDLE
1276 /* Create file to track */
1278 file = fopen( TRACK_BUNDLE_FILE ,"w");
1279 fprintf(file,"begin\n");
1284 /* ============= main optimization loop ============== */
1286 /* project all points using current vector X */
1287 icvProjPointsStatusFunc(numImages, vectorX_points4D, vectorX_projMatrs, pointsPres, projVisPoints);
1289 /* Compute error with observed value and computed projection */
1292 for(int currImage = 0; currImage < numImages; currImage++ )
1294 cvSub(observVisPoints[currImage],projVisPoints[currImage],errorProjPoints[currImage]);
1295 double currNorm = cvNorm(errorProjPoints[currImage]);
1296 prevError += currNorm * currNorm;
1298 prevError = sqrt(prevError);
1304 //#ifdef TRACK_BUNDLE
1307 /* Create file to track */
1309 file = fopen( TRACK_BUNDLE_FILE ,"a");
1310 fprintf(file,"\n========================================\n");;
1311 fprintf(file,"Iter=0\n");
1312 fprintf(file,"Error = %20.15lf\n",prevError);
1313 fprintf(file,"Change = %20.15lf\n",1.0);
1315 fprintf(file,"projection errors\n");
1317 /* Print all proejction errors */
1318 for(int currImage = 0; currImage < numImages; currImage++)
1320 fprintf(file,"\nImage=%d\n",currImage);
1321 int numPn = errorProjPoints[currImage]->cols;
1322 for( int currPoint = 0; currPoint < numPn; currPoint++ )
1325 ex = cvmGet(errorProjPoints[currImage],0,currPoint);
1326 ey = cvmGet(errorProjPoints[currImage],1,currPoint);
1327 fprintf(file,"%40.35lf, %40.35lf\n",ex,ey);
1345 file = fopen( TRACK_BUNDLE_FILE ,"a");
1346 fprintf(file,"\n----- test 6 do main -----\n");
1348 double norm = cvNorm(vectorX_points4D);
1349 fprintf(file," test 6.01 prev normPnts=%lf\n",norm);
1351 for( int i=0;i<numImages;i++ )
1353 double norm = cvNorm(vectorX_projMatrs[i]);
1354 fprintf(file," test 6.01 prev normProj=%lf\n",norm);
1361 /* Compute derivates by projectinon matrices */
1362 icvComputeDerivateProjAll(vectorX_points4D,vectorX_projMatrs,pointsPres,numImages,DerivProj);
1364 /* Compute derivates by 4D points */
1365 icvComputeDerivatePointsAll(vectorX_points4D,vectorX_projMatrs,pointsPres,numImages,DerivPoint);
1367 /* Compute matrces Uk */
1368 icvComputeMatrixUAll(numImages,DerivProj,matrsUk);
1369 icvComputeMatrixVAll(numImages,DerivPoint,pointsPres,matrsVi);
1370 icvComputeMatrixW(numImages,DerivProj,DerivPoint,pointsPres,matrW);
1376 file = fopen( TRACK_BUNDLE_FILE ,"a");
1377 fprintf(file,"\n----- test 6.03 do matrs U V -----\n");
1380 for( i = 0; i < numImages; i++ )
1382 double norm = cvNorm(matrsUk[i]);
1383 fprintf(file," test 6.01 prev matrsUk=%lf\n",norm);
1386 for( i = 0; i < numPoints; i++ )
1388 double norm = cvNorm(matrsVi[i]);
1389 fprintf(file," test 6.01 prev matrsVi=%lf\n",norm);
1396 /* Compute jac errors */
1397 icvComputeJacErrorProj(numImages, DerivProj, errorProjPoints, jacProjErr);
1398 icvComputeJacErrorPoint(numImages, DerivPoint, errorProjPoints, pointsPres, jacPointErr);
1403 file = fopen( TRACK_BUNDLE_FILE ,"a");
1404 fprintf(file,"\n----- test 6 do main -----\n");
1405 double norm1 = cvNorm(vectorX_points4D);
1406 fprintf(file," test 6.02 post normPnts=%lf\n",norm1);
1410 /* Copy matrices Uk to work matrices Uk */
1411 for(int currImage = 0; currImage < numImages; currImage++ )
1413 cvCopy(matrsUk[currImage],workMatrsUk[currImage]);
1419 file = fopen( TRACK_BUNDLE_FILE ,"a");
1420 fprintf(file,"\n----- test 60.3 do matrs U V -----\n");
1423 for( i = 0; i < numImages; i++ )
1425 double norm = cvNorm(matrsUk[i]);
1426 fprintf(file," test 6.01 post1 matrsUk=%lf\n",norm);
1429 for( i = 0; i < numPoints; i++ )
1431 double norm = cvNorm(matrsVi[i]);
1432 fprintf(file," test 6.01 post1 matrsVi=%lf\n",norm);
1439 /* ========== Solve normal equation for given alpha and Jacobian ============ */
1443 /* ---- Add alpha to matrices --- */
1444 /* Add alpha to matrInvVi and make workMatrsInvVi */
1447 for( currV = 0; currV < numPoints; currV++ )
1449 cvCopy(matrsVi[currV],workMatrVi);
1451 for( i = 0; i < 4; i++ )
1453 cvmSet(workMatrVi,i,i,cvmGet(matrsVi[currV],i,i)*(1+alpha) );
1456 cvInvert(workMatrVi,workMatrsInvVi[currV],CV_LU/*,&currV*/);
1459 /* Add alpha to matrUk and make matrix workMatrsUk */
1460 for(int currImage = 0; currImage< numImages; currImage++ )
1463 for( i = 0; i < 12; i++ )
1465 cvmSet(workMatrsUk[currImage],i,i,cvmGet(matrsUk[currImage],i,i)*(1+alpha));
1471 /* Fill matrix to make system for computing delta P (matrTmpSys1 = inv(V)*tr(W) )*/
1472 for( currV = 0; currV < numPoints; currV++ )
1475 for( currRowV = 0; currRowV < 4; currRowV++ )
1477 for(int currImage = 0; currImage < numImages; currImage++ )
1479 for( int currCol = 0; currCol < 12; currCol++ )/* For each column of transposed matrix W */
1482 for( i = 0; i < 4; i++ )
1484 sum += cvmGet(workMatrsInvVi[currV],currRowV,i) *
1485 cvmGet(matrW,currImage*12+currCol,currV*4+i);
1487 cvmSet(matrTmpSys1,currV*4+currRowV,currImage*12+currCol,sum);
1494 /* Fill matrix to make system for computing delta P (matrTmpSys2 = W * matrTmpSys ) */
1495 cvmMul(matrW,matrTmpSys1,matrSysDeltaP);
1497 /* need to compute U-matrTmpSys2. But we compute matTmpSys2-U */
1498 for(int currImage = 0; currImage < numImages; currImage++ )
1501 cvGetSubRect(matrSysDeltaP,&subMatr,cvRect(currImage*12,currImage*12,12,12));
1502 cvSub(&subMatr,workMatrsUk[currImage],&subMatr);
1505 /* Compute right side of normal equation */
1506 for( currV = 0; currV < numPoints; currV++ )
1508 CvMat subMatrErPnts;
1510 cvGetSubRect(jacPointErr,&subMatrErPnts,cvRect(0,currV*4,1,4));
1511 cvGetSubRect(vectTmpSys3,&subMatr,cvRect(0,currV*4,1,4));
1512 cvmMul(workMatrsInvVi[currV],&subMatrErPnts,&subMatr);
1515 cvmMul(matrW,vectTmpSys3,vectSysDeltaP);
1516 cvSub(vectSysDeltaP,jacProjErr,vectSysDeltaP);
1518 /* Now we can compute part of normal system - deltaP */
1519 cvSolve(matrSysDeltaP ,vectSysDeltaP, deltaP, CV_SVD);
1521 /* Print deltaP to file */
1526 file = fopen( TRACK_BUNDLE_FILE_DELTAP ,"w");
1528 for(int currImage = 0; currImage < numImages; currImage++ )
1530 fprintf(file,"\nImage=%d\n",currImage);
1532 for( i = 0; i < 12; i++ )
1535 val = cvmGet(deltaP,currImage*12+i,0);
1536 fprintf(file,"%lf\n",val);
1543 /* We know deltaP and now we can compute system for deltaM */
1544 for( i = 0; i < numPoints * 4; i++ )
1547 for( int j = 0; j < numImages * 12; j++ )
1549 sum += cvmGet(matrW,j,i) * cvmGet(deltaP,j,0);
1551 cvmSet(vectTmpSysM,i,0,cvmGet(jacPointErr,i,0)-sum);
1554 /* Compute deltaM */
1555 for( currV = 0; currV < numPoints; currV++ )
1559 cvGetSubRect(vectTmpSysM,&subMatr,cvRect(0,currV*4,1,4));
1560 cvGetSubRect(deltaM,&subMatrM,cvRect(0,currV*4,1,4));
1561 cvmMul(workMatrsInvVi[currV],&subMatr,&subMatrM);
1564 /* We know delta and compute new value of vector X: nextVectX = vectX + deltas */
1567 for(int currImage = 0; currImage < numImages; currImage++ )
1569 for( i = 0; i < 3; i++ )
1571 for( int j = 0; j < 4; j++ )
1573 cvmSet(newVectorX_projMatrs[currImage],i,j,
1574 cvmGet(vectorX_projMatrs[currImage],i,j) + cvmGet(deltaP,currImage*12+i*4+j,0));
1581 for( currPoint = 0; currPoint < numPoints; currPoint++ )
1583 for( i = 0; i < 4; i++ )
1585 cvmSet(newVectorX_points4D,i,currPoint,
1586 cvmGet(vectorX_points4D,i,currPoint) + cvmGet(deltaM,currPoint*4+i,0));
1590 /* ----- Compute errors for new vectorX ----- */
1591 /* Project points using new vectorX and status of each point */
1592 icvProjPointsStatusFunc(numImages, newVectorX_points4D, newVectorX_projMatrs, pointsPres, projVisPoints);
1593 /* Compute error with observed value and computed projection */
1594 double newError = 0;
1595 for(int currImage = 0; currImage < numImages; currImage++ )
1597 cvSub(observVisPoints[currImage],projVisPoints[currImage],errorProjPoints[currImage]);
1598 double currNorm = cvNorm(errorProjPoints[currImage]);
1600 //#ifdef TRACK_BUNDLE
1604 file = fopen( TRACK_BUNDLE_FILE ,"a");
1605 fprintf(file,"\n----- test 13,01 currImage=%d currNorm=%lf -----\n",currImage,currNorm);
1609 newError += currNorm * currNorm;
1611 newError = sqrt(newError);
1618 //#ifdef TRACK_BUNDLE
1621 /* Create file to track */
1623 file = fopen( TRACK_BUNDLE_FILE ,"a");
1624 fprintf(file,"\n========================================\n");
1625 fprintf(file,"numPoints=%d\n",numPoints);
1626 fprintf(file,"Iter=%d\n",currIter);
1627 fprintf(file,"Error = %20.15lf\n",newError);
1628 fprintf(file,"Change = %20.15lf\n",change);
1631 /* Print all projection errors */
1633 fprintf(file,"projection errors\n");
1634 for(int currImage = 0; currImage < numImages; currImage++)
1636 fprintf(file,"\nImage=%d\n",currImage);
1637 int numPn = errorProjPoints[currImage]->cols;
1638 for( int currPoint = 0; currPoint < numPn; currPoint++ )
1641 ex = cvmGet(errorProjPoints[currImage],0,currPoint);
1642 ey = cvmGet(errorProjPoints[currImage],1,currPoint);
1643 fprintf(file,"%lf,%lf\n",ex,ey);
1646 fprintf(file,"\n---- test 0 -----\n");
1655 /* Compare new error and last error */
1656 if( newError < prevError )
1657 {/* accept new value */
1658 prevError = newError;
1659 /* Compute relative change of required parameter vectorX. change = norm(curr-prev) / norm(curr) ) */
1661 double normAll1 = 0;
1662 double normAll2 = 0;
1663 double currNorm1 = 0;
1664 double currNorm2 = 0;
1665 /* compute norm for projection matrices */
1666 for(int currImage = 0; currImage < numImages; currImage++ )
1668 currNorm1 = cvNorm(newVectorX_projMatrs[currImage],vectorX_projMatrs[currImage]);
1669 currNorm2 = cvNorm(newVectorX_projMatrs[currImage]);
1671 normAll1 += currNorm1 * currNorm1;
1672 normAll2 += currNorm2 * currNorm2;
1675 /* compute norm for points */
1676 currNorm1 = cvNorm(newVectorX_points4D,vectorX_points4D);
1677 currNorm2 = cvNorm(newVectorX_points4D);
1679 normAll1 += currNorm1 * currNorm1;
1680 normAll2 += currNorm2 * currNorm2;
1682 /* compute change */
1683 change = sqrt(normAll1) / sqrt(normAll2);
1686 //#ifdef TRACK_BUNDLE
1689 /* Create file to track */
1691 file = fopen( TRACK_BUNDLE_FILE ,"a");
1692 fprintf(file,"\nChange inside newVal change = %20.15lf\n",change);
1693 fprintf(file," normAll1= %20.15lf\n",sqrt(normAll1));
1694 fprintf(file," normAll2= %20.15lf\n",sqrt(normAll2));
1703 for(int currImage = 0; currImage < numImages; currImage++ )
1705 cvCopy(newVectorX_projMatrs[currImage],vectorX_projMatrs[currImage]);
1707 cvCopy(newVectorX_points4D,vectorX_points4D);
1716 } while( change > epsilon && currIter < maxIter );/* solve normal equation using current alpha */
1718 //#ifdef TRACK_BUNDLE
1722 file = fopen( TRACK_BUNDLE_FILE ,"a");
1723 fprintf(file,"\nBest error = %40.35lf\n",prevError);
1730 } while( change > epsilon && currIter < maxIter );
1732 /*--------------------------------------------*/
1733 /* Optimization complete copy computed params */
1734 /* Copy projection matrices */
1735 for(int currImage = 0; currImage < numImages; currImage++ )
1737 cvCopy(newVectorX_projMatrs[currImage],resultProjMatrs[currImage]);
1739 /* Copy 4D points */
1740 cvCopy(newVectorX_points4D,resultPoints4D);
1746 /* Free allocated memory */
1748 /* Free simple matrices */
1749 cvFree(&vectorX_points4D);
1750 cvFree(&newVectorX_points4D);
1751 cvFree(&changeVectorX_points4D);
1752 cvFree(&changeVectorX_projMatrs);
1754 cvFree(&workMatrVi);
1755 cvFree(&jacProjErr);
1756 cvFree(&jacPointErr);
1757 cvFree(&matrTmpSys1);
1758 cvFree(&matrSysDeltaP);
1759 cvFree(&vectTmpSys3);
1760 cvFree(&vectSysDeltaP);
1763 cvFree(&vectTmpSysM);
1765 /* Free arrays of matrices */
1766 icvFreeMatrixArray(&vectorX_projMatrs,numImages);
1767 icvFreeMatrixArray(&newVectorX_projMatrs,numImages);
1768 icvFreeMatrixArray(&observVisPoints,numImages);
1769 icvFreeMatrixArray(&projVisPoints,numImages);
1770 icvFreeMatrixArray(&errorProjPoints,numImages);
1771 icvFreeMatrixArray(&DerivProj,numImages);
1772 icvFreeMatrixArray(&DerivPoint,numImages);
1773 icvFreeMatrixArray(&matrsUk,numImages);
1774 icvFreeMatrixArray(&workMatrsUk,numImages);
1775 icvFreeMatrixArray(&matrsVi,numPoints);
1776 icvFreeMatrixArray(&workMatrsInvVi,numPoints);