Move the sources to trunk
[opencv] / tests / cv / src / aeigenobjects.cpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
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.
8 //
9 //
10 //                        Intel License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 //   * Redistribution's of source code must retain the above copyright notice,
20 //     this list of conditions and the following disclaimer.
21 //
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.
25 //
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.
28 //
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.
39 //
40 //M*/
41
42 #include "cvtest.h"
43
44 #if 0
45
46 #include "aeigenobjects.inc"
47
48 #define __8U   8
49 #define __32F 32
50 #define MAXDIFF 1.01
51 #define RELDIFF 1.0e-4
52
53 typedef struct _UserData  /* User data structure for callback mode */
54 {
55     void*  addr1;  /* Array of objects ROI start addresses */
56     void*  addr2;
57     int    step1;  /* Step in bytes */
58     int    step2;
59     CvSize size1;  /* ROI or full size */
60     CvSize size2;
61 } UserData;
62
63 /* Testing parameters */
64 static char FuncName[]  =
65 "cvCalcCovarMatrixEx, cvCalcEigenObjects, cvCalcDecompCoeff, cvEigenDecomposite, cvEigenProjection";
66 static char TestName[]  = "Eigen objects functions group test";
67 static char TestClass[] = "Algorithm";
68 static int obj_number, obj_width, obj_height;
69 static double rel_bufSize;
70
71 /*-----------------------------=--=-=== Callback functions ===-=--=---------------------*/
72
73 int read_callback_8u( int ind, void* buf, void* userData)
74 {
75     int i, j, k = 0;
76     UserData* data = (UserData*)userData;
77     uchar* start = ((uchar**)(data->addr1))[ind];
78     uchar* buff = (uchar*)buf;
79
80     if( ind<0 ) return CV_BADFACTOR_ERR;
81     if( buf==NULL || userData==NULL ) return CV_NULLPTR_ERR;
82
83     for( i=0; i<data->size1.height; i++, start+=data->step1 )
84         for( j=0; j<data->size1.width; j++, k++ )
85             buff[k] = start[j];
86     return CV_NO_ERR;
87 }
88 /*----------------------*/
89 int read_callback_32f( int ind, void* buf, void* userData)
90 {
91     int i, j, k = 0;
92     UserData* data = (UserData*)userData;
93     float* start = ((float**)(data->addr2))[ind];
94     float* buff = (float*)buf;
95
96     if( ind<0 ) return CV_BADFACTOR_ERR;
97     if( buf==NULL || userData==NULL ) return CV_NULLPTR_ERR;
98
99     for( i=0; i<data->size2.height; i++, start+=data->step2/4 )
100         for( j=0; j<data->size2.width; j++, k++ )
101             buff[k] = start[j];
102     return CV_NO_ERR;
103 }
104 /*========================*/
105 int write_callback_8u( int ind, void* buf, void* userData)
106 {
107     int i, j, k = 0;
108     UserData* data = (UserData*)userData;
109     uchar* start = ((uchar**)(data->addr1))[ind];
110     uchar* buff = (uchar*)buf;
111
112     if( ind<0 ) return CV_BADFACTOR_ERR;
113     if( buf==NULL || userData==NULL ) return CV_NULLPTR_ERR;
114
115     for( i=0; i<data->size1.height; i++, start+=data->step1 )
116         for( j=0; j<data->size1.width; j++, k++ )
117             start[j] = buff[k];
118     return CV_NO_ERR;
119 }
120 /*----------------------*/
121 int write_callback_32f( int ind, void* buf, void* userData)
122 {
123     int i, j, k = 0;
124     UserData* data = (UserData*)userData;
125     float* start = ((float**)(data->addr2))[ind];
126     float* buff = (float*)buf;
127
128     if( ind<0 ) return CV_BADFACTOR_ERR;
129     if( buf==NULL || userData==NULL ) return CV_NULLPTR_ERR;
130
131     for( i=0; i<data->size2.height; i++, start+=data->step2/4 )
132         for( j=0; j<data->size2.width; j++, k++ )
133             start[j] = buff[k];
134     return CV_NO_ERR;
135 }
136
137 /*##########################################=-- Test body --=###########################*/
138 static int fmaEigenObjects( void )
139 {
140     int n, n4, i, j, ie, m1, rep = 0, roi, roi4, bufSize;
141     int roix=0, roiy=0, sizex, sizey, step, step4, step44;
142     int err0, err1, err2, err3, err4, err5, err6, err7, err=0;
143     uchar *pro, *pro0, *object;
144     uchar** objs;
145     float *covMatr, *covMatr0, *avg, *avg0, *eigVal, *eigVal0, *coeffs, *coeffs0,
146           covMatrMax, coeffm, singleCoeff0;
147     float **eigObjs, **eigObjs0;
148     IplImage **Objs, **EigObjs, **EigObjs0, *Pro, *Pro0, *Object, *Avg, *Avg0;
149     double eps0, amax=0, singleCoeff, p;
150     AtsRandState state;
151     CvSize size;
152     int  r;
153     CvTermCriteria limit;
154     UserData userData;
155     int (*read_callback)( int ind, void* buf, void* userData)=
156                  read_callback_8u;
157     int (*read2_callback)( int ind, void* buf, void* userData)=
158                  read_callback_32f;
159     int (*write_callback)( int ind, void* buf, void* userData)=
160                  write_callback_32f;
161     CvInput* u_r = (CvInput*)&read_callback;
162     CvInput* u_r2= (CvInput*)&read2_callback;
163     CvInput* u_w = (CvInput*)&write_callback;
164     void* read_    = (u_r)->data;
165     void* read_2   = (u_r2)->data;
166     void* write_   = (u_w)->data;
167
168     /* Reading test parameters */
169     trsiRead( &obj_width,    "100", "width of objects" );
170     trsiRead( &obj_height,   "100", "height of objects" );
171     trsiRead( &obj_number,    "11", "number of objects" );
172     trsdRead( &rel_bufSize, "0.09", "relative i/o buffer size" );
173
174     if( rel_bufSize < 0.0 ) rel_bufSize = 0.0;
175     m1  = obj_number - 1;
176     eps0= 1.0e-27;
177     n = obj_width * obj_height;
178     sizex = obj_width,  sizey = obj_height;
179
180     Objs     = (IplImage**)cvAlloc(sizeof(IplImage*) * obj_number );
181     EigObjs  = (IplImage**)cvAlloc(sizeof(IplImage*) * m1         );
182     EigObjs0 = (IplImage**)cvAlloc(sizeof(IplImage*) * m1         );
183
184     objs     = (uchar**)cvAlloc(sizeof(uchar*) * obj_number     );
185     eigObjs  = (float**)cvAlloc(sizeof(float*) * m1             );
186     eigObjs0 = (float**)cvAlloc(sizeof(float*) * m1             );
187     covMatr  = (float*) cvAlloc(sizeof(float)  * obj_number * obj_number );
188     covMatr0 = (float*) cvAlloc(sizeof(float)  * obj_number * obj_number );
189     coeffs   = (float*) cvAlloc(sizeof(float*) * m1             );
190     coeffs0  = (float*) cvAlloc(sizeof(float*) * m1             );
191     eigVal   = (float*) cvAlloc(sizeof(float)  * obj_number     );
192     eigVal0  = (float*) cvAlloc(sizeof(float)  * obj_number     );
193
194     size.width = obj_width;  size.height = obj_height;
195     atsRandInit( &state, 0, 255, 13 );
196
197     Avg  = cvCreateImage( size, IPL_DEPTH_32F, 1 );
198     cvSetImageROI( Avg, cvRect(0, 0, Avg->width, Avg->height) );
199     Avg0 = cvCreateImage( size, IPL_DEPTH_32F, 1 );
200     cvSetImageROI( Avg0, cvRect(0, 0, Avg0->width, Avg0->height) );
201     avg  = (float*)Avg->imageData;
202     avg0 = (float*)Avg0->imageData;
203     Pro  = cvCreateImage( size, IPL_DEPTH_8U, 1 );
204     cvSetImageROI( Pro, cvRect(0, 0, Pro->width, Pro->height) );
205     Pro0 = cvCreateImage( size, IPL_DEPTH_8U, 1 );
206     cvSetImageROI( Pro0, cvRect(0, 0, Pro0->width, Pro0->height) );
207     pro  = (uchar*)Pro->imageData;
208     pro0 = (uchar*)Pro0->imageData;
209     Object = cvCreateImage( size, IPL_DEPTH_8U, 1 );
210     cvSetImageROI( Object, cvRect(0, 0, Object->width, Object->height) );
211     object = (uchar*)Object->imageData;
212
213     step = Pro->widthStep;  step4 = Avg->widthStep;  step44 = step4/4;
214     n = step*obj_height;   n4= step44*obj_height;
215     atsbRand8u ( &state, object, n );
216
217     for( i=0; i<obj_number; i++ )
218     {
219         Objs[i]     = cvCreateImage( size, IPL_DEPTH_8U, 1 );
220         cvSetImageROI( Objs[i], cvRect(0, 0, Objs[i]->width, Objs[i]->height) );
221         objs[i] = (uchar*)Objs[i]->imageData;
222         atsbRand8u ( &state, objs[i], n );
223         if( i < m1 )
224         {
225             EigObjs[i]  = cvCreateImage( size, IPL_DEPTH_32F, 1 );
226             cvSetImageROI( EigObjs[i], cvRect(0, 0, EigObjs[i]->width, EigObjs[i]->height) );
227             EigObjs0[i] = cvCreateImage( size, IPL_DEPTH_32F, 1 );
228             cvSetImageROI( EigObjs0[i], cvRect(0, 0, EigObjs0[i]->width, EigObjs0[i]->height) );
229         }
230     }
231
232     limit.type = CV_TERMCRIT_ITER;  limit.max_iter = m1;  limit.epsilon = 1;//(float)eps0;
233
234     bufSize = (int)(4*n*obj_number*rel_bufSize);
235 trsWrite(TW_RUN|TW_CON, "\n i/o buffer size : %10d bytes\n", bufSize );
236
237 trsWrite(TW_RUN|TW_CON, "\n ROI unsupported\n" );
238
239 /* User data fill */
240     userData.addr1 = (void*)objs;
241     userData.addr2 = (void*)eigObjs;
242     userData.step1 = step;
243     userData.step2 = step4;
244
245
246 repeat:
247     roi  = roiy*step    + roix;
248     roi4 = roiy*step44 + roix;
249
250     Avg->roi->xOffset    = roix;         Avg->roi->yOffset    = roiy;
251     Avg->roi->height     = size.height;  Avg->roi->width      = size.width;
252     Avg0->roi->xOffset   = roix;         Avg0->roi->yOffset   = roiy;
253     Avg0->roi->height    = size.height;  Avg0->roi->width     = size.width;
254     Pro->roi->xOffset    = roix;         Pro->roi->yOffset    = roiy;
255     Pro->roi->height     = size.height;  Pro->roi->width      = size.width;
256     Pro0->roi->xOffset   = roix;         Pro0->roi->yOffset   = roiy;
257     Pro0->roi->height    = size.height;  Pro0->roi->width     = size.width;
258     Object->roi->xOffset = roix;         Object->roi->yOffset = roiy;
259     Object->roi->height  = size.height;  Object->roi->width   = size.width;
260
261     for( i=0; i<obj_number; i++ )
262     {
263         Objs[i]->roi->xOffset = roix;         Objs[i]->roi->yOffset = roiy;
264         Objs[i]->roi->height  = size.height;  Objs[i]->roi->width   = size.width;
265         objs[i] = (uchar*)Objs[i]->imageData + roi;
266         if( i < m1 )
267         {
268             EigObjs[i]->roi->xOffset  = roix;        EigObjs[i]->roi->yOffset  = roiy;
269             EigObjs[i]->roi->height   = size.height; EigObjs[i]->roi->width    = size.width;
270             EigObjs0[i]->roi->xOffset = roix;        EigObjs0[i]->roi->yOffset = roiy;
271             EigObjs0[i]->roi->height  = size.height; EigObjs0[i]->roi->width   = size.width;
272             eigObjs[i]  = (float*)EigObjs[i]->imageData  + roi4;
273             eigObjs0[i] = (float*)EigObjs0[i]->imageData + roi4;
274         }
275     }
276
277     userData.size1 = userData.size2 = size;
278
279 /* =================================== Test functions run ============================= */
280
281     r = _cvCalcEigenObjects_8u32fR_q( obj_number, objs, step, eigObjs0, step4,
282                                     size, eigVal0, avg0+roi4, step4, &m1, &eps0 );
283
284     r = _cvEigenDecomposite_8u32fR_q( object+roi, step, m1, eigObjs0, step4,
285                                     avg0+roi4, step4, size, coeffs0 );
286
287     r = _cvEigenProjection_8u32fR_q( m1, eigObjs0, step4, coeffs0, avg0+roi4, step4,
288                                    pro0+roi, step, size );
289
290     r = _cvCalcCovarMatrix_8u32fR_q( obj_number, objs, step, avg0+roi4, step4,
291                                      size, covMatr0 );
292
293     singleCoeff0 = _cvCalcDecompCoeff_8u32fR_q( object+roi, step, eigObjs0[0], step4,
294                                                 avg0+roi4, step4, size );
295
296     covMatrMax = 0.f;
297     for( i=0; i<obj_number*obj_number; i++ )
298         if( covMatrMax < (float)fabs( covMatr[i] ) )
299             covMatrMax = (float)fabs( covMatr[i] );
300
301     amax = 0;
302     for( ie=0; ie<m1; ie++ )
303         for( i=0; i<size.height; i++ )
304             for( j=0; j<size.width; j++ )
305             {
306                 int ij = i*obj_width + j;
307                 float e = eigObjs0[ie][ij];
308                 if( amax < fabs(e) ) amax = fabs(e);
309             }
310
311     coeffm = 0.f;
312     for( i=0; i<m1; i++ )
313         if( coeffm < (float)fabs(coeffs0[i]) ) coeffm = (float)fabs(coeffs0[i]);
314
315 /*- - - - - - - - - - - - - - - - - - - - - without callbacks - - - - - - - - - - - - - */
316     for( i=0; i<obj_number*obj_number; i++ ) covMatr[i] = covMatr0[i];
317     for( i=0; i<size.height; i++ )
318         for( j=0; j<size.width; j++ ) pro[i*step + j] = pro0[i*step + j];
319     for( i=0; i<size.height; i++ )
320         for( j=0; j<size.width; j++ ) avg[i*step44 + j] = avg0[i*step44 + j];
321     for( i=0; i<m1;   i++ ) { coeffs[i] = coeffs0[i];  eigVal[i] = eigVal0[i]; }
322     for( ie=0; ie<m1; ie++ )
323         for( i=0; i<size.height; i++ )
324             for( j=0; j<size.width; j++ )
325                 eigObjs[ie][i*step44+j] = eigObjs0[ie][i*step44+j];
326
327     err1 = err2 = err3 = err4 = err5 = err6 = err7 = 0;
328
329     cvCalcCovarMatrixEx( obj_number,
330                          (void*)Objs,
331                          CV_EIGOBJ_NO_CALLBACK,
332                          bufSize,
333                          NULL,
334                          (void*)&userData,
335                          Avg,
336                          covMatr );
337
338     cvCalcEigenObjects ( obj_number,
339                          (void*)Objs,
340                          (void*)EigObjs,
341                          CV_EIGOBJ_NO_CALLBACK,
342                          bufSize,
343                          (void*)&userData,
344                          &limit,
345                          Avg,
346                          eigVal );
347
348     singleCoeff = cvCalcDecompCoeff( Object, EigObjs[0], Avg );
349     if( fabs( (singleCoeff - singleCoeff0)/singleCoeff0 ) > RELDIFF ) err7++;
350
351     cvEigenDecomposite( Object,
352                         m1,
353                         (void*)EigObjs,
354                         CV_EIGOBJ_NO_CALLBACK,
355                         (void*)&userData,
356                         Avg,
357                         coeffs );
358     cvEigenProjection ( (void*)EigObjs,
359                         m1,
360                         CV_EIGOBJ_NO_CALLBACK,
361                         (void*)&userData,
362                         coeffs,
363                         Avg,
364                         Pro );
365
366 /*  Covariance matrix comparision */
367     for( i=0; i<obj_number*obj_number; i++ )
368         if( fabs(covMatr[i] - covMatr0[i]) > RELDIFF*fabs(covMatrMax) ) err6++;
369
370 /*  Averaged object comparision */
371     for( i=0; i<size.height; i++ )
372         for( j=0; j<size.width; j++ )
373         {
374             int ij = i*step44 + j;
375             if( fabs( (avg+roi)[ij] - (avg0+roi)[ij] ) > MAXDIFF ) err1++;
376         }
377
378 /*  Eigen objects comparision */
379     for( ie=0; ie<m1; ie++ )
380         for( i=0; i<size.height; i++ )
381             for( j=0; j<size.width; j++ )
382             {
383                 int ij = i*step44 + j;
384                 float e0 = (eigObjs0[ie])[ij],  e = (eigObjs[ie])[ij];
385                 if( fabs( (e-e0)/amax ) > RELDIFF ) err2++;
386             }
387
388 /*  Eigen values comparision */
389     for( i=0; i<m1; i++ )
390     {
391         double e0 = eigVal0[i], e = eigVal[i];
392         if(e0)
393             if( fabs( (e-e0)/e0 ) > RELDIFF ) err3++;
394     }
395
396 /*  Decomposition coefficients comparision */
397     for( i=0; i<m1; i++ )
398         if(coeffs0[i])
399             if( fabs( (coeffs[i] - coeffs0[i])/coeffm ) > RELDIFF ) err4++;
400
401 /*  Projection comparision */
402     for( i=0; i<size.height; i++ )
403         for( j=0; j<size.width; j++ )
404         {
405             int ij = i*step + j;
406             if( fabs( (double)((pro+roi)[ij] - (pro0+roi)[ij]) ) > MAXDIFF ) err5++;
407         }
408
409     err0 = 0;
410     p = 100.f*err6/(float)(obj_number*obj_number);
411     if( p>0.1 )
412     {
413         trsWrite(TW_RUN|TW_CON, "         Covar. matrix - %d errors (%7.3f %% );\n", err6, p );
414         err0 += err6;
415     }
416     p = 100.f*err1/(float)(size.height*size.width);
417     if( p>0.1 )
418     {
419         trsWrite(TW_RUN|TW_CON, "         Averaged obj. - %d errors (%7.3f %% );\n", err1, p );
420         err0 += err1;
421     }
422     p = 100.f*err3/(float)(m1);
423     if( p>0.1 )
424     {
425         trsWrite(TW_RUN|TW_CON, "         Eigen values  - %d errors (%7.3f %% );\n", err3, p );
426         err0 += err3;
427     }
428     p = 100.f*err2/(float)(size.height*size.width*m1);
429     if( p>0.1 )
430     {
431         trsWrite(TW_RUN|TW_CON, "         Eigen objects - %d errors (%7.3f %% );\n", err2, p );
432         err0 += err2;
433     }
434     p = 100.f*err4/(float)(m1);
435     if( p>0.1 )
436     {
437         trsWrite(TW_RUN|TW_CON, "         Decomp.coeffs - %d errors (%7.3f %% );\n", err4, p );
438         err0 += err4;
439     }
440     if( ((float)err7)/m1 > 0.1 )
441     {
442         trsWrite(TW_RUN|TW_CON, "         Single dec.c. - %d errors        ;\n", err7);
443         err0 += err7;
444     }
445     p = 100.f*err5/(float)(size.height*size.width);
446     if( p>0.1 )
447     {
448         trsWrite(TW_RUN|TW_CON, "         Projection    - %d errors (%7.3f %% );\n", err5, p );
449         err0 += err5;
450     }
451     trsWrite(TW_RUN|TW_CON, "     without callbacks :  %8d  errors;\n", err0 );
452
453     err += err0;
454
455 /*- - - - - - - - - - - - - - - - - - - - - input callback - - - - - - - - - - - - - */
456     for( i=0; i<size.height; i++ )
457         for( j=0; j<size.width; j++ ) pro[i*step + j] = pro0[i*step + j];
458     for( i=0; i<size.height; i++ )
459         for( j=0; j<size.width; j++ ) avg[i*step44 + j] = avg0[i*step44 + j];
460     for( i=0; i<m1;   i++ ) { coeffs[i] = coeffs0[i];  eigVal[i] = eigVal0[i]; }
461     for( ie=0; ie<m1; ie++ )
462         for( i=0; i<size.height; i++ )
463             for( j=0; j<size.width; j++ )
464                 eigObjs[ie][i*step44+j] = eigObjs0[ie][i*step44+j];
465
466     err1 = err2 = err3 = err4 = err5 = err6 = err7 = 0;
467
468     cvCalcEigenObjects ( obj_number,
469                          read_,
470                          (void*)EigObjs,
471                          CV_EIGOBJ_INPUT_CALLBACK,
472                          bufSize,
473                          (void*)&userData,
474                          &limit,
475                          Avg,
476                          eigVal );
477
478     cvEigenDecomposite( Object,
479                         m1,
480                         read_2,
481                         CV_EIGOBJ_INPUT_CALLBACK,
482                         (void*)&userData,
483                         Avg,
484                         coeffs );
485
486     cvEigenProjection ( read_2,
487                         m1,
488                         CV_EIGOBJ_INPUT_CALLBACK,
489                         (void*)&userData,
490                         coeffs,
491                         Avg,
492                         Pro );
493
494 /*  Averaged object comparision */
495     for( i=0; i<size.height; i++ )
496         for( j=0; j<size.width; j++ )
497         {
498             int ij = i*step44 + j;
499             if( fabs( (avg+roi)[ij] - (avg0+roi)[ij] ) > MAXDIFF ) err1++;
500         }
501
502 /*  Eigen objects comparision */
503     for( ie=0; ie<m1; ie++ )
504         for( i=0; i<size.height; i++ )
505             for( j=0; j<size.width; j++ )
506             {
507                 int ij = i*step44 + j;
508                 float e0 = (eigObjs0[ie])[ij],  e = (eigObjs[ie])[ij];
509                     if( fabs( (e-e0)/amax ) > RELDIFF ) err2++;
510             }
511
512 /*  Eigen values comparision */
513     for( i=0; i<m1; i++ )
514     {
515         double e0 = eigVal0[i], e = eigVal[i];
516         if(e0)
517             if( fabs( (e-e0)/e0 ) > RELDIFF ) err3++;
518     }
519
520 /*  Projection comparision */
521     for( i=0; i<size.height; i++ )
522         for( j=0; j<size.width; j++ )
523         {
524             int ij = i*step + j;
525             if( fabs( (double)((pro+roi)[ij] - (pro0+roi)[ij]) ) > MAXDIFF ) err5++;
526         }
527
528 /*  Decomposition coefficients comparision */
529     for( i=0; i<m1; i++ )
530         if(coeffs0[i])
531             if( fabs( (coeffs[i] - coeffs0[i])/coeffm ) > RELDIFF ) err4++;
532
533     err0 = 0;
534     p = 100.f*err1/(float)(size.height*size.width);
535     if( p>0.1 )
536     {
537         trsWrite(TW_RUN|TW_CON, "         Averaged obj. - %d errors (%7.3f %% );\n", err1, p );
538         err0 += err1;
539     }
540     p = 100.f*err3/(float)(m1);
541     if( p>0.1 )
542     {
543         trsWrite(TW_RUN|TW_CON, "         Eigen values  - %d errors (%7.3f %% );\n", err3, p );
544         err0 += err3;
545     }
546     p = 100.f*err2/(float)(size.height*size.width*m1);
547     if( p>0.1 )
548     {
549         trsWrite(TW_RUN|TW_CON, "         Eigen objects - %d errors (%7.3f %% );\n", err2, p );
550         err0 += err2;
551     }
552     p = 100.f*err4/(float)(m1);
553     if( p>0.1 )
554     {
555         trsWrite(TW_RUN|TW_CON, "         Decomp.coeffs - %d errors (%7.3f %% );\n", err4, p );
556         err0 += err4;
557     }
558     p = 100.f*err5/(float)(size.height*size.width);
559     if( p>0.1 )
560     {
561         trsWrite(TW_RUN|TW_CON, "         Projection    - %d errors (%7.3f %% );\n", err5, p );
562         err0 += err5;
563     }
564     trsWrite(TW_RUN|TW_CON, "        input callback :  %8d  errors;\n", err0 );
565
566     err += err0;
567
568 /*- - - - - - - - - - - - - - - - - - - - - output callback - - - - - - - - - - - - - */
569     for( i=0; i<size.height; i++ )
570         for( j=0; j<size.width; j++ ) avg[i*step44 + j] = avg0[i*step44 + j];
571     for( i=0; i<m1;   i++ ) eigVal[i] = eigVal0[i];
572     for( ie=0; ie<m1; ie++ )
573         for( i=0; i<size.height; i++ )
574             for( j=0; j<size.width; j++ )
575                 eigObjs[ie][i*step44+j] = eigObjs0[ie][i*step44+j];
576
577     err1 = err2 = err3 = err4 = err5 = 0;
578
579     cvCalcEigenObjects ( obj_number,
580                          (void*)Objs,
581                          write_,
582                          CV_EIGOBJ_OUTPUT_CALLBACK,
583                          bufSize,
584                          (void*)&userData,
585                          &limit,
586                          Avg,
587                          eigVal );
588
589 /*  Averaged object comparision */
590     for( i=0; i<size.height; i++ )
591         for( j=0; j<size.width; j++ )
592         {
593             int ij = i*step44 + j;
594             if( fabs( (avg+roi)[ij] - (avg0+roi)[ij] ) > MAXDIFF ) err1++;
595         }
596
597 /*  Eigen objects comparision */
598     for( ie=0; ie<m1; ie++ )
599         for( i=0; i<size.height; i++ )
600             for( j=0; j<size.width; j++ )
601             {
602                 int ij = i*step44 + j;
603                 float e0 = (eigObjs0[ie])[ij],  e = (eigObjs[ie])[ij];
604                     if( fabs( (e-e0)/amax ) > RELDIFF ) err2++;
605             }
606
607 /*  Eigen values comparision */
608     for( i=0; i<m1; i++ )
609     {
610         double e0 = eigVal0[i], e = eigVal[i];
611         if(e0)
612             if( fabs( (e-e0)/e0 ) > RELDIFF ) err3++;
613     }
614
615     err0 = 0;
616     p = 100.f*err1/(float)(size.height*size.width);
617     if( p>0.1 )
618     {
619         trsWrite(TW_RUN|TW_CON, "         Averaged obj. - %d errors (%7.3f %% );\n", err1, p );
620         err0 += err1;
621     }
622     p = 100.f*err3/(float)(m1);
623     if( p>0.1 )
624     {
625         trsWrite(TW_RUN|TW_CON, "         Eigen values  - %d errors (%7.3f %% );\n", err3, p );
626         err0 += err3;
627     }
628     p = 100.f*err2/(float)(size.height*size.width*m1);
629     if( p>0.1 )
630     {
631         trsWrite(TW_RUN|TW_CON, "         Eigen objects - %d errors (%7.3f %% );\n", err2, p );
632         err0 += err2;
633     }
634     trsWrite(TW_RUN|TW_CON, "       output callback :  %8d  errors;\n", err0 );
635
636     err += err0;
637
638 /*- - - - - - - - - - - - - - - - - - - - - both callbacks - - - - - - - - - - - - - */
639     for( i=0; i<size.height; i++ )
640         for( j=0; j<size.width; j++ ) avg[i*step44 + j] = avg0[i*step44 + j];
641     for( i=0; i<m1;   i++ ) eigVal[i] = eigVal0[i];
642     for( ie=0; ie<m1; ie++ )
643         for( i=0; i<size.height; i++ )
644             for( j=0; j<size.width; j++ )
645                 eigObjs[ie][i*step44+j] = eigObjs0[ie][i*step44+j];
646
647     err1 = err2 = err3 = err4 = err5 = 0;
648
649     cvCalcEigenObjects ( obj_number,
650                          read_,
651                          write_,
652                          CV_EIGOBJ_INPUT_CALLBACK | CV_EIGOBJ_OUTPUT_CALLBACK,
653                          bufSize,
654                          (void*)&userData,
655                          &limit,
656                          Avg,
657                          eigVal );
658
659 /*  Averaged object comparision */
660     for( i=0; i<size.height; i++ )
661         for( j=0; j<size.width; j++ )
662         {
663             int ij = i*step44 + j;
664             if( fabs( (avg+roi)[ij] - (avg0+roi)[ij] ) > MAXDIFF ) err1++;
665         }
666
667 /*  Eigen objects comparision */
668     for( ie=0; ie<m1; ie++ )
669         for( i=0; i<size.height; i++ )
670             for( j=0; j<size.width; j++ )
671             {
672                 int ij = i*step44 + j;
673                 float e0 = (eigObjs0[ie])[ij],  e = (eigObjs[ie])[ij];
674                     if( fabs( (e-e0)/amax ) > RELDIFF ) err2++;
675             }
676
677 /*  Eigen values comparision */
678     for( i=0; i<m1; i++ )
679     {
680         double e0 = eigVal0[i], e = eigVal[i];
681         if(e0)
682             if( fabs( (e-e0)/e0 ) > RELDIFF ) err3++;
683     }
684
685     err0 = 0;
686     p = 100.f*err1/(float)(size.height*size.width);
687     if( p>0.1 )
688     {
689         trsWrite(TW_RUN|TW_CON, "         Averaged obj. - %d errors (%7.3f %% );\n", err1, p );
690         err0 += err1;
691     }
692     p = 100.f*err3/(float)(m1);
693     if( p>0.1 )
694     {
695         trsWrite(TW_RUN|TW_CON, "         Eigen values  - %d errors (%7.3f %% );\n", err3, p );
696         err0 += err3;
697     }
698     p = 100.f*err2/(float)(size.height*size.width*m1);
699     if( p>0.1 )
700     {
701         trsWrite(TW_RUN|TW_CON, "         Eigen objects - %d errors (%7.3f %% );\n", err2, p );
702         err0 += err2;
703     }
704     trsWrite(TW_RUN|TW_CON, "        both callbacks :  %8d  errors;\n", err0 );
705
706     err += err0;
707
708
709 /*================================-- test with ROI --===================================*/
710
711     if(!rep)
712     {
713         roix  = (int)(0.157f*obj_width);
714         roiy  = (int)(0.131f*obj_height);
715         sizex = (int)(0.611f*obj_width);
716         sizey = (int)(0.737f*obj_height);
717         roi   = roiy*obj_width + roix;
718
719 trsWrite(TW_RUN|TW_CON, "\n ROI   supported\n" );
720         rep++;
721         size.width = sizex;  size.height = sizey;
722
723         goto repeat;
724     }
725
726 /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ free memory ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
727     cvReleaseImage( &Avg    );
728     cvReleaseImage( &Avg0   );
729     cvReleaseImage( &Pro    );
730     cvReleaseImage( &Pro0   );
731     cvReleaseImage( &Object );
732     for( i=0; i<obj_number; i++ )
733     {
734         cvReleaseImage( &Objs[i] );
735         if( i < m1 )
736         {
737             cvReleaseImage( &EigObjs[i]  );
738             cvReleaseImage( &EigObjs0[i] );
739         }
740     }
741
742     cvFree( &objs     );
743     cvFree( &eigObjs  );
744     cvFree( &eigObjs0 );
745     cvFree( &coeffs   );
746     cvFree( &coeffs0  );
747     cvFree( &eigVal   );
748     cvFree( &eigVal0  );
749     cvFree( &Objs     );
750     cvFree( &EigObjs  );
751     cvFree( &EigObjs0 );
752     cvFree( &covMatr  );
753     cvFree( &covMatr0 );
754
755 trsWrite(TW_RUN|TW_CON, "\n Errors number: %d\n", err );
756
757     if(err) return trsResult( TRS_FAIL, "Algorithm test has passed. %d errors.", err );
758     else    return trsResult( TRS_OK, "Algorithm test has passed successfully" );
759     
760 } /*fma*/
761
762 /*------------------------------------------- Initialize function ------------------------ */
763 void InitAEigenObjects( void )
764 {
765    /* Registering test function */
766     trsReg( FuncName, TestName, TestClass, fmaEigenObjects );
767 } /* InitAEigenObjects */
768
769 #endif
770
771 /*  End of file  */