]> rtime.felk.cvut.cz Git - opencv.git/commitdiff
modified pca test
authormdim <mdim@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 22 Dec 2009 12:49:56 +0000 (12:49 +0000)
committermdim <mdim@73c94f0f-984f-4a5f-82bc-2d8db8d8ee08>
Tue, 22 Dec 2009 12:49:56 +0000 (12:49 +0000)
git-svn-id: https://code.ros.org/svn/opencv/trunk@2474 73c94f0f-984f-4a5f-82bc-2d8db8d8ee08

opencv/tests/cxcore/src/apca.cpp

index 21589b39f49d1963bd282119d94edc33ba0f5947..d6ce18ebf5bf9d03abee446159762345cc300415 100644 (file)
@@ -43,6 +43,9 @@
 \r
 using namespace cv;\r
 \r
+//#define CHECK_C\r
+\r
+Size sz( 200, 500);\r
 \r
 class CV_PCATest : public CvTest\r
 {\r
@@ -52,6 +55,8 @@ protected:
     void run( int);\r
 };\r
 \r
+#if 0\r
+\r
 void CV_PCATest::run( int )\r
 {\r
     int code = CvTS::OK, err;\r
@@ -114,5 +119,189 @@ void CV_PCATest::run( int )
 \r
     ts->set_failed_test_info( code );\r
 }\r
