16acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*M///////////////////////////////////////////////////////////////////////////////////////
26acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
36acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
46acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
56acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  By downloading, copying, installing or using the software you agree to this license.
66acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  If you do not agree to this license, do not download, install,
76acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//  copy or use the software.
86acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
96acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                        Intel License Agreement
116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                For Open Source Computer Vision Library
126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Copyright (C) 2000, Intel Corporation, all rights reserved.
146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Third party copyrights are property of their respective owners.
156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// Redistribution and use in source and binary forms, with or without modification,
176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// are permitted provided that the following conditions are met:
186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's of source code must retain the above copyright notice,
206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer.
216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * Redistribution's in binary form must reproduce the above copyright notice,
236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     this list of conditions and the following disclaimer in the documentation
246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     and/or other materials provided with the distribution.
256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//   * The name of Intel Corporation may not be used to endorse or promote products
276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//     derived from this software without specific prior written permission.
286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// This software is provided by the copyright holders and contributors "as is" and
306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// any express or implied warranties, including, but not limited to, the implied
316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// warranties of merchantability and fitness for a particular purpose are disclaimed.
326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// In no event shall the Intel Corporation or contributors be liable for any direct,
336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// indirect, incidental, special, exemplary, or consequential damages
346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// (including, but not limited to, procurement of substitute goods or services;
356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// loss of use, data, or profits; or business interruption) however caused
366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// and on any theory of liability, whether in contract, strict liability,
376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// or tort (including negligence or otherwise) arising in any way out of
386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn// the use of this software, even if advised of the possibility of such damage.
396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//M*/
416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn#include "_cvaux.h"
436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCvStatus CV_STDCALL
456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvJacobiEigens_32f(float *A, float *V, float *E, int n, float eps)
466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k, ind;
486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *AA = A, *VV = V;
496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double Amax, anorm = 0, ax;
506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( A == NULL || V == NULL || E == NULL )
526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( n <= 0 )
546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( eps < 1.0e-7f )
566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eps = 1.0e-7f;
576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*-------- Prepare --------*/
596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < n; i++, VV += n, AA += n )
606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < i; j++ )
626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            double Am = AA[j];
646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            anorm += Am * Am;
666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < n; j++ )
686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            VV[j] = 0.f;
696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        VV[i] = 1.f;
706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    anorm = sqrt( anorm + anorm );
736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ax = anorm * eps / n;
746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    Amax = anorm;
756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    while( Amax > ax )
776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Amax /= n;
796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        do                      /* while (ind) */
806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int p, q;
826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float *V1 = V, *A1 = A;
836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ind = 0;
856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( p = 0; p < n - 1; p++, A1 += n, V1 += n )
866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *A2 = A + n * (p + 1), *V2 = V + n * (p + 1);
886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( q = p + 1; q < n; q++, A2 += n, V2 += n )
906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    double x, y, c, s, c2, s2, a;
926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float *A3, Apq = A1[q], App, Aqq, Aip, Aiq, Vpi, Vqi;
936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( fabs( Apq ) < Amax )
956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        continue;
966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    ind = 1;
986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /*---- Calculation of rotation angle's sine & cosine ----*/
1006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    App = A1[p];
1016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    Aqq = A2[q];
1026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    y = 5.0e-1 * (App - Aqq);
1036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    x = -Apq / sqrt( (double)Apq * Apq + (double)y * y );
1046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( y < 0.0 )
1056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        x = -x;
1066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s = x / sqrt( 2.0 * (1.0 + sqrt( 1.0 - (double)x * x )));
1076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    s2 = s * s;
1086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    c = sqrt( 1.0 - s2 );
1096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    c2 = c * c;
1106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    a = 2.0 * Apq * c * s;
1116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    /*---- Apq annulation ----*/
1136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    A3 = A;
1146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( i = 0; i < p; i++, A3 += n )
1156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
1166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aip = A3[p];
1176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aiq = A3[q];
1186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vpi = V1[i];
1196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vqi = V2[i];
1206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A3[p] = (float) (Aip * c - Aiq * s);
1216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A3[q] = (float) (Aiq * c + Aip * s);
1226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V1[i] = (float) (Vpi * c - Vqi * s);
1236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V2[i] = (float) (Vqi * c + Vpi * s);
1246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
1256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( ; i < q; i++, A3 += n )
1266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
1276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aip = A1[i];
1286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aiq = A3[q];
1296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vpi = V1[i];
1306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vqi = V2[i];
1316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A1[i] = (float) (Aip * c - Aiq * s);
1326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A3[q] = (float) (Aiq * c + Aip * s);
1336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V1[i] = (float) (Vpi * c - Vqi * s);
1346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V2[i] = (float) (Vqi * c + Vpi * s);
1356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
1366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( ; i < n; i++ )
1376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
1386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aip = A1[i];
1396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Aiq = A2[i];
1406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vpi = V1[i];
1416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        Vqi = V2[i];
1426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A1[i] = (float) (Aip * c - Aiq * s);
1436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        A2[i] = (float) (Aiq * c + Aip * s);
1446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V1[i] = (float) (Vpi * c - Vqi * s);
1456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        V2[i] = (float) (Vqi * c + Vpi * s);
1466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
1476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    A1[p] = (float) (App * c2 + Aqq * s2 - a);
1486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    A2[q] = (float) (App * s2 + Aqq * c2 + a);
1496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    A1[q] = A2[p] = 0.0f;
1506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }               /*q */
1516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                   /*p */
1526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        while( ind );
1546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        Amax /= n;
1556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /* while ( Amax > ax ) */
1566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0, k = 0; i < n; i++, k += n + 1 )
1586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        E[i] = A[k];
1596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /*printf(" M = %d\n", M); */
1606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* -------- ordering -------- */
1626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < n; i++ )
1636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
1646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int m = i;
1656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float Em = (float) fabs( E[i] );
1666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = i + 1; j < n; j++ )
1686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float Ej = (float) fabs( E[j] );
1706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            m = (Em < Ej) ? j : m;
1726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            Em = (Em < Ej) ? Ej : Em;
1736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( m != i )
1756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
1766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int l;
1776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float b = E[i];
1786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            E[i] = E[m];
1806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            E[m] = b;
1816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0, k = i * n, l = m * n; j < n; j++, k++, l++ )
1826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
1836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b = V[k];
1846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                V[k] = V[l];
1856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                V[l] = b;
1866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
1876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
1886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
1896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
1916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
1926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
1936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
1946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvCalcCovarMatrixEx_8u32fR
1956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates a covariance matrix for a group of input objects
1966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             (images, vectors, etc.). ROI supported.
1976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
1986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  nObjects    - number of source objects
1996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 objects     - array of pointers to ROIs of the source objects
2006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 imgStep     - full width of each source object row in bytes
2016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg         - pointer to averaged object
2026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avgStep     - full width of averaged object row in bytes
2036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 size        - ROI size of each source and averaged objects
2046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 covarMatrix - covariance matrix (output parameter; must be allocated
2056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               before call)
2066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
2076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: CV_NO_ERR or error code
2086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
2096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
2106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
2116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus  CV_STDCALL
2126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCalcCovarMatrixEx_8u32fR( int nObjects, void *input, int objStep1,
2136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             int ioFlags, int ioBufSize, uchar* buffer,
2146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             void *userData, float *avg, int avgStep,
2156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                             CvSize size, float *covarMatrix )
2166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
2176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int objStep = objStep1;
2186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* ---- TEST OF PARAMETERS ---- */
2206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( nObjects < 2 )
2226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
2236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags < 0 || ioFlags > 3 )
2246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
2256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags && ioBufSize < 1024 )
2266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
2276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags && buffer == NULL )
2286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
2296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( input == NULL || avg == NULL || covarMatrix == NULL )
2306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
2316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width > objStep || 4 * size.width > avgStep || size.height < 1 )
2326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
2336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    avgStep /= 4;
2356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )    /* ==== USE INPUT CALLBACK ==== */
2376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
2386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int nio, ngr, igr, n = size.width * size.height, mm = 0;
2396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvCallback read_callback = ((CvInput *) & input)->callback;
2406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar *buffer2;
2416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objStep = n;
2436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nio = ioBufSize / n;    /* number of objects in buffer */
2446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ngr = nObjects / nio;   /* number of io groups */
2456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( nObjects % nio )
2466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            mm = 1;
2476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ngr += mm;
2486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer2 = (uchar *)cvAlloc( sizeof( uchar ) * n );
2506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer2 == NULL )
2516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
2526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( igr = 0; igr < ngr; igr++ )
2546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
2556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int k, l;
2566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int io, jo, imin = igr * nio, imax = imin + nio;
2576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *bu1 = buffer, *bu2;
2586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( imax > nObjects )
2606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                imax = nObjects;
2616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* read igr group */
2636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( io = imin; io < imax; io++, bu1 += n )
2646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvStatus r;
2666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r = (CvStatus)read_callback( io, (void *) bu1, userData );
2686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( r )
2696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return r;
2706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* diagonal square calc */
2736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bu1 = buffer;
2746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( io = imin; io < imax; io++, bu1 += n )
2756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bu2 = bu1;
2776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( jo = io; jo < imax; jo++, bu2 += n )
2786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
2796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float w = 0.f;
2806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float *fu = avg;
2816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int ij = 0;
2826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < size.height; k++, fu += avgStep )
2846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( l = 0; l < size.width; l++, ij++ )
2856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
2866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float f = fu[l], u1 = bu1[ij], u2 = bu2[ij];
2876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
2896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
2906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    covarMatrix[io * nObjects + jo] = covarMatrix[jo * nObjects + io] = w;
2916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
2926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
2936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            /* non-diagonal elements calc */
2956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( jo = imax; jo < nObjects; jo++ )
2966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
2976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvStatus r;
2986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
2996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bu1 = buffer;
3006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bu2 = buffer2;
3016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                /* read jo object */
3036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r = (CvStatus)read_callback( jo, (void *) bu2, userData );
3046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( r )
3056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return r;
3066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( io = imin; io < imax; io++, bu1 += n )
3086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float w = 0.f;
3106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float *fu = avg;
3116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int ij = 0;
3126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < size.height; k++, fu += avgStep )
3146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( l = 0; l < size.width - 3; l += 4, ij += 4 )
3166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
3176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float f = fu[l];
3186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            uchar u1 = bu1[ij];
3196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            uchar u2 = bu2[ij];
3206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
3226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = fu[l + 1];
3236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u1 = bu1[ij + 1];
3246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u2 = bu2[ij + 1];
3256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
3266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = fu[l + 2];
3276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u1 = bu1[ij + 2];
3286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u2 = bu2[ij + 2];
3296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
3306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = fu[l + 3];
3316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u1 = bu1[ij + 3];
3326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            u2 = bu2[ij + 3];
3336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
3346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
3356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( ; l < size.width; l++, ij++ )
3366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
3376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float f = fu[l], u1 = bu1[ij], u2 = bu2[ij];
3386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            w += (u1 - f) * (u2 - f);
3406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
3416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    covarMatrix[io * nObjects + jo] = covarMatrix[jo * nObjects + io] = w;
3436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
3446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
3456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                       /* igr */
3466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer2 );
3486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /* if() */
3496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
3516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* ==== NOT USE INPUT CALLBACK ==== */
3526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
3536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int i, j;
3546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar **objects = (uchar **) (((CvInput *) & input)->data);
3556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nObjects; i++ )
3576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
3586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *bu = objects[i];
3596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = i; j < nObjects; j++ )
3616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
3626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                int k, l;
3636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float w = 0.f;
3646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *a = avg;
3656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *bu1 = bu;
3666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *bu2 = objects[j];
3676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( k = 0; k < size.height;
3696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     k++, bu1 += objStep, bu2 += objStep, a += avgStep )
3706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
3716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( l = 0; l < size.width - 3; l += 4 )
3726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float f = a[l];
3746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar u1 = bu1[l];
3756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar u2 = bu2[l];
3766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        w += (u1 - f) * (u2 - f);
3786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = a[l + 1];
3796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u1 = bu1[l + 1];
3806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u2 = bu2[l + 1];
3816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        w += (u1 - f) * (u2 - f);
3826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = a[l + 2];
3836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u1 = bu1[l + 2];
3846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u2 = bu2[l + 2];
3856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        w += (u1 - f) * (u2 - f);
3866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = a[l + 3];
3876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u1 = bu1[l + 3];
3886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u2 = bu2[l + 3];
3896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        w += (u1 - f) * (u2 - f);
3906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( ; l < size.width; l++ )
3926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
3936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float f = a[l];
3946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar u1 = bu1[l];
3956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar u2 = bu2[l];
3966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
3976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        w += (u1 - f) * (u2 - f);
3986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
3996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
4006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                covarMatrix[i * nObjects + j] = covarMatrix[j * nObjects + i] = w;
4026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
4036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
4046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /* else */
4056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
4076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*======================== end of icvCalcCovarMatrixEx_8u32fR ===========================*/
4106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic int
4136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvDefaultBufferSize( void )
4146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return 10 * 1024 * 1024;
4166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
4176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
4196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvCalcEigenObjects_8u32fR
4206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates an orthonormal eigen basis and a mean (averaged)
4216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object for a group of input objects (images, vectors, etc.). ROI supported.
4226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
4236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: nObjects  - number of source objects
4246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                input     - pointer either to array of pointers to input objects
4256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            or to read callback function (depending on ioFlags)
4266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                imgStep   - full width of each source object row in bytes
4276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                output    - pointer either to array of pointers to output eigen objects
4286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            or to write callback function (depending on ioFlags)
4296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                eigStep   - full width of each eigenobject row in bytes
4306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                size      - ROI size of each source object
4316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                ioFlags   - input/output flags (see Notes)
4326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                ioBufSize - input/output buffer size
4336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                userData  - pointer to the structure which contains all necessary
4346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            data for the callback functions
4356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                calcLimit - determines the calculation finish conditions
4366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                avg       - pointer to averaged object (has the same size as ROI)
4376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                avgStep   - full width of averaged object row in bytes
4386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                eigVals   - pointer to corresponding eigenvalues (array of <nObjects>
4396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            elements in descending order)
4406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: CV_NO_ERR or error code
4426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes: 1. input/output data (that is, input objects and eigen ones) may either
4446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              be allocated in the RAM or be read from/written to the HDD (or any
4456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              other device) by read/write callback functions. It depends on the
4466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              value of ioFlags paramater, which may be the following:
4476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_NO_CALLBACK, or 0;
4486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_INPUT_CALLBACK;
4496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_OUTPUT_CALLBACK;
4506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_BOTH_CALLBACK, or
4516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            CV_EIGOBJ_INPUT_CALLBACK | CV_EIGOBJ_OUTPUT_CALLBACK.
4526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              The callback functions as well as the user data structure must be
4536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              developed by the user.
4546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           2. If ioBufSize = 0, or it's too large, the function dermines buffer size
4566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              itself.
4576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           3. Depending on calcLimit parameter, calculations are finished either if
4596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              eigenfaces number comes up to certain value or the relation of the
4606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              current eigenvalue and the largest one comes down to certain value
4616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              (or any of the above conditions takes place). The calcLimit->type value
4626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              must be CV_TERMCRIT_NUMB, CV_TERMCRIT_EPS or
4636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              CV_TERMCRIT_NUMB | CV_TERMCRIT_EPS. The function returns the real
4646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              values calcLimit->max_iter and calcLimit->epsilon.
4656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           4. eigVals may be equal to NULL (if you don't need eigen values in further).
4676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
4686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
4696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
4706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCalcEigenObjects_8u32fR( int nObjects, void* input, int objStep,
4716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            void* output, int eigStep, CvSize size,
4726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int  ioFlags, int ioBufSize, void* userData,
4736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvTermCriteria* calcLimit, float* avg,
4746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            int    avgStep, float  *eigVals )
4756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
4766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, n, iev = 0, m1 = nObjects - 1, objStep1 = objStep, eigStep1 = eigStep / 4;
4776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize objSize, eigSize, avgSize;
4786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *c = 0;
4796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *ev = 0;
4806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *bf = 0;
4816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *buf = 0;
4826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    void *buffer = 0;
4836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float m = 1.0f / (float) nObjects;
4846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvStatus r;
4856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( m1 > calcLimit->max_iter && calcLimit->type != CV_TERMCRIT_EPS )
4876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m1 = calcLimit->max_iter;
4886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* ---- TEST OF PARAMETERS ---- */
4906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
4916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( nObjects < 2 )
4926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
4936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags < 0 || ioFlags > 3 )
4946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
4956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( input == NULL || output == NULL || avg == NULL )
4966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
4976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width > objStep || 4 * size.width > eigStep ||
4986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        4 * size.width > avgStep || size.height < 1 )
4996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
5006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !(ioFlags & CV_EIGOBJ_INPUT_CALLBACK) )
5016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nObjects; i++ )
5026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ((uchar **) input)[i] == NULL )
5036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NULLPTR_ERR;
5046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !(ioFlags & CV_EIGOBJ_OUTPUT_CALLBACK) )
5056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < m1; i++ )
5066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ((float **) output)[i] == NULL )
5076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NULLPTR_ERR;
5086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    avgStep /= 4;
5106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    eigStep /= 4;
5116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( objStep == size.width && eigStep == size.width && avgStep == size.width )
5136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width *= size.height;
5156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = 1;
5166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objStep = objStep1 = eigStep = eigStep1 = avgStep = size.width;
5176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    objSize = eigSize = avgSize = size;
5196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )
5216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objSize.width *= objSize.height;
5236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objSize.height = 1;
5246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objStep = objSize.width;
5256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objStep1 = size.width;
5266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags & CV_EIGOBJ_OUTPUT_CALLBACK )
5296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigSize.width *= eigSize.height;
5316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigSize.height = 1;
5326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigStep = eigSize.width;
5336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigStep1 = size.width;
5346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    n = objSize.height * objSize.width * (ioFlags & CV_EIGOBJ_INPUT_CALLBACK) +
5376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        2 * eigSize.height * eigSize.width * (ioFlags & CV_EIGOBJ_OUTPUT_CALLBACK);
5386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Buffer size determination */
5406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags )
5416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int size = icvDefaultBufferSize();
5436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ioBufSize = MIN( size, n );
5446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* memory allocation (if necesseay) */
5476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )
5496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buf = (uchar *) cvAlloc( sizeof( uchar ) * objSize.width );
5516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf == NULL )
5526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
5536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags )
5566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = (void *) cvAlloc( ioBufSize );
5586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer == NULL )
5596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( buf )
5616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buf );
5626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
5636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Calculation of averaged object */
5676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bf = avg;
5686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < avgSize.height; i++, bf += avgStep )
5696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < avgSize.width; j++ )
5706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bf[j] = 0.f;
5716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < nObjects; i++ )
5736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
5746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int k, l;
5756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar *bu = (ioFlags & CV_EIGOBJ_INPUT_CALLBACK) ? buf : ((uchar **) input)[i];
5766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )
5786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
5796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvCallback read_callback = ((CvInput *) & input)->callback;
5806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            r = (CvStatus)read_callback( i, (void *) buf, userData );
5826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( r )
5836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
5846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( buffer )
5856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvFree( &buffer );
5866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( buf )
5876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvFree( &buf );
5886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return r;
5896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
5906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
5916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        bf = avg;
5936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 0; k < avgSize.height; k++, bf += avgStep, bu += objStep1 )
5946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( l = 0; l < avgSize.width; l++ )
5956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bf[l] += bu[l];
5966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
5976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
5986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    bf = avg;
5996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < avgSize.height; i++, bf += avgStep )
6006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < avgSize.width; j++ )
6016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            bf[j] *= m;
6026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Calculation of covariance matrix */
6046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    c = (float *) cvAlloc( sizeof( float ) * nObjects * nObjects );
6056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( c == NULL )
6076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer )
6096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buffer );
6106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf )
6116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buf );
6126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
6136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r = icvCalcCovarMatrixEx_8u32fR( nObjects, input, objStep1, ioFlags, ioBufSize,
6166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                      (uchar *) buffer, userData, avg, 4 * avgStep, size, c );
6176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r )
6186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &c );
6206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer )
6216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buffer );
6226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf )
6236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buf );
6246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return r;
6256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Calculation of eigenvalues & eigenvectors */
6286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    ev = (float *) cvAlloc( sizeof( float ) * nObjects * nObjects );
6296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ev == NULL )
6316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &c );
6336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer )
6346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buffer );
6356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf )
6366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buf );
6376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
6386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( eigVals == NULL )
6416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigVals = (float *) cvAlloc( sizeof( float ) * nObjects );
6436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( eigVals == NULL )
6456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &c );
6476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &ev );
6486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( buffer )
6496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buffer );
6506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( buf )
6516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buf );
6526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
6536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
6546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        iev = 1;
6556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    r = icvJacobiEigens_32f( c, ev, eigVals, nObjects, 0.0f );
6586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &c );
6596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( r )
6606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &ev );
6626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer )
6636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buffer );
6646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buf )
6656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buf );
6666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( iev )
6676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &eigVals );
6686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return r;
6696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* Eigen objects number determination */
6726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( calcLimit->type != CV_TERMCRIT_NUMBER )
6736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < m1; i++ )
6756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( fabs( eigVals[i] / eigVals[0] ) < calcLimit->epsilon )
6766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                break;
6776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m1 = calcLimit->max_iter = i;
6786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
6796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
6806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        m1 = calcLimit->max_iter;
6816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    calcLimit->epsilon = (float) fabs( eigVals[m1 - 1] / eigVals[0] );
6826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < m1; i++ )
6846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigVals[i] = (float) (1.0 / sqrt( (double)eigVals[i] ));
6856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    /* ----------------- Calculation of eigenobjects ----------------------- */
6876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags & CV_EIGOBJ_OUTPUT_CALLBACK )
6886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
6896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int nio, ngr, igr;
6906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nio = ioBufSize / (4 * eigSize.width);  /* number of eigen objects in buffer */
6926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        ngr = m1 / nio;         /* number of io groups */
6936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( nObjects % nio )
6946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            ngr += 1;
6956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
6966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( igr = 0; igr < ngr; igr++ )
6976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
6986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int i, io, ie, imin = igr * nio, imax = imin + nio;
6996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( imax > m1 )
7016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                imax = m1;
7026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < eigSize.width * (imax - imin); i++ )
7046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                ((float *) buffer)[i] = 0.f;
7056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( io = 0; io < nObjects; io++ )
7076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *bu = ioFlags & CV_EIGOBJ_INPUT_CALLBACK ? buf : ((uchar **) input)[io];
7096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )
7116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvCallback read_callback = ((CvInput *) & input)->callback;
7136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    r = (CvStatus)read_callback( io, (void *) buf, userData );
7156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( r )
7166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &ev );
7186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( iev )
7196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cvFree( &eigVals );
7206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( buffer )
7216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cvFree( &buffer );
7226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        if( buf )
7236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            cvFree( &buf );
7246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        return r;
7256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( ie = imin; ie < imax; ie++ )
7296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int k, l;
7316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    uchar *bv = bu;
7326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float e = ev[ie * nObjects + io] * eigVals[ie];
7336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float *be = ((float *) buffer) + ((ie - imin) * eigStep);
7346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    bf = avg;
7366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( k = 0; k < size.height; k++, bv += objStep1,
7376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                         bf += avgStep, be += eigStep1 )
7386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
7396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( l = 0; l < size.width - 3; l += 4 )
7406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        {
7416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            float f = bf[l];
7426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            uchar v = bv[l];
7436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            be[l] += e * (v - f);
7456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = bf[l + 1];
7466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            v = bv[l + 1];
7476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            be[l + 1] += e * (v - f);
7486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = bf[l + 2];
7496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            v = bv[l + 2];
7506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            be[l + 2] += e * (v - f);
7516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            f = bf[l + 3];
7526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            v = bv[l + 3];
7536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            be[l + 3] += e * (v - f);
7546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        }
7556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        for( ; l < size.width; l++ )
7566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            be[l] += e * (bv[l] - bf[l]);
7576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
7586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                   /* io */
7606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ie = imin; ie < imax; ie++ )   /* calculated eigen objects writting */
7626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
7636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvCallback write_callback = ((CvInput *) & output)->callback;
7646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *be = ((float *) buffer) + ((ie - imin) * eigStep);
7656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r = (CvStatus)write_callback( ie, (void *) be, userData );
7676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( r )
7686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
7696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvFree( &ev );
7706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( iev )
7716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &eigVals );
7726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( buffer )
7736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &buffer );
7746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( buf )
7756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &buf );
7766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return r;
7776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
7786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
7796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                       /* igr */
7806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
7816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
7836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
7846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int k, p, l;
7856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < m1; i++ )       /* e.o. annulation */
7876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float *be = ((float **) output)[i];
7896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( p = 0; p < eigSize.height; p++, be += eigStep )
7916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( l = 0; l < eigSize.width; l++ )
7926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    be[l] = 0.0f;
7936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
7946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 0; k < nObjects; k++ )
7966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
7976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *bv = (ioFlags & CV_EIGOBJ_INPUT_CALLBACK) ? buf : ((uchar **) input)[k];
7986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
7996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ioFlags & CV_EIGOBJ_INPUT_CALLBACK )
8006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CvCallback read_callback = ((CvInput *) & input)->callback;
8026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                r = (CvStatus)read_callback( k, (void *) buf, userData );
8046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( r )
8056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    cvFree( &ev );
8076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( iev )
8086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &eigVals );
8096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( buffer )
8106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &buffer );
8116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    if( buf )
8126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        cvFree( &buf );
8136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    return r;
8146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
8166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < m1; i++ )
8186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
8196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float v = eigVals[i] * ev[i * nObjects + k];
8206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *be = ((float **) output)[i];
8216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *bu = bv;
8226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                bf = avg;
8246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                for( p = 0; p < size.height; p++, bu += objStep1,
8266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     bf += avgStep, be += eigStep1 )
8276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                {
8286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( l = 0; l < size.width - 3; l += 4 )
8296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    {
8306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        float f = bf[l];
8316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        uchar u = bu[l];
8326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        be[l] += v * (u - f);
8346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = bf[l + 1];
8356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u = bu[l + 1];
8366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        be[l + 1] += v * (u - f);
8376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = bf[l + 2];
8386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u = bu[l + 2];
8396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        be[l + 2] += v * (u - f);
8406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        f = bf[l + 3];
8416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        u = bu[l + 3];
8426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        be[l + 3] += v * (u - f);
8436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    }
8446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    for( ; l < size.width; l++ )
8456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                        be[l] += v * (bu[l] - bf[l]);
8466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                }
8476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }                   /* i */
8486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }                       /* k */
8496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }                           /* else */
8506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &ev );
8526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( iev )
8536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &eigVals );
8546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
8556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < m1; i++ )
8566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            eigVals[i] = 1.f / (eigVals[i] * eigVals[i]);
8576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buffer )
8586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
8596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buf )
8606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buf );
8616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
8626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
8636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* --- End of icvCalcEigenObjects_8u32fR --- */
8656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
8676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: icvCalcDecompCoeff_8u32fR
8686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates one decomposition coefficient of input object
8696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             using previously calculated eigen object and the mean (averaged) object
8706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
8716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obj     - input object
8726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 objStep - its step (in bytes)
8736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigObj  - pointer to eigen object
8746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigStep - its step (in bytes)
8756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg     - pointer to averaged object
8766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avgStep - its step (in bytes)
8776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 size    - ROI size of each source object
8786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
8796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: decomposition coefficient value or large negative value (if error)
8806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
8816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
8826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
8836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic float CV_STDCALL
8846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvCalcDecompCoeff_8u32fR( uchar* obj, int objStep,
8856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           float *eigObj, int eigStep,
8866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           float *avg, int avgStep, CvSize size )
8876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
8886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, k;
8896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float w = 0.0f;
8906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width > objStep || 4 * size.width > eigStep
8926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        || 4 * size.width > avgStep || size.height < 1 )
8936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return -1.0e30f;
8946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj == NULL || eigObj == NULL || avg == NULL )
8956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return -1.0e30f;
8966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
8976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    eigStep /= 4;
8986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    avgStep /= 4;
8996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width == objStep && size.width == eigStep && size.width == avgStep )
9016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width *= size.height;
9036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = 1;
9046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        objStep = eigStep = avgStep = size.width;
9056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++, obj += objStep, eigObj += eigStep, avg += avgStep )
9086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( k = 0; k < size.width - 4; k += 4 )
9106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float o = (float) obj[k];
9126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float e = eigObj[k];
9136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float a = avg[k];
9146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w += e * (o - a);
9166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            o = (float) obj[k + 1];
9176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            e = eigObj[k + 1];
9186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = avg[k + 1];
9196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w += e * (o - a);
9206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            o = (float) obj[k + 2];
9216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            e = eigObj[k + 2];
9226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = avg[k + 2];
9236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w += e * (o - a);
9246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            o = (float) obj[k + 3];
9256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            e = eigObj[k + 3];
9266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            a = avg[k + 3];
9276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w += e * (o - a);
9286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
9296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( ; k < size.width; k++ )
9306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w += eigObj[k] * ((float) obj[k] - avg[k]);
9316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
9326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return w;
9346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
9356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
9376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Names: icvEigenDecomposite_8u32fR
9386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates all decomposition coefficients for input object
9396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             using previously calculated eigen objects basis and the mean (averaged)
9406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object
9416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
9426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obj         - input object
9436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 objStep     - its step (in bytes)
9446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 nEigObjs    - number of eigen objects
9456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigInput    - pointer either to array of pointers to eigen objects
9466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               or to read callback function (depending on ioFlags)
9476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigStep     - eigen objects step (in bytes)
9486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 ioFlags     - input/output flags
9496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 iserData    - pointer to the structure which contains all necessary
9506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               data for the callback function
9516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg         - pointer to averaged object
9526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avgStep     - its step (in bytes)
9536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 size        - ROI size of each source object
9546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 coeffs      - calculated coefficients (output data)
9556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
9566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: icv status
9576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
9586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:   see notes for icvCalcEigenObjects_8u32fR function
9596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
9606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
9616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvEigenDecomposite_8u32fR( uchar * obj, int objStep, int nEigObjs,
9626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            void *eigInput, int eigStep, int ioFlags,
9636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            void *userData, float *avg, int avgStep,
9646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                            CvSize size, float *coeffs )
9656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
9666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
9676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( nEigObjs < 2 )
9696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
9706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags < 0 || ioFlags > 1 )
9716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
9726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width > objStep || 4 * size.width > eigStep ||
9736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        4 * size.width > avgStep || size.height < 1 )
9746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
9756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj == NULL || eigInput == NULL || coeffs == NULL || avg == NULL )
9766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
9776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !ioFlags )
9786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
9796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ((uchar **) eigInput)[i] == NULL )
9806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NULLPTR_ERR;
9816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags )               /* callback */
9836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
9856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float *buffer;
9866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvCallback read_callback = ((CvInput *) & eigInput)->callback;
9876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigStep = 4 * size.width;
9896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* memory allocation */
9916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = (float *) cvAlloc( sizeof( float ) * size.width * size.height );
9926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer == NULL )
9946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
9956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
9966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
9976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
9986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float w;
9996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus r = (CvStatus)read_callback( i, (void *) buffer, userData );
10006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( r )
10026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buffer );
10046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return r;
10056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w = icvCalcDecompCoeff_8u32fR( obj, objStep, buffer,
10076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            eigStep, avg, avgStep, size );
10086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( w < -1.0e29f )
10096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
10106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buffer );
10116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NOTDEFINED_ERR;
10126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
10136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            coeffs[i] = w;
10146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
10166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
10196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        /* no callback */
10206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
10216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
10226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float w = icvCalcDecompCoeff_8u32fR( obj, objStep, ((float **) eigInput)[i],
10236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                  eigStep, avg, avgStep, size );
10246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( w < -1.0e29f )
10266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NOTDEFINED_ERR;
10276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            coeffs[i] = w;
10286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
10296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
10316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
10326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
10356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Names: icvEigenProjection_8u32fR
10366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates object projection to the eigen sub-space (restores
10376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             an object) using previously calculated eigen objects basis, mean (averaged)
10386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object and decomposition coefficients of the restored object
10396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
10406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  nEigObjs - Number of eigen objects
10416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigens   - Array of pointers to eigen objects
10426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigStep  - Eigen objects step (in bytes)
10436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 coeffs   - Previously calculated decomposition coefficients
10446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg      - Pointer to averaged object
10456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avgStep  - Its step (in bytes)
10466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 rest     - Pointer to restored object
10476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 restStep - Its step (in bytes)
10486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 size     - ROI size of each object
10496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
10506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: CV status
10516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
10526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
10536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
10546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Rennstatic CvStatus CV_STDCALL
10556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennicvEigenProjection_8u32fR( int nEigObjs, void *eigInput, int eigStep,
10566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           int ioFlags, void *userData, float *coeffs,
10576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           float *avg, int avgStep, uchar * rest,
10586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                           int restStep, CvSize size )
10596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
10606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i, j, k;
10616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *buf;
10626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *buffer = NULL;
10636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *b;
10646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvCallback read_callback = ((CvInput *) & eigInput)->callback;
10656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width > avgStep || 4 * size.width > eigStep || size.height < 1 )
10676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADSIZE_ERR;
10686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( rest == NULL || eigInput == NULL || avg == NULL || coeffs == NULL )
10696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_NULLPTR_ERR;
10706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags < 0 || ioFlags > 1 )
10716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_BADFACTOR_ERR;
10726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( !ioFlags )
10736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
10746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( ((uchar **) eigInput)[i] == NULL )
10756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return CV_NULLPTR_ERR;
10766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    eigStep /= 4;
10776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    avgStep /= 4;
10786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( size.width == restStep && size.width == eigStep && size.width == avgStep )
10806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.width *= size.height;
10826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        size.height = 1;
10836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        restStep = eigStep = avgStep = size.width;
10846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
10856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    buf = (float *) cvAlloc( sizeof( float ) * size.width * size.height );
10876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( buf == NULL )
10896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        return CV_OUTOFMEM_ERR;
10906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    b = buf;
10916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++, avg += avgStep, b += size.width )
10926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j++ )
10936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            b[j] = avg[j];
10946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags )
10966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
10976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        buffer = (float *) cvAlloc( sizeof( float ) * size.width * size.height );
10986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
10996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( buffer == NULL )
11006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &buf );
11026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            return CV_OUTOFMEM_ERR;
11036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        eigStep = size.width;
11056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( k = 0; k < nEigObjs; k++ )
11086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
11096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float *e = ioFlags ? buffer : ((float **) eigInput)[k];
11106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float c = coeffs[k];
11116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( ioFlags )           /* read eigen object */
11136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvStatus r = (CvStatus)read_callback( k, (void *) buffer, userData );
11156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( r )
11176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buf );
11196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvFree( &buffer );
11206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                return r;
11216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        b = buf;
11256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < size.height; i++, e += eigStep, b += size.width )
11266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( j = 0; j < size.width - 3; j += 4 )
11286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
11296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float b0 = c * e[j];
11306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float b1 = c * e[j + 1];
11316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float b2 = c * e[j + 2];
11326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float b3 = c * e[j + 3];
11336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b[j] += b0;
11356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b[j + 1] += b1;
11366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b[j + 2] += b2;
11376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b[j + 3] += b3;
11386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
11396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( ; j < size.width; j++ )
11406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                b[j] += c * e[j];
11416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
11436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    b = buf;
11456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    for( i = 0; i < size.height; i++, avg += avgStep, b += size.width, rest += restStep )
11466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( j = 0; j < size.width; j++ )
11476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
11486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int w = cvRound( b[j] );
11496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            w = !(w & ~255) ? w : w < 0 ? 0 : 255;
11516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            rest[j] = (uchar) w;
11526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
11536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvFree( &buf );
11556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags )
11566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &buffer );
11576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return CV_NO_ERR;
11586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
11596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
11616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: cvCalcCovarMatrixEx
11626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates a covariance matrix for a group of input objects
11636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             (images, vectors, etc.).
11646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
11656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  nObjects    - number of source objects
11666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 input       - pointer either to array of input objects
11676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               or to read callback function (depending on ioFlags)
11686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 ioFlags     - input/output flags (see Notes to
11696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               cvCalcEigenObjects function)
11706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 ioBufSize   - input/output buffer size
11716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 userData    - pointer to the structure which contains all necessary
11726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               data for the callback functions
11736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg         - averaged object
11746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 covarMatrix - covariance matrix (output parameter; must be allocated
11756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               before call)
11766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
11776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:  See Notes to cvCalcEigenObjects function
11786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
11796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
11816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCalcCovarMatrixEx( int  nObjects, void*  input, int  ioFlags,
11826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     int  ioBufSize, uchar*  buffer, void*  userData,
11836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                     IplImage* avg, float*  covarMatrix )
11846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
11856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *avg_data;
11866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int avg_step = 0;
11876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize avg_size;
11886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
11896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCalcCovarMatrixEx" );
11916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
11936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
11946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( avg, (uchar **) & avg_data, &avg_step, &avg_size );
11956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->depth != IPL_DEPTH_32F )
11966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
11976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->nChannels != 1 )
11986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
11996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags == CV_EIGOBJ_NO_CALLBACK )
12016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IplImage **images = (IplImage **) (((CvInput *) & input)->data);
12036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        uchar **objects = (uchar **) cvAlloc( sizeof( uchar * ) * nObjects );
12046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int img_step = 0, old_step = 0;
12056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSize img_size = avg_size, old_size = avg_size;
12066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( objects == NULL )
12086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Insufficient memory" );
12096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nObjects; i++ )
12116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
12126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage *img = images[i];
12136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar *img_data;
12146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGetImageRawData( img, &img_data, &img_step, &img_size );
12166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( img->depth != IPL_DEPTH_8U )
12176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
12186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( img_size != avg_size || img_size != old_size )
12196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
12206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( img->nChannels != 1 )
12216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
12226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i > 0 && img_step != old_step )
12236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different steps of objects" );
12246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_step = img_step;
12266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_size = img_size;
12276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            objects[i] = img_data;
12286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
12296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvCalcCovarMatrixEx_8u32fR( nObjects,
12316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              (void*) objects,
12326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              img_step,
12336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              CV_EIGOBJ_NO_CALLBACK,
12346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              0,
12356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              NULL,
12366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              NULL,
12376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_data,
12386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_step,
12396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_size,
12406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              covarMatrix ));
12416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &objects );
12426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
12456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
12476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvCalcCovarMatrixEx_8u32fR( nObjects,
12486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              input,
12496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_step / 4,
12506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              ioFlags,
12516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              ioBufSize,
12526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              buffer,
12536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              userData,
12546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_data,
12556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_step,
12566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              avg_size,
12576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                              covarMatrix ));
12586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
12596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
12616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
12626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
12636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
12646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: cvCalcEigenObjects
12656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates an orthonormal eigen basis and a mean (averaged)
12666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object for a group of input objects (images, vectors, etc.).
12676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
12686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters: nObjects  - number of source objects
12696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                input     - pointer either to array of input objects
12706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            or to read callback function (depending on ioFlags)
12716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                output    - pointer either to output eigen objects
12726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            or to write callback function (depending on ioFlags)
12736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                ioFlags   - input/output flags (see Notes)
12746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                ioBufSize - input/output buffer size
12756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                userData  - pointer to the structure which contains all necessary
12766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            data for the callback functions
12776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                calcLimit - determines the calculation finish conditions
12786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                avg       - averaged object (has the same size as ROI)
12796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                eigVals   - pointer to corresponding eigen values (array of <nObjects>
12806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            elements in descending order)
12816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
12826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes: 1. input/output data (that is, input objects and eigen ones) may either
12836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              be allocated in the RAM or be read from/written to the HDD (or any
12846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              other device) by read/write callback functions. It depends on the
12856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              value of ioFlags paramater, which may be the following:
12866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_NO_CALLBACK, or 0;
12876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_INPUT_CALLBACK;
12886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_OUTPUT_CALLBACK;
12896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                  CV_EIGOBJ_BOTH_CALLBACK, or
12906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                            CV_EIGOBJ_INPUT_CALLBACK | CV_EIGOBJ_OUTPUT_CALLBACK.
12916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              The callback functions as well as the user data structure must be
12926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              developed by the user.
12936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
12946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           2. If ioBufSize = 0, or it's too large, the function dermines buffer size
12956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              itself.
12966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
12976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           3. Depending on calcLimit parameter, calculations are finished either if
12986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              eigenfaces number comes up to certain value or the relation of the
12996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              current eigenvalue and the largest one comes down to certain value
13006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              (or any of the above conditions takes place). The calcLimit->type value
13016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              must be CV_TERMCRIT_NUMB, CV_TERMCRIT_EPS or
13026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              CV_TERMCRIT_NUMB | CV_TERMCRIT_EPS. The function returns the real
13036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//              values calcLimit->max_iter and calcLimit->epsilon.
13046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
13056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//           4. eigVals may be equal to NULL (if you don't need eigen values in further).
13066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
13076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
13086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
13096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCalcEigenObjects( int       nObjects,
13106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    void*     input,
13116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    void*     output,
13126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int       ioFlags,
13136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int       ioBufSize,
13146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    void*     userData,
13156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CvTermCriteria* calcLimit,
13166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IplImage* avg,
13176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float*    eigVals )
13186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
13196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *avg_data;
13206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int avg_step = 0;
13216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize avg_size;
13226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
13236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int nEigens = nObjects - 1;
13246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCalcEigenObjects" );
13266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
13286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( avg, (uchar **) & avg_data, &avg_step, &avg_size );
13306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->depth != IPL_DEPTH_32F )
13316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
13326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->nChannels != 1 )
13336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
13346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( nEigens > calcLimit->max_iter && calcLimit->type != CV_TERMCRIT_EPS )
13366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        nEigens = calcLimit->max_iter;
13376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    switch (ioFlags)
13396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
13406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_EIGOBJ_NO_CALLBACK:
13416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
13426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage **objects = (IplImage **) (((CvInput *) & input)->data);
13436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage **eigens = (IplImage **) (((CvInput *) & output)->data);
13446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar **objs = (uchar **) cvAlloc( sizeof( uchar * ) * nObjects );
13456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float **eigs = (float **) cvAlloc( sizeof( float * ) * nEigens );
13466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int obj_step = 0, old_step = 0;
13476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int eig_step = 0, oldeig_step = 0;
13486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize obj_size = avg_size, old_size = avg_size,
13496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                eig_size = avg_size, oldeig_size = avg_size;
13516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( objects == NULL || eigens == NULL )
13536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Insufficient memory" );
13546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < nObjects; i++ )
13566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IplImage *img = objects[i];
13586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *obj_data;
13596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetImageRawData( img, &obj_data, &obj_step, &obj_size );
13616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( img->depth != IPL_DEPTH_8U )
13626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
13636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( obj_size != avg_size || obj_size != old_size )
13646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
13656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( img->nChannels != 1 )
13666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
13676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i > 0 && obj_step != old_step )
13686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different steps of objects" );
13696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                old_step = obj_step;
13716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                old_size = obj_size;
13726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                objs[i] = obj_data;
13736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < nEigens; i++ )
13756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
13766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IplImage *eig = eigens[i];
13776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *eig_data;
13786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetImageRawData( eig, (uchar **) & eig_data, &eig_step, &eig_size );
13806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig->depth != IPL_DEPTH_32F )
13816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
13826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig_size != avg_size || eig_size != oldeig_size )
13836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
13846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig->nChannels != 1 )
13856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
13866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i > 0 && eig_step != oldeig_step )
13876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different steps of objects" );
13886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
13896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                oldeig_step = eig_step;
13906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                oldeig_size = eig_size;
13916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                eigs[i] = eig_data;
13926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
13936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( icvCalcEigenObjects_8u32fR( nObjects, (void*) objs, obj_step,
13946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 (void*) eigs, eig_step, obj_size,
13956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 ioFlags, ioBufSize, userData,
13966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 calcLimit, avg_data, avg_step, eigVals ));
13976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &objs );
13986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &eigs );
13996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
14006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_EIGOBJ_OUTPUT_CALLBACK:
14036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage **objects = (IplImage **) (((CvInput *) & input)->data);
14056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            uchar **objs = (uchar **) cvAlloc( sizeof( uchar * ) * nObjects );
14066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int obj_step = 0, old_step = 0;
14076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize obj_size = avg_size, old_size = avg_size;
14086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( objects == NULL )
14106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Insufficient memory" );
14116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < nObjects; i++ )
14136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IplImage *img = objects[i];
14156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                uchar *obj_data;
14166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetImageRawData( img, &obj_data, &obj_step, &obj_size );
14186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( img->depth != IPL_DEPTH_8U )
14196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
14206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( obj_size != avg_size || obj_size != old_size )
14216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
14226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( img->nChannels != 1 )
14236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
14246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i > 0 && obj_step != old_step )
14256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different steps of objects" );
14266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                old_step = obj_step;
14286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                old_size = obj_size;
14296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                objs[i] = obj_data;
14306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( icvCalcEigenObjects_8u32fR( nObjects,
14326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 (void*) objs,
14336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 obj_step,
14346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 output,
14356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_step,
14366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 obj_size,
14376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 ioFlags,
14386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 ioBufSize,
14396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 userData,
14406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 calcLimit,
14416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_data,
14426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_step,
14436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 eigVals   ));
14446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &objs );
14456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
14466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_EIGOBJ_INPUT_CALLBACK:
14496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
14506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage **eigens = (IplImage **) (((CvInput *) & output)->data);
14516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float **eigs = (float**) cvAlloc( sizeof( float* ) * nEigens );
14526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            int eig_step = 0, oldeig_step = 0;
14536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CvSize eig_size = avg_size, oldeig_size = avg_size;
14546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eigens == NULL )
14566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Insufficient memory" );
14576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            for( i = 0; i < nEigens; i++ )
14596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            {
14606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                IplImage *eig = eigens[i];
14616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                float *eig_data;
14626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                cvGetImageRawData( eig, (uchar **) & eig_data, &eig_step, &eig_size );
14646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig->depth != IPL_DEPTH_32F )
14656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
14666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig_size != avg_size || eig_size != oldeig_size )
14676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
14686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( eig->nChannels != 1 )
14696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
14706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                if( i > 0 && eig_step != oldeig_step )
14716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    CV_ERROR( CV_StsBadArg, "Different steps of objects" );
14726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                oldeig_step = eig_step;
14746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                oldeig_size = eig_size;
14756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                eigs[i] = eig_data;
14766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            }
14776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_CALL( icvCalcEigenObjects_8u32fR( nObjects,
14786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 input,
14796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_step / 4,
14806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 (void*) eigs,
14816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 eig_step,
14826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 eig_size,
14836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 ioFlags,
14846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 ioBufSize,
14856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 userData,
14866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 calcLimit,
14876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_data,
14886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 avg_step,
14896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                                 eigVals   ));
14906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvFree( &eigs );
14916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            break;
14926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
14936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    case CV_EIGOBJ_INPUT_CALLBACK | CV_EIGOBJ_OUTPUT_CALLBACK:
14946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
14956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvCalcEigenObjects_8u32fR( nObjects,
14966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             input,
14976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step / 4,
14986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             output,
14996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step,
15006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_size,
15016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             ioFlags,
15026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             ioBufSize,
15036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             userData,
15046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             calcLimit,
15056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_data,
15066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step,
15076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             eigVals   ));
15086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        break;
15096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    default:
15116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Unsupported i/o flag" );
15126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
15136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
15156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*--------------------------------------------------------------------------------------*/
15186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
15196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: cvCalcDecompCoeff
15206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates one decomposition coefficient of input object
15216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             using previously calculated eigen object and the mean (averaged) object
15226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
15236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obj     - input object
15246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigObj  - eigen object
15256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg     - averaged object
15266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
15276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Returns: decomposition coefficient value or large negative value (if error)
15286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
15296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:
15306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
15316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL double
15336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvCalcDecompCoeff( IplImage * obj, IplImage * eigObj, IplImage * avg )
15346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
15356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    double coeff = DBL_MAX;
15366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *obj_data;
15386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *eig_data;
15396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *avg_data;
15406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int obj_step = 0, eig_step = 0, avg_step = 0;
15416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize obj_size, eig_size, avg_size;
15426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvCalcDecompCoeff" );
15446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
15466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( obj, &obj_data, &obj_step, &obj_size );
15486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj->depth != IPL_DEPTH_8U )
15496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
15506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj->nChannels != 1 )
15516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
15526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( eigObj, (uchar **) & eig_data, &eig_step, &eig_size );
15546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( eigObj->depth != IPL_DEPTH_32F )
15556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
15566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( eigObj->nChannels != 1 )
15576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
15586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( avg, (uchar **) & avg_data, &avg_step, &avg_size );
15606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->depth != IPL_DEPTH_32F )
15616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
15626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->nChannels != 1 )
15636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
15646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj_size != eig_size || obj_size != avg_size )
15666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "different sizes of images" );
15676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    coeff = icvCalcDecompCoeff_8u32fR( obj_data, obj_step,
15696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       eig_data, eig_step,
15706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                       avg_data, avg_step, obj_size );
15716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
15736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    return coeff;
15756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
15766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*--------------------------------------------------------------------------------------*/
15786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
15796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Names: cvEigenDecomposite
15806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates all decomposition coefficients for input object
15816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             using previously calculated eigen objects basis and the mean (averaged)
15826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object
15836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
15846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  obj         - input object
15856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 nEigObjs    - number of eigen objects
15866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigInput    - pointer either to array of pointers to eigen objects
15876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               or to read callback function (depending on ioFlags)
15886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 ioFlags     - input/output flags
15896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 userData    - pointer to the structure which contains all necessary
15906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               data for the callback function
15916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg         - averaged object
15926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 coeffs      - calculated coefficients (output data)
15936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
15946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:   see notes for cvCalcEigenObjects function
15956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
15966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
15976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
15986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEigenDecomposite( IplImage* obj,
15996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int       nEigObjs,
16006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    void*     eigInput,
16016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    int       ioFlags,
16026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    void*     userData,
16036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    IplImage* avg,
16046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                    float*    coeffs )
16056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
16066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *avg_data;
16076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *obj_data;
16086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int avg_step = 0, obj_step = 0;
16096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize avg_size, obj_size;
16106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
16116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvEigenDecomposite" );
16136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
16156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( avg, (uchar **) & avg_data, &avg_step, &avg_size );
16176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->depth != IPL_DEPTH_32F )
16186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
16196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->nChannels != 1 )
16206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
16216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( obj, &obj_data, &obj_step, &obj_size );
16236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj->depth != IPL_DEPTH_8U )
16246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
16256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj->nChannels != 1 )
16266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
16276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( obj_size != avg_size )
16296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
16306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags == CV_EIGOBJ_NO_CALLBACK )
16326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IplImage **eigens = (IplImage **) (((CvInput *) & eigInput)->data);
16346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float **eigs = (float **) cvAlloc( sizeof( float * ) * nEigObjs );
16356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int eig_step = 0, old_step = 0;
16366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSize eig_size = avg_size, old_size = avg_size;
16376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( eigs == NULL )
16396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Insufficient memory" );
16406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
16426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
16436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage *eig = eigens[i];
16446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float *eig_data;
16456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGetImageRawData( eig, (uchar **) & eig_data, &eig_step, &eig_size );
16476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig->depth != IPL_DEPTH_32F )
16486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
16496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig_size != avg_size || eig_size != old_size )
16506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
16516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig->nChannels != 1 )
16526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
16536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i > 0 && eig_step != old_step )
16546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different steps of objects" );
16556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_step = eig_step;
16576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_size = eig_size;
16586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            eigs[i] = eig_data;
16596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
16606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvEigenDecomposite_8u32fR( obj_data,
16626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             obj_step,
16636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             nEigObjs,
16646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             (void*) eigs,
16656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             eig_step,
16666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             ioFlags,
16676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             userData,
16686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_data,
16696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step,
16706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             obj_size,
16716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             coeffs   ));
16726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &eigs );
16736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
16766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
16786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvEigenDecomposite_8u32fR( obj_data,
16796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             obj_step,
16806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             nEigObjs,
16816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             eigInput,
16826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step,
16836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             ioFlags,
16846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             userData,
16856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_data,
16866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             avg_step,
16876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             obj_size,
16886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                             coeffs   ));
16896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
16906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
16926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
16936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
16946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*--------------------------------------------------------------------------------------*/
16956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/*F///////////////////////////////////////////////////////////////////////////////////////
16966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Name: cvEigenProjection
16976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Purpose: The function calculates object projection to the eigen sub-space (restores
16986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             an object) using previously calculated eigen objects basis, mean (averaged)
16996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//             object and decomposition coefficients of the restored object
17006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Context:
17016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Parameters:  nEigObjs    - number of eigen objects
17026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 eigInput    - pointer either to array of pointers to eigen objects
17036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               or to read callback function (depending on ioFlags)
17046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 ioFlags     - input/output flags
17056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 userData    - pointer to the structure which contains all necessary
17066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                               data for the callback function
17076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 coeffs      - array of decomposition coefficients
17086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 avg         - averaged object
17096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//                 proj        - object projection (output data)
17106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//
17116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//    Notes:   see notes for cvCalcEigenObjects function
17126acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn//F*/
17136acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17146acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RennCV_IMPL void
17156acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius RenncvEigenProjection( void*     eigInput,
17166acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int       nEigObjs,
17176acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   int       ioFlags,
17186acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   void*     userData,
17196acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   float*    coeffs,
17206acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   IplImage* avg,
17216acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                   IplImage* proj )
17226acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn{
17236acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    float *avg_data;
17246acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    uchar *proj_data;
17256acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int avg_step = 0, proj_step = 0;
17266acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CvSize avg_size, proj_size;
17276acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    int i;
17286acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17296acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    CV_FUNCNAME( "cvEigenProjection" );
17306acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17316acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __BEGIN__;
17326acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17336acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( avg, (uchar **) & avg_data, &avg_step, &avg_size );
17346acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->depth != IPL_DEPTH_32F )
17356acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
17366acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( avg->nChannels != 1 )
17376acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
17386acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17396acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    cvGetImageRawData( proj, &proj_data, &proj_step, &proj_size );
17406acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( proj->depth != IPL_DEPTH_8U )
17416acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
17426acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( proj->nChannels != 1 )
17436acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
17446acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17456acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( proj_size != avg_size )
17466acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_ERROR( CV_StsBadArg, "Different sizes of projects" );
17476acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17486acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    if( ioFlags == CV_EIGOBJ_NO_CALLBACK )
17496acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17506acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        IplImage **eigens = (IplImage**) (((CvInput *) & eigInput)->data);
17516acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        float **eigs = (float**) cvAlloc( sizeof( float * ) * nEigObjs );
17526acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        int eig_step = 0, old_step = 0;
17536acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CvSize eig_size = avg_size, old_size = avg_size;
17546acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17556acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        if( eigs == NULL )
17566acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            CV_ERROR( CV_StsBadArg, "Insufficient memory" );
17576acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17586acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        for( i = 0; i < nEigObjs; i++ )
17596acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        {
17606acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            IplImage *eig = eigens[i];
17616acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            float *eig_data;
17626acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17636acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            cvGetImageRawData( eig, (uchar **) & eig_data, &eig_step, &eig_size );
17646acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig->depth != IPL_DEPTH_32F )
17656acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadDepth, cvUnsupportedFormat );
17666acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig_size != avg_size || eig_size != old_size )
17676acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different sizes of objects" );
17686acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( eig->nChannels != 1 )
17696acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_BadNumChannels, cvUnsupportedFormat );
17706acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            if( i > 0 && eig_step != old_step )
17716acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                CV_ERROR( CV_StsBadArg, "Different steps of objects" );
17726acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17736acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_step = eig_step;
17746acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            old_size = eig_size;
17756acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn            eigs[i] = eig_data;
17766acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        }
17776acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17786acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvEigenProjection_8u32fR( nEigObjs,
17796acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            (void*) eigs,
17806acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            eig_step,
17816acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            ioFlags,
17826acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            userData,
17836acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            coeffs,
17846acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_data,
17856acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_step,
17866acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            proj_data,
17876acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            proj_step,
17886acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_size   ));
17896acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        cvFree( &eigs );
17906acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
17916acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17926acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    else
17936acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
17946acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    {
17956acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn        CV_CALL( icvEigenProjection_8u32fR( nEigObjs,
17966acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            eigInput,
17976acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_step,
17986acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            ioFlags,
17996acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            userData,
18006acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            coeffs,
18016acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_data,
18026acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_step,
18036acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            proj_data,
18046acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            proj_step,
18056acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn                                            avg_size   ));
18066acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    }
18076acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18086acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn    __END__;
18096acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn}
18106acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn
18116acb9a7ea3d7564944e12cbc73a857b88c1301eeMarius Renn/* End of file. */
1812