\r
using namespace cv;\r
\r
+//#define CHECK_C\r
+\r
+Size sz( 200, 500);\r
\r
class CV_PCATest : public CvTest\r
{\r
void run( int);\r
};\r
\r
+#if 0\r
+\r
void CV_PCATest::run( int )\r
{\r
int code = CvTS::OK, err;\r
\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