+#else\r
+void CV_PCATest::run( int )\r
+{\r
+       int code = CvTS::OK;\r
+       \r
+       double diffPrjEps, diffBackPrjEps,\r
+                  prjEps, backPrjEps,\r
+                  evalEps, evecEps;\r
+       int maxComponents = 100;\r
+       Mat rPoints(sz, CV_32FC1), rTestPoints(sz, CV_32FC1);\r
+       RNG rng = *ts->get_rng(); \r
+\r
+       rng.fill( rPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );\r
+       rng.fill( rTestPoints, RNG::UNIFORM, Scalar::all(0.0), Scalar::all(1.0) );\r
+\r
+       PCA rPCA( rPoints, Mat(), CV_PCA_DATA_AS_ROW, maxComponents ), cPCA;\r
+\r
+       // 1. check C++ PCA & ROW\r
+       Mat rPrjTestPoints = rPCA.project( rTestPoints );\r
+       Mat rBackPrjTestPoints = rPCA.backProject( rPrjTestPoints );\r
+\r
+       Mat avg(1, sz.width, CV_32FC1 );\r
+       reduce( rPoints, avg, 0, CV_REDUCE_AVG );\r
+       Mat Q = rPoints - repeat( avg, rPoints.rows, 1 ), eval, evec;\r
+       Q = Q.t() * Q;\r
+       Q = Q /(float)rPoints.rows;\r
+\r
+       eigen( Q, eval, evec );\r
+       /*SVD svd(Q);\r
+       evec = svd.vt;\r
+       eval = svd.w;*/\r
+\r
+       Mat subEval( maxComponents, 1, eval.type(), eval.data ),\r
+               subEvec( maxComponents, evec.cols, evec.type(), evec.data );\r
+\r
+#ifdef CHECK_C\r
+       Mat prjTestPoints, backPrjTestPoints, cPoints = rPoints.t(), cTestPoints = rTestPoints.t();\r
+       CvMat _points, _testPoints, _avg, _eval, _evec, _prjTestPoints, _backPrjTestPoints;\r
+#endif\r
+\r
+       // check eigen()\r
+       double eigenEps = 1e-6;\r
+       double err;\r
+       for(int i = 0; i < Q.rows; i++ )\r
+       {\r
+               Mat v = evec.row(i).t();\r
+               Mat Qv = Q * v;\r
+\r
+               Mat lv = eval.at<float>(i,0) * v;\r
+               err = norm( Qv, lv );\r
+               if( err > eigenEps )\r
+               {\r
+                       ts->printf( CvTS::LOG, "bad accuracy of eigen(); err = %f\n", err );\r
+                       code = CvTS::FAIL_BAD_ACCURACY;
+                       goto exit_func;
+               }\r
+       }\r
+       // check pca eigenvalues\r
+       evalEps = 1e-6, evecEps = 1;\r
+       err = norm( rPCA.eigenvalues, subEval );\r
+       if( err > evalEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "pca.eigenvalues is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+       // check pca eigenvectors\r
+       err = norm( rPCA.eigenvectors, subEvec, CV_RELATIVE_L2 );\r
+       if( err > evecEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "pca.eigenvectors is incorrect (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+       \r
+       prjEps = 1.2, backPrjEps = 1.2;\r
+       for( int i = 0; i < rTestPoints.rows; i++ )\r
+       {\r
+               // check pca project\r
+               Mat prj = (rTestPoints.row(i) - avg) * subEvec.t();\r
+               err = norm(rPrjTestPoints.row(i), prj, CV_RELATIVE_L2);\r
+               if( err > prjEps )\r
+               {\r
+                       ts->printf( CvTS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+                       code = CvTS::FAIL_BAD_ACCURACY;
+                       goto exit_func;
+               }\r
+               // check pca backProject\r
+               Mat backPrj = rPrjTestPoints.row(i) * subEvec + avg;\r
+               err = norm( rBackPrjTestPoints.row(i), backPrj, CV_RELATIVE_L2 );\r
+               if( err > backPrjEps )\r
+               {\r
+                       ts->printf( CvTS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+                       code = CvTS::FAIL_BAD_ACCURACY;
+                       goto exit_func;
+               }\r
+       }\r
+\r
+       // 2. check C++ PCA & COL\r
+       cPCA( rPoints.t(), Mat(), CV_PCA_DATA_AS_COL, maxComponents );\r
+       diffPrjEps = 1, diffBackPrjEps = 1;\r
+       err = norm(cPCA.project(rTestPoints.t()), rPrjTestPoints.t(), CV_RELATIVE_L2 );\r
+       if( err > diffPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of project() (CV_PCA_DATA_AS_COL); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+       err = norm(cPCA.backProject(rPrjTestPoints.t()), rBackPrjTestPoints.t(), CV_RELATIVE_L2 );\r
+       if( err > diffBackPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of backProject() (CV_PCA_DATA_AS_COL); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+\r
+#ifdef CHECK_C\r
+       // 3. check C PCA & ROW\r
+       _points = rPoints;\r
+       _testPoints = rTestPoints;\r
+       _avg = avg;\r
+       _eval = eval;\r
+       _evec = evec;\r
+       prjTestPoints.create(rTestPoints.rows, rTestPoints.cols/*maxComponents*/, rTestPoints.type() );\r
+       backPrjTestPoints.create(rPoints.size(), rPoints.type() );\r
+       _prjTestPoints = prjTestPoints;\r
+       _backPrjTestPoints = backPrjTestPoints;\r
+\r
+       cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_ROW );\r
+       cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );\r
+       cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );\r
+\r
+       err = norm(prjTestPoints, rPrjTestPoints.t(), CV_RELATIVE_L2);\r
+       if( err > diffPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+       err = norm(backPrjTestPoints, rBackPrjTestPoints.t(), CV_RELATIVE_L2);\r
+       if( err > diffBackPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_ROW); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+\r
+       // 3. check C PCA & COL\r
+       _points = cPoints;\r
+       _testPoints = cTestPoints;\r
+       avg.t(); _avg = avg;\r
+       eval.t(); _eval = eval;\r
+       evec.t(); _evec = evec;\r
+       prjTestPoints.t(); _prjTestPoints = prjTestPoints;\r
+       backPrjTestPoints.t(); _backPrjTestPoints = backPrjTestPoints;\r
+\r
+       cvCalcPCA( &_points, &_avg, &_eval, &_evec, CV_PCA_DATA_AS_COL );\r
+       cvProjectPCA( &_testPoints, &_avg, &_evec, &_prjTestPoints );\r
+       cvBackProjectPCA( &_prjTestPoints, &_avg, &_evec, &_backPrjTestPoints );\r
+\r
+       err = norm(prjTestPoints, rPrjTestPoints, CV_RELATIVE_L2 );\r
+       if( err > diffPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of cvProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+       err = norm(backPrjTestPoints, rBackPrjTestPoints, CV_RELATIVE_L2);\r
+       if( err > diffBackPrjEps )\r
+       {\r
+               ts->printf( CvTS::LOG, "bad accuracy of cvBackProjectPCA() (CV_PCA_DATA_AS_COL); err = %f\n", err );\r
+               code = CvTS::FAIL_BAD_ACCURACY;
+               goto exit_func;
+       }\r
+#endif\r
+\r
+exit_func:\r
+\r
+       CvRNG* _rng = ts->get_rng(); \r
+       *_rng = rng.state;\r
+       ts->set_failed_test_info( code );\r
+}\r
+\r
+#endif\r
 \r
 CV_PCATest pca_test;
\ No newline at end of file