Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 #include "_cvaux.h"
     42 #include "_cvvm.h"
     43 #include <stdlib.h>
     44 
     45 #define Sgn(x)              ( (x)<0 ? -1:1 )    /* Sgn(0) = 1 ! */
     46 /*===========================================================================*/
     47 CvStatus
     48 icvLMedS( int *points1, int *points2, int numPoints, CvMatrix3 * fundamentalMatrix )
     49 {
     50     int sample, j, amount_samples, done;
     51     int amount_solutions;
     52     int ml7[21], mr7[21];
     53 
     54     double F_try[9 * 3];
     55     double F[9];
     56     double Mj, Mj_new;
     57 
     58     int i, num;
     59 
     60     int *ml;
     61     int *mr;
     62     int *new_ml;
     63     int *new_mr;
     64     int new_num;
     65     CvStatus error;
     66 
     67     error = CV_NO_ERR;
     68 
     69     if( fundamentalMatrix == 0 )
     70         return CV_BADFACTOR_ERR;
     71 
     72     num = numPoints;
     73 
     74     if( num < 6 )
     75     {
     76         return CV_BADFACTOR_ERR;
     77     }                           /* if */
     78 
     79     ml = (int *) cvAlloc( sizeof( int ) * num * 3 );
     80     mr = (int *) cvAlloc( sizeof( int ) * num * 3 );
     81 
     82     for( i = 0; i < num; i++ )
     83     {
     84 
     85         ml[i * 3] = points1[i * 2];
     86         ml[i * 3 + 1] = points1[i * 2 + 1];
     87 
     88         ml[i * 3 + 2] = 1;
     89 
     90         mr[i * 3] = points2[i * 2];
     91         mr[i * 3 + 1] = points2[i * 2 + 1];
     92 
     93         mr[i * 3 + 2] = 1;
     94     }                           /* for */
     95 
     96     if( num > 7 )
     97     {
     98 
     99         Mj = -1;
    100         amount_samples = 1000;  /*  -------  Must be changed !  --------- */
    101 
    102         for( sample = 0; sample < amount_samples; sample++ )
    103         {
    104 
    105             icvChoose7( ml, mr, num, ml7, mr7 );
    106             icvPoint7( ml7, mr7, F_try, &amount_solutions );
    107 
    108             for( i = 0; i < amount_solutions / 9; i++ )
    109             {
    110 
    111                 Mj_new = icvMedian( ml, mr, num, F_try + i * 9 );
    112 
    113                 if( Mj_new >= 0 && (Mj == -1 || Mj_new < Mj) )
    114                 {
    115 
    116                     for( j = 0; j < 9; j++ )
    117                     {
    118 
    119                         F[j] = F_try[i * 9 + j];
    120                     }           /* for */
    121 
    122                     Mj = Mj_new;
    123                 }               /* if */
    124             }                   /* for */
    125         }                       /* for */
    126 
    127         if( Mj == -1 )
    128             return CV_BADFACTOR_ERR;
    129 
    130         done = icvBoltingPoints( ml, mr, num, F, Mj, &new_ml, &new_mr, &new_num );
    131 
    132         if( done == -1 )
    133         {
    134 
    135             cvFree( &mr );
    136             cvFree( &ml );
    137             return CV_OUTOFMEM_ERR;
    138         }                       /* if */
    139 
    140         if( done > 7 )
    141             error = icvPoints8( new_ml, new_mr, new_num, F );
    142 
    143         cvFree( &new_mr );
    144         cvFree( &new_ml );
    145 
    146     }
    147     else
    148     {
    149         error = icvPoint7( ml, mr, F, &i );
    150     }                           /* if */
    151 
    152     if( error == CV_NO_ERR )
    153         error = icvRank2Constraint( F );
    154 
    155     for( i = 0; i < 3; i++ )
    156         for( j = 0; j < 3; j++ )
    157             fundamentalMatrix->m[i][j] = (float) F[i * 3 + j];
    158 
    159     return error;
    160 
    161 }                               /* icvLMedS */
    162 
    163 /*===========================================================================*/
    164 /*===========================================================================*/
    165 void
    166 icvChoose7( int *ml, int *mr, int num, int *ml7, int *mr7 )
    167 {
    168     int indexes[7], i, j;
    169 
    170     if( !ml || !mr || num < 7 || !ml7 || !mr7 )
    171         return;
    172 
    173     for( i = 0; i < 7; i++ )
    174     {
    175 
    176         indexes[i] = (int) ((double) rand() / RAND_MAX * num);
    177 
    178         for( j = 0; j < i; j++ )
    179         {
    180 
    181             if( indexes[i] == indexes[j] )
    182                 i--;
    183         }                       /* for */
    184     }                           /* for */
    185 
    186     for( i = 0; i < 21; i++ )
    187     {
    188 
    189         ml7[i] = ml[3 * indexes[i / 3] + i % 3];
    190         mr7[i] = mr[3 * indexes[i / 3] + i % 3];
    191     }                           /* for */
    192 }                               /* cs_Choose7 */
    193 
    194 /*===========================================================================*/
    195 /*===========================================================================*/
    196 CvStatus
    197 icvCubic( double a2, double a1, double a0, double *squares )
    198 {
    199     double p, q, D, c1, c2, b1, b2, ro1, ro2, fi1, fi2, tt;
    200     double x[6][3];
    201     int i, j, t;
    202 
    203     if( !squares )
    204         return CV_BADFACTOR_ERR;
    205 
    206     p = a1 - a2 * a2 / 3;
    207     q = (9 * a1 * a2 - 27 * a0 - 2 * a2 * a2 * a2) / 27;
    208     D = q * q / 4 + p * p * p / 27;
    209 
    210     if( D < 0 )
    211     {
    212 
    213         c1 = q / 2;
    214         c2 = c1;
    215         b1 = sqrt( -D );
    216         b2 = -b1;
    217 
    218         ro1 = sqrt( c1 * c1 - D );
    219         ro2 = ro1;
    220 
    221         fi1 = atan2( b1, c1 );
    222         fi2 = -fi1;
    223     }
    224     else
    225     {
    226 
    227         c1 = q / 2 + sqrt( D );
    228         c2 = q / 2 - sqrt( D );
    229         b1 = 0;
    230         b2 = 0;
    231 
    232         ro1 = fabs( c1 );
    233         ro2 = fabs( c2 );
    234         fi1 = CV_PI * (1 - SIGN( c1 )) / 2;
    235         fi2 = CV_PI * (1 - SIGN( c2 )) / 2;
    236     }                           /* if */
    237 
    238     for( i = 0; i < 6; i++ )
    239     {
    240 
    241         x[i][0] = -a2 / 3;
    242         x[i][1] = 0;
    243         x[i][2] = 0;
    244 
    245         squares[i] = x[i][i % 2];
    246     }                           /* for */
    247 
    248     if( !REAL_ZERO( ro1 ))
    249     {
    250         tt = SIGN( ro1 ) * pow( fabs( ro1 ), 0.333333333333 );
    251         c1 = tt - p / (3. * tt);
    252         c2 = tt + p / (3. * tt);
    253     }                           /* if */
    254 
    255     if( !REAL_ZERO( ro2 ))
    256     {
    257         tt = SIGN( ro2 ) * pow( fabs( ro2 ), 0.333333333333 );
    258         b1 = tt - p / (3. * tt);
    259         b2 = tt + p / (3. * tt);
    260     }                           /* if */
    261 
    262     for( i = 0; i < 6; i++ )
    263     {
    264 
    265         if( i < 3 )
    266         {
    267 
    268             if( !REAL_ZERO( ro1 ))
    269             {
    270 
    271                 x[i][0] = cos( fi1 / 3. + 2 * CV_PI * (i % 3) / 3. ) * c1 - a2 / 3;
    272                 x[i][1] = sin( fi1 / 3. + 2 * CV_PI * (i % 3) / 3. ) * c2;
    273             }
    274             else
    275             {
    276 
    277                 x[i][2] = 1;
    278             }                   /* if */
    279         }
    280         else
    281         {
    282 
    283             if( !REAL_ZERO( ro2 ))
    284             {
    285 
    286                 x[i][0] = cos( fi2 / 3. + 2 * CV_PI * (i % 3) / 3. ) * b1 - a2 / 3;
    287                 x[i][1] = sin( fi2 / 3. + 2 * CV_PI * (i % 3) / 3. ) * b2;
    288             }
    289             else
    290             {
    291 
    292                 x[i][2] = 1;
    293             }                   /* if */
    294         }                       /* if */
    295     }                           /* for */
    296 
    297     t = 0;
    298 
    299     for( i = 0; i < 6; i++ )
    300     {
    301 
    302         if( !x[i][2] )
    303         {
    304 
    305             squares[t++] = x[i][0];
    306             squares[t++] = x[i][1];
    307             x[i][2] = 1;
    308 
    309             for( j = i + 1; j < 6; j++ )
    310             {
    311 
    312                 if( !x[j][2] && REAL_ZERO( x[i][0] - x[j][0] )
    313                     && REAL_ZERO( x[i][1] - x[j][1] ))
    314                 {
    315 
    316                     x[j][2] = 1;
    317                     break;
    318                 }               /* if */
    319             }                   /* for */
    320         }                       /* if */
    321     }                           /* for */
    322     return CV_NO_ERR;
    323 }                               /* icvCubic */
    324 
    325 /*======================================================================================*/
    326 double
    327 icvDet( double *M )
    328 {
    329     double value;
    330 
    331     if( !M )
    332         return 0;
    333 
    334     value = M[0] * M[4] * M[8] + M[2] * M[3] * M[7] + M[1] * M[5] * M[6] -
    335         M[2] * M[4] * M[6] - M[0] * M[5] * M[7] - M[1] * M[3] * M[8];
    336 
    337     return value;
    338 
    339 }                               /* icvDet */
    340 
    341 /*===============================================================================*/
    342 double
    343 icvMinor( double *M, int x, int y )
    344 {
    345     int row1, row2, col1, col2;
    346     double value;
    347 
    348     if( !M || x < 0 || x > 2 || y < 0 || y > 2 )
    349         return 0;
    350 
    351     row1 = (y == 0 ? 1 : 0);
    352     row2 = (y == 2 ? 1 : 2);
    353     col1 = (x == 0 ? 1 : 0);
    354     col2 = (x == 2 ? 1 : 2);
    355 
    356     value = M[row1 * 3 + col1] * M[row2 * 3 + col2] - M[row2 * 3 + col1] * M[row1 * 3 + col2];
    357 
    358     value *= 1 - (x + y) % 2 * 2;
    359 
    360     return value;
    361 
    362 }                               /* icvMinor */
    363 
    364 /*======================================================================================*/
    365 CvStatus
    366 icvGetCoef( double *f1, double *f2, double *a2, double *a1, double *a0 )
    367 {
    368     double G[9], a3;
    369     int i;
    370 
    371     if( !f1 || !f2 || !a0 || !a1 || !a2 )
    372         return CV_BADFACTOR_ERR;
    373 
    374     for( i = 0; i < 9; i++ )
    375     {
    376 
    377         G[i] = f1[i] - f2[i];
    378     }                           /* for */
    379 
    380     a3 = icvDet( G );
    381 
    382     if( REAL_ZERO( a3 ))
    383         return CV_BADFACTOR_ERR;
    384 
    385     *a2 = 0;
    386     *a1 = 0;
    387     *a0 = icvDet( f2 );
    388 
    389     for( i = 0; i < 9; i++ )
    390     {
    391 
    392         *a2 += f2[i] * icvMinor( G, (int) (i % 3), (int) (i / 3) );
    393         *a1 += G[i] * icvMinor( f2, (int) (i % 3), (int) (i / 3) );
    394     }                           /* for */
    395 
    396     *a0 /= a3;
    397     *a1 /= a3;
    398     *a2 /= a3;
    399 
    400     return CV_NO_ERR;
    401 
    402 }                               /* icvGetCoef */
    403 
    404 /*===========================================================================*/
    405 double
    406 icvMedian( int *ml, int *mr, int num, double *F )
    407 {
    408     double l1, l2, l3, d1, d2, value;
    409     double *deviation;
    410     int i, i3;
    411 
    412     if( !ml || !mr || !F )
    413         return -1;
    414 
    415     deviation = (double *) cvAlloc( (num) * sizeof( double ));
    416 
    417     if( !deviation )
    418         return -1;
    419 
    420     for( i = 0, i3 = 0; i < num; i++, i3 += 3 )
    421     {
    422 
    423         l1 = F[0] * mr[i3] + F[1] * mr[i3 + 1] + F[2];
    424         l2 = F[3] * mr[i3] + F[4] * mr[i3 + 1] + F[5];
    425         l3 = F[6] * mr[i3] + F[7] * mr[i3 + 1] + F[8];
    426 
    427         d1 = (l1 * ml[i3] + l2 * ml[i3 + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
    428 
    429         l1 = F[0] * ml[i3] + F[3] * ml[i3 + 1] + F[6];
    430         l2 = F[1] * ml[i3] + F[4] * ml[i3 + 1] + F[7];
    431         l3 = F[2] * ml[i3] + F[5] * ml[i3 + 1] + F[8];
    432 
    433         d2 = (l1 * mr[i3] + l2 * mr[i3 + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
    434 
    435         deviation[i] = (double) (d1 * d1 + d2 * d2);
    436     }                           /* for */
    437 
    438     if( icvSort( deviation, num ) != CV_NO_ERR )
    439     {
    440 
    441         cvFree( &deviation );
    442         return -1;
    443     }                           /* if */
    444 
    445     value = deviation[num / 2];
    446     cvFree( &deviation );
    447     return value;
    448 
    449 }                               /* cs_Median */
    450 
    451 /*===========================================================================*/
    452 CvStatus
    453 icvSort( double *array, int length )
    454 {
    455     int i, j, index;
    456     double swapd;
    457 
    458     if( !array || length < 1 )
    459         return CV_BADFACTOR_ERR;
    460 
    461     for( i = 0; i < length - 1; i++ )
    462     {
    463 
    464         index = i;
    465 
    466         for( j = i + 1; j < length; j++ )
    467         {
    468 
    469             if( array[j] < array[index] )
    470                 index = j;
    471         }                       /* for */
    472 
    473         if( index - i )
    474         {
    475 
    476             swapd = array[i];
    477             array[i] = array[index];
    478             array[index] = swapd;
    479         }                       /* if */
    480     }                           /* for */
    481 
    482     return CV_NO_ERR;
    483 
    484 }                               /* cs_Sort */
    485 
    486 /*===========================================================================*/
    487 int
    488 icvBoltingPoints( int *ml, int *mr,
    489                   int num, double *F, double Mj, int **new_ml, int **new_mr, int *new_num )
    490 {
    491     double l1, l2, l3, d1, d2, sigma;
    492     int i, j, length;
    493     int *index;
    494 
    495     if( !ml || !mr || num < 1 || !F || Mj < 0 )
    496         return -1;
    497 
    498     index = (int *) cvAlloc( (num) * sizeof( int ));
    499 
    500     if( !index )
    501         return -1;
    502 
    503     length = 0;
    504     sigma = (double) (2.5 * 1.4826 * (1 + 5. / (num - 7)) * sqrt( Mj ));
    505 
    506     for( i = 0; i < num * 3; i += 3 )
    507     {
    508 
    509         l1 = F[0] * mr[i] + F[1] * mr[i + 1] + F[2];
    510         l2 = F[3] * mr[i] + F[4] * mr[i + 1] + F[5];
    511         l3 = F[6] * mr[i] + F[7] * mr[i + 1] + F[8];
    512 
    513         d1 = (l1 * ml[i] + l2 * ml[i + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
    514 
    515         l1 = F[0] * ml[i] + F[3] * ml[i + 1] + F[6];
    516         l2 = F[1] * ml[i] + F[4] * ml[i + 1] + F[7];
    517         l3 = F[2] * ml[i] + F[5] * ml[i + 1] + F[8];
    518 
    519         d2 = (l1 * mr[i] + l2 * mr[i + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
    520 
    521         if( d1 * d1 + d2 * d2 <= sigma * sigma )
    522         {
    523 
    524             index[i / 3] = 1;
    525             length++;
    526         }
    527         else
    528         {
    529 
    530             index[i / 3] = 0;
    531         }                       /* if */
    532     }                           /* for */
    533 
    534     *new_num = length;
    535 
    536     *new_ml = (int *) cvAlloc( (length * 3) * sizeof( int ));
    537 
    538     if( !new_ml )
    539     {
    540 
    541         cvFree( &index );
    542         return -1;
    543     }                           /* if */
    544 
    545     *new_mr = (int *) cvAlloc( (length * 3) * sizeof( int ));
    546 
    547     if( !new_mr )
    548     {
    549 
    550         cvFree( &new_ml );
    551         cvFree( &index );
    552         return -1;
    553     }                           /* if */
    554 
    555     j = 0;
    556 
    557     for( i = 0; i < num * 3; )
    558     {
    559 
    560         if( index[i / 3] )
    561         {
    562 
    563             (*new_ml)[j] = ml[i];
    564             (*new_mr)[j++] = mr[i++];
    565             (*new_ml)[j] = ml[i];
    566             (*new_mr)[j++] = mr[i++];
    567             (*new_ml)[j] = ml[i];
    568             (*new_mr)[j++] = mr[i++];
    569         }
    570         else
    571             i += 3;
    572     }                           /* for */
    573 
    574     cvFree( &index );
    575     return length;
    576 
    577 }                               /* cs_BoltingPoints */
    578 
    579 /*===========================================================================*/
    580 CvStatus
    581 icvPoints8( int *ml, int *mr, int num, double *F )
    582 {
    583     double *U;
    584     double l1, l2, w, old_norm = -1, new_norm = -2, summ;
    585     int i3, i9, j, num3, its = 0, a, t;
    586 
    587     if( !ml || !mr || num < 8 || !F )
    588         return CV_BADFACTOR_ERR;
    589 
    590     U = (double *) cvAlloc( (num * 9) * sizeof( double ));
    591 
    592     if( !U )
    593         return CV_OUTOFMEM_ERR;
    594 
    595     num3 = num * 3;
    596 
    597     while( !REAL_ZERO( new_norm - old_norm ))
    598     {
    599 
    600         if( its++ > 1e+2 )
    601         {
    602 
    603             cvFree( &U );
    604             return CV_BADFACTOR_ERR;
    605         }                       /* if */
    606 
    607         old_norm = new_norm;
    608 
    609         for( i3 = 0, i9 = 0; i3 < num3; i3 += 3, i9 += 9 )
    610         {
    611 
    612             l1 = F[0] * mr[i3] + F[1] * mr[i3 + 1] + F[2];
    613             l2 = F[3] * mr[i3] + F[4] * mr[i3 + 1] + F[5];
    614 
    615             if( REAL_ZERO( l1 ) && REAL_ZERO( l2 ))
    616             {
    617 
    618                 cvFree( &U );
    619                 return CV_BADFACTOR_ERR;
    620             }                   /* if */
    621 
    622             w = 1 / (l1 * l1 + l2 * l2);
    623 
    624             l1 = F[0] * ml[i3] + F[3] * ml[i3 + 1] + F[6];
    625             l2 = F[1] * ml[i3] + F[4] * ml[i3 + 1] + F[7];
    626 
    627             if( REAL_ZERO( l1 ) && REAL_ZERO( l2 ))
    628             {
    629 
    630                 cvFree( &U );
    631                 return CV_BADFACTOR_ERR;
    632             }                   /* if */
    633 
    634             w += 1 / (l1 * l1 + l2 * l2);
    635             w = sqrt( w );
    636 
    637             for( j = 0; j < 9; j++ )
    638             {
    639 
    640                 U[i9 + j] = w * (double) ml[i3 + j / 3] * (double) mr[i3 + j % 3];
    641             }                   /* for */
    642         }                       /* for */
    643 
    644         new_norm = 0;
    645 
    646         for( a = 0; a < num; a++ )
    647         {                       /* row */
    648 
    649             summ = 0;
    650 
    651             for( t = 0; t < 9; t++ )
    652             {
    653 
    654                 summ += U[a * 9 + t] * F[t];
    655             }                   /* for */
    656 
    657             new_norm += summ * summ;
    658         }                       /* for */
    659 
    660         new_norm = sqrt( new_norm );
    661 
    662         icvAnalyticPoints8( U, num, F );
    663     }                           /* while */
    664 
    665     cvFree( &U );
    666     return CV_NO_ERR;
    667 
    668 }                               /* cs_Points8 */
    669 
    670 /*===========================================================================*/
    671 double
    672 icvAnalyticPoints8( double *A, int num, double *F )
    673 {
    674     double *U;
    675     double V[8 * 8];
    676     double W[8];
    677     double *f;
    678     double solution[9];
    679     double temp1[8 * 8];
    680     double *temp2;
    681     double *A_short;
    682     double norm, summ, best_norm;
    683     int num8 = num * 8, num9 = num * 9;
    684     int i, j, j8, j9, value, a, a8, a9, a_num, b, b8, t;
    685 
    686     /* --------- Initialization data ------------------ */
    687 
    688     if( !A || num < 8 || !F )
    689         return -1;
    690 
    691     best_norm = -1;
    692     U = (double *) cvAlloc( (num8) * sizeof( double ));
    693 
    694     if( !U )
    695         return -1;
    696 
    697     f = (double *) cvAlloc( (num) * sizeof( double ));
    698 
    699     if( !f )
    700     {
    701         cvFree( &U );
    702         return -1;
    703     }                           /* if */
    704 
    705     temp2 = (double *) cvAlloc( (num8) * sizeof( double ));
    706 
    707     if( !temp2 )
    708     {
    709         cvFree( &f );
    710         cvFree( &U );
    711         return -1;
    712     }                           /* if */
    713 
    714     A_short = (double *) cvAlloc( (num8) * sizeof( double ));
    715 
    716     if( !A_short )
    717     {
    718         cvFree( &temp2 );
    719         cvFree( &f );
    720         cvFree( &U );
    721         return -1;
    722     }                           /* if */
    723 
    724     for( i = 0; i < 8; i++ )
    725     {
    726         for( j8 = 0, j9 = 0; j9 < num9; j8 += 8, j9 += 9 )
    727         {
    728             A_short[j8 + i] = A[j9 + i + 1];
    729         }                       /* for */
    730     }                           /* for */
    731 
    732     for( i = 0; i < 9; i++ )
    733     {
    734 
    735         for( j = 0, j8 = 0, j9 = 0; j < num; j++, j8 += 8, j9 += 9 )
    736         {
    737 
    738             f[j] = -A[j9 + i];
    739 
    740             if( i )
    741                 A_short[j8 + i - 1] = A[j9 + i - 1];
    742         }                       /* for */
    743 
    744         value = icvSingularValueDecomposition( num, 8, A_short, W, 1, U, 1, V );
    745 
    746         if( !value )
    747         {                       /* -----------  computing the solution  ----------- */
    748 
    749             /*  -----------  W = W(-1)  ----------- */
    750             for( j = 0; j < 8; j++ )
    751             {
    752                 if( !REAL_ZERO( W[j] ))
    753                     W[j] = 1 / W[j];
    754             }                   /* for */
    755 
    756             /* -----------  temp1 = V * W(-1)  ----------- */
    757             for( a8 = 0; a8 < 64; a8 += 8 )
    758             {                   /* row */
    759                 for( b = 0; b < 8; b++ )
    760                 {               /* column */
    761                     temp1[a8 + b] = V[a8 + b] * W[b];
    762                 }               /* for */
    763             }                   /* for */
    764 
    765             /*  -----------  temp2 = V * W(-1) * U(T)  ----------- */
    766             for( a8 = 0, a_num = 0; a8 < 64; a8 += 8, a_num += num )
    767             {                   /* row */
    768                 for( b = 0, b8 = 0; b < num; b++, b8 += 8 )
    769                 {               /* column */
    770 
    771                     temp2[a_num + b] = 0;
    772 
    773                     for( t = 0; t < 8; t++ )
    774                     {
    775 
    776                         temp2[a_num + b] += temp1[a8 + t] * U[b8 + t];
    777                     }           /* for */
    778                 }               /* for */
    779             }                   /* for */
    780 
    781             /* -----------  solution = V * W(-1) * U(T) * f  ----------- */
    782             for( a = 0, a_num = 0; a < 8; a++, a_num += num )
    783             {                   /* row */
    784                 for( b = 0; b < num; b++ )
    785                 {               /* column */
    786 
    787                     solution[a] = 0;
    788 
    789                     for( t = 0; t < num && W[a]; t++ )
    790                     {
    791                         solution[a] += temp2[a_num + t] * f[t];
    792                     }           /* for */
    793                 }               /* for */
    794             }                   /* for */
    795 
    796             for( a = 8; a > 0; a-- )
    797             {
    798 
    799                 if( a == i )
    800                     break;
    801                 solution[a] = solution[a - 1];
    802             }                   /* for */
    803 
    804             solution[a] = 1;
    805 
    806             norm = 0;
    807 
    808             for( a9 = 0; a9 < num9; a9 += 9 )
    809             {                   /* row */
    810 
    811                 summ = 0;
    812 
    813                 for( t = 0; t < 9; t++ )
    814                 {
    815 
    816                     summ += A[a9 + t] * solution[t];
    817                 }               /* for */
    818 
    819                 norm += summ * summ;
    820             }                   /* for */
    821 
    822             norm = sqrt( norm );
    823 
    824             if( best_norm == -1 || norm < best_norm )
    825             {
    826 
    827                 for( j = 0; j < 9; j++ )
    828                     F[j] = solution[j];
    829 
    830                 best_norm = norm;
    831             }                   /* if */
    832         }                       /* if */
    833     }                           /* for */
    834 
    835     cvFree( &A_short );
    836     cvFree( &temp2 );
    837     cvFree( &f );
    838     cvFree( &U );
    839 
    840     return best_norm;
    841 
    842 }                               /* cs_AnalyticPoints8 */
    843 
    844 /*===========================================================================*/
    845 CvStatus
    846 icvRank2Constraint( double *F )
    847 {
    848     double U[9], V[9], W[3];
    849     double aW[3];
    850     int i, i3, j, j3, t;
    851 
    852     if( F == 0 )
    853         return CV_BADFACTOR_ERR;
    854 
    855     if( icvSingularValueDecomposition( 3, 3, F, W, 1, U, 1, V ))
    856         return CV_BADFACTOR_ERR;
    857 
    858     aW[0] = fabs(W[0]);
    859     aW[1] = fabs(W[1]);
    860     aW[2] = fabs(W[2]);
    861 
    862     if( aW[0] < aW[1] )
    863     {
    864         if( aW[0] < aW[2] )
    865         {
    866 
    867             if( REAL_ZERO( W[0] ))
    868                 return CV_NO_ERR;
    869             else
    870                 W[0] = 0;
    871         }
    872         else
    873         {
    874 
    875             if( REAL_ZERO( W[2] ))
    876                 return CV_NO_ERR;
    877             else
    878                 W[2] = 0;
    879         }                       /* if */
    880     }
    881     else
    882     {
    883 
    884         if( aW[1] < aW[2] )
    885         {
    886 
    887             if( REAL_ZERO( W[1] ))
    888                 return CV_NO_ERR;
    889             else
    890                 W[1] = 0;
    891         }
    892         else
    893         {
    894             if( REAL_ZERO( W[2] ))
    895                 return CV_NO_ERR;
    896             else
    897                 W[2] = 0;
    898         }                       /* if */
    899     }                           /* if */
    900 
    901     for( i = 0; i < 3; i++ )
    902     {
    903         for( j3 = 0; j3 < 9; j3 += 3 )
    904         {
    905             U[j3 + i] *= W[i];
    906         }                       /* for */
    907     }                           /* for */
    908 
    909     for( i = 0, i3 = 0; i < 3; i++, i3 += 3 )
    910     {
    911         for( j = 0, j3 = 0; j < 3; j++, j3 += 3 )
    912         {
    913 
    914             F[i3 + j] = 0;
    915 
    916             for( t = 0; t < 3; t++ )
    917             {
    918                 F[i3 + j] += U[i3 + t] * V[j3 + t];
    919             }                   /* for */
    920         }                       /* for */
    921     }                           /* for */
    922 
    923     return CV_NO_ERR;
    924 }                               /* cs_Rank2Constraint */
    925 
    926 
    927 /*===========================================================================*/
    928 
    929 int
    930 icvSingularValueDecomposition( int M,
    931                                int N,
    932                                double *A,
    933                                double *W, int get_U, double *U, int get_V, double *V )
    934 {
    935     int i = 0, j, k, l = 0, i1, k1, l1 = 0;
    936     int iterations, error = 0, jN, iN, kN, lN = 0;
    937     double *rv1;
    938     double c, f, g, h, s, x, y, z, scale, anorm;
    939     double af, ag, ah, t;
    940     int MN = M * N;
    941     int NN = N * N;
    942 
    943     /*  max_iterations - maximum number QR-iterations
    944        cc - reduces requirements to number stitch (cc>1)
    945      */
    946 
    947     int max_iterations = 100;
    948     double cc = 100;
    949 
    950     if( M < N )
    951         return N;
    952 
    953     rv1 = (double *) cvAlloc( N * sizeof( double ));
    954 
    955     if( rv1 == 0 )
    956         return N;
    957 
    958     for( iN = 0; iN < MN; iN += N )
    959     {
    960         for( j = 0; j < N; j++ )
    961             U[iN + j] = A[iN + j];
    962     }                           /* for */
    963 
    964     /*  Adduction to bidiagonal type (transformations of reflection).
    965        Bidiagonal matrix is located in W (diagonal elements)
    966        and in rv1 (upperdiagonal elements)
    967      */
    968 
    969     g = 0;
    970     scale = 0;
    971     anorm = 0;
    972 
    973     for( i = 0, iN = 0; i < N; i++, iN += N )
    974     {
    975 
    976         l = i + 1;
    977         lN = iN + N;
    978         rv1[i] = scale * g;
    979 
    980         /*  Multiplyings on the left  */
    981 
    982         g = 0;
    983         s = 0;
    984         scale = 0;
    985 
    986         for( kN = iN; kN < MN; kN += N )
    987             scale += fabs( U[kN + i] );
    988 
    989         if( !REAL_ZERO( scale ))
    990         {
    991 
    992             for( kN = iN; kN < MN; kN += N )
    993             {
    994 
    995                 U[kN + i] /= scale;
    996                 s += U[kN + i] * U[kN + i];
    997             }                   /* for */
    998 
    999             f = U[iN + i];
   1000             g = -sqrt( s ) * Sgn( f );
   1001             h = f * g - s;
   1002             U[iN + i] = f - g;
   1003 
   1004             for( j = l; j < N; j++ )
   1005             {
   1006 
   1007                 s = 0;
   1008 
   1009                 for( kN = iN; kN < MN; kN += N )
   1010                 {
   1011 
   1012                     s += U[kN + i] * U[kN + j];
   1013                 }               /* for */
   1014 
   1015                 f = s / h;
   1016 
   1017                 for( kN = iN; kN < MN; kN += N )
   1018                 {
   1019 
   1020                     U[kN + j] += f * U[kN + i];
   1021                 }               /* for */
   1022             }                   /* for */
   1023 
   1024             for( kN = iN; kN < MN; kN += N )
   1025                 U[kN + i] *= scale;
   1026         }                       /* if */
   1027 
   1028         W[i] = scale * g;
   1029 
   1030         /*  Multiplyings on the right  */
   1031 
   1032         g = 0;
   1033         s = 0;
   1034         scale = 0;
   1035 
   1036         for( k = l; k < N; k++ )
   1037             scale += fabs( U[iN + k] );
   1038 
   1039         if( !REAL_ZERO( scale ))
   1040         {
   1041 
   1042             for( k = l; k < N; k++ )
   1043             {
   1044 
   1045                 U[iN + k] /= scale;
   1046                 s += (U[iN + k]) * (U[iN + k]);
   1047             }                   /* for */
   1048 
   1049             f = U[iN + l];
   1050             g = -sqrt( s ) * Sgn( f );
   1051             h = f * g - s;
   1052             U[i * N + l] = f - g;
   1053 
   1054             for( k = l; k < N; k++ )
   1055                 rv1[k] = U[iN + k] / h;
   1056 
   1057             for( jN = lN; jN < MN; jN += N )
   1058             {
   1059 
   1060                 s = 0;
   1061 
   1062                 for( k = l; k < N; k++ )
   1063                     s += U[jN + k] * U[iN + k];
   1064 
   1065                 for( k = l; k < N; k++ )
   1066                     U[jN + k] += s * rv1[k];
   1067 
   1068             }                   /* for */
   1069 
   1070             for( k = l; k < N; k++ )
   1071                 U[iN + k] *= scale;
   1072         }                       /* if */
   1073 
   1074         t = fabs( W[i] );
   1075         t += fabs( rv1[i] );
   1076         anorm = MAX( anorm, t );
   1077     }                           /* for */
   1078 
   1079     anorm *= cc;
   1080 
   1081     /*  accumulation of right transformations, if needed  */
   1082 
   1083     if( get_V )
   1084     {
   1085 
   1086         for( i = N - 1, iN = NN - N; i >= 0; i--, iN -= N )
   1087         {
   1088 
   1089             if( i < N - 1 )
   1090             {
   1091 
   1092                 /*  pass-by small g  */
   1093                 if( !REAL_ZERO( g ))
   1094                 {
   1095 
   1096                     for( j = l, jN = lN; j < N; j++, jN += N )
   1097                         V[jN + i] = U[iN + j] / U[iN + l] / g;
   1098 
   1099                     for( j = l; j < N; j++ )
   1100                     {
   1101 
   1102                         s = 0;
   1103 
   1104                         for( k = l, kN = lN; k < N; k++, kN += N )
   1105                             s += U[iN + k] * V[kN + j];
   1106 
   1107                         for( kN = lN; kN < NN; kN += N )
   1108                             V[kN + j] += s * V[kN + i];
   1109                     }           /* for */
   1110                 }               /* if */
   1111 
   1112                 for( j = l, jN = lN; j < N; j++, jN += N )
   1113                 {
   1114                     V[iN + j] = 0;
   1115                     V[jN + i] = 0;
   1116                 }               /* for */
   1117             }                   /* if */
   1118 
   1119             V[iN + i] = 1;
   1120             g = rv1[i];
   1121             l = i;
   1122             lN = iN;
   1123         }                       /* for */
   1124     }                           /* if */
   1125 
   1126     /*  accumulation of left transformations, if needed  */
   1127 
   1128     if( get_U )
   1129     {
   1130 
   1131         for( i = N - 1, iN = NN - N; i >= 0; i--, iN -= N )
   1132         {
   1133 
   1134             l = i + 1;
   1135             lN = iN + N;
   1136             g = W[i];
   1137 
   1138             for( j = l; j < N; j++ )
   1139                 U[iN + j] = 0;
   1140 
   1141             /*  pass-by small g  */
   1142             if( !REAL_ZERO( g ))
   1143             {
   1144 
   1145                 for( j = l; j < N; j++ )
   1146                 {
   1147 
   1148                     s = 0;
   1149 
   1150                     for( kN = lN; kN < MN; kN += N )
   1151                         s += U[kN + i] * U[kN + j];
   1152 
   1153                     f = s / U[iN + i] / g;
   1154 
   1155                     for( kN = iN; kN < MN; kN += N )
   1156                         U[kN + j] += f * U[kN + i];
   1157                 }               /* for */
   1158 
   1159                 for( jN = iN; jN < MN; jN += N )
   1160                     U[jN + i] /= g;
   1161             }
   1162             else
   1163             {
   1164 
   1165                 for( jN = iN; jN < MN; jN += N )
   1166                     U[jN + i] = 0;
   1167             }                   /* if */
   1168 
   1169             U[iN + i] += 1;
   1170         }                       /* for */
   1171     }                           /* if */
   1172 
   1173     /*  Iterations QR-algorithm for bidiagonal matrixes
   1174        W[i] - is the main diagonal
   1175        rv1[i] - is the top diagonal, rv1[0]=0.
   1176      */
   1177 
   1178     for( k = N - 1; k >= 0; k-- )
   1179     {
   1180 
   1181         k1 = k - 1;
   1182         iterations = 0;
   1183 
   1184         for( ;; )
   1185         {
   1186 
   1187             /*  Cycle: checking a possibility of fission matrix  */
   1188             for( l = k; l >= 0; l-- )
   1189             {
   1190 
   1191                 l1 = l - 1;
   1192 
   1193                 if( REAL_ZERO( rv1[l] ) || REAL_ZERO( W[l1] ))
   1194                     break;
   1195             }                   /* for */
   1196 
   1197             if( !REAL_ZERO( rv1[l] ))
   1198             {
   1199 
   1200                 /*  W[l1] = 0,  matrix possible to fission
   1201                    by clearing out rv1[l]  */
   1202 
   1203                 c = 0;
   1204                 s = 1;
   1205 
   1206                 for( i = l; i <= k; i++ )
   1207                 {
   1208 
   1209                     f = s * rv1[i];
   1210                     rv1[i] = c * rv1[i];
   1211 
   1212                     /*  Rotations are done before the end of the block,
   1213                        or when element in the line is finagle.
   1214                      */
   1215 
   1216                     if( REAL_ZERO( f ))
   1217                         break;
   1218 
   1219                     g = W[i];
   1220 
   1221                     /*  Scaling prevents finagling H ( F!=0!) */
   1222 
   1223                     af = fabs( f );
   1224                     ag = fabs( g );
   1225 
   1226                     if( af < ag )
   1227                         h = ag * sqrt( 1 + (f / g) * (f / g) );
   1228                     else
   1229                         h = af * sqrt( 1 + (f / g) * (f / g) );
   1230 
   1231                     W[i] = h;
   1232                     c = g / h;
   1233                     s = -f / h;
   1234 
   1235                     if( get_U )
   1236                     {
   1237 
   1238                         for( jN = 0; jN < MN; jN += N )
   1239                         {
   1240 
   1241                             y = U[jN + l1];
   1242                             z = U[jN + i];
   1243                             U[jN + l1] = y * c + z * s;
   1244                             U[jN + i] = -y * s + z * c;
   1245                         }       /* for */
   1246                     }           /* if */
   1247                 }               /* for */
   1248             }                   /* if */
   1249 
   1250 
   1251             /*  Output in this place of program means,
   1252                that rv1[L] = 0, matrix fissioned
   1253                Iterations of the process of the persecution
   1254                will be executed always for
   1255                the bottom block ( from l before k ),
   1256                with increase l possible.
   1257              */
   1258 
   1259             z = W[k];
   1260 
   1261             if( l == k )
   1262                 break;
   1263 
   1264             /*  Completion iterations: lower block
   1265                became trivial ( rv1[K]=0)  */
   1266 
   1267             if( iterations++ == max_iterations )
   1268                 return k;
   1269 
   1270             /*  Shift is computed on the lowest order 2 minor.  */
   1271 
   1272             x = W[l];
   1273             y = W[k1];
   1274             g = rv1[k1];
   1275             h = rv1[k];
   1276 
   1277             /*  consequent fission prevents forming a machine zero  */
   1278             f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h) / y;
   1279 
   1280             /*  prevented overflow  */
   1281             if( fabs( f ) > 1 )
   1282             {
   1283                 g = fabs( f );
   1284                 g *= sqrt( 1 + (1 / f) * (1 / f) );
   1285             }
   1286             else
   1287                 g = sqrt( f * f + 1 );
   1288 
   1289             f = ((x - z) * (x + z) + h * (y / (f + fabs( g ) * Sgn( f )) - h)) / x;
   1290             c = 1;
   1291             s = 1;
   1292 
   1293             for( i1 = l; i1 <= k1; i1++ )
   1294             {
   1295 
   1296                 i = i1 + 1;
   1297                 g = rv1[i];
   1298                 y = W[i];
   1299                 h = s * g;
   1300                 g *= c;
   1301 
   1302                 /*  Scaling at calculation Z prevents its clearing,
   1303                    however if F and H both are zero - pass-by of fission on Z.
   1304                  */
   1305 
   1306                 af = fabs( f );
   1307                 ah = fabs( h );
   1308 
   1309                 if( af < ah )
   1310                     z = ah * sqrt( 1 + (f / h) * (f / h) );
   1311 
   1312                 else
   1313                 {
   1314 
   1315                     z = 0;
   1316                     if( !REAL_ZERO( af ))
   1317                         z = af * sqrt( 1 + (h / f) * (h / f) );
   1318                 }               /* if */
   1319 
   1320                 rv1[i1] = z;
   1321 
   1322                 /*  if Z=0, the rotation is free.  */
   1323                 if( !REAL_ZERO( z ))
   1324                 {
   1325 
   1326                     c = f / z;
   1327                     s = h / z;
   1328                 }               /* if */
   1329 
   1330                 f = x * c + g * s;
   1331                 g = -x * s + g * c;
   1332                 h = y * s;
   1333                 y *= c;
   1334 
   1335                 if( get_V )
   1336                 {
   1337 
   1338                     for( jN = 0; jN < NN; jN += N )
   1339                     {
   1340 
   1341                         x = V[jN + i1];
   1342                         z = V[jN + i];
   1343                         V[jN + i1] = x * c + z * s;
   1344                         V[jN + i] = -x * s + z * c;
   1345                     }           /* for */
   1346                 }               /* if */
   1347 
   1348                 af = fabs( f );
   1349                 ah = fabs( h );
   1350 
   1351                 if( af < ah )
   1352                     z = ah * sqrt( 1 + (f / h) * (f / h) );
   1353                 else
   1354                 {
   1355 
   1356                     z = 0;
   1357                     if( !REAL_ZERO( af ))
   1358                         z = af * sqrt( 1 + (h / f) * (h / f) );
   1359                 }               /* if */
   1360 
   1361                 W[i1] = z;
   1362 
   1363                 if( !REAL_ZERO( z ))
   1364                 {
   1365 
   1366                     c = f / z;
   1367                     s = h / z;
   1368                 }               /* if */
   1369 
   1370                 f = c * g + s * y;
   1371                 x = -s * g + c * y;
   1372 
   1373                 if( get_U )
   1374                 {
   1375 
   1376                     for( jN = 0; jN < MN; jN += N )
   1377                     {
   1378 
   1379                         y = U[jN + i1];
   1380                         z = U[jN + i];
   1381                         U[jN + i1] = y * c + z * s;
   1382                         U[jN + i] = -y * s + z * c;
   1383                     }           /* for */
   1384                 }               /* if */
   1385             }                   /* for */
   1386 
   1387             rv1[l] = 0;
   1388             rv1[k] = f;
   1389             W[k] = x;
   1390         }                       /* for */
   1391 
   1392         if( z < 0 )
   1393         {
   1394 
   1395             W[k] = -z;
   1396 
   1397             if( get_V )
   1398             {
   1399 
   1400                 for( jN = 0; jN < NN; jN += N )
   1401                     V[jN + k] *= -1;
   1402             }                   /* if */
   1403         }                       /* if */
   1404     }                           /* for */
   1405 
   1406     cvFree( &rv1 );
   1407 
   1408     return error;
   1409 
   1410 }                               /* vm_SingularValueDecomposition */
   1411 
   1412 /*========================================================================*/
   1413 
   1414 /* Obsolete functions. Just for ViewMorping */
   1415 /*=====================================================================================*/
   1416 
   1417 int
   1418 icvGaussMxN( double *A, double *B, int M, int N, double **solutions )
   1419 {
   1420     int *variables;
   1421     int row, swapi, i, i_best = 0, j, j_best = 0, t;
   1422     double swapd, ratio, bigest;
   1423 
   1424     if( !A || !B || !M || !N )
   1425         return -1;
   1426 
   1427     variables = (int *) cvAlloc( (size_t) N * sizeof( int ));
   1428 
   1429     if( variables == 0 )
   1430         return -1;
   1431 
   1432     for( i = 0; i < N; i++ )
   1433     {
   1434         variables[i] = i;
   1435     }                           /* for */
   1436 
   1437     /* -----  Direct way  ----- */
   1438 
   1439     for( row = 0; row < M; row++ )
   1440     {
   1441 
   1442         bigest = 0;
   1443 
   1444         for( j = row; j < M; j++ )
   1445         {                       /* search non null element */
   1446             for( i = row; i < N; i++ )
   1447             {
   1448                 double a = fabs( A[j * N + i] ), b = fabs( bigest );
   1449                 if( a > b )
   1450                 {
   1451                     bigest = A[j * N + i];
   1452                     i_best = i;
   1453                     j_best = j;
   1454                 }               /* if */
   1455             }                   /* for */
   1456         }                       /* for */
   1457 
   1458         if( REAL_ZERO( bigest ))
   1459             break;              /* if all shank elements are null */
   1460 
   1461         if( j_best - row )
   1462         {
   1463 
   1464             for( t = 0; t < N; t++ )
   1465             {                   /* swap a rows */
   1466 
   1467                 swapd = A[row * N + t];
   1468                 A[row * N + t] = A[j_best * N + t];
   1469                 A[j_best * N + t] = swapd;
   1470             }                   /* for */
   1471 
   1472             swapd = B[row];
   1473             B[row] = B[j_best];
   1474             B[j_best] = swapd;
   1475         }                       /* if */
   1476 
   1477         if( i_best - row )
   1478         {
   1479 
   1480             for( t = 0; t < M; t++ )
   1481             {                   /* swap a columns  */
   1482 
   1483                 swapd = A[t * N + i_best];
   1484                 A[t * N + i_best] = A[t * N + row];
   1485                 A[t * N + row] = swapd;
   1486             }                   /* for */
   1487 
   1488             swapi = variables[row];
   1489             variables[row] = variables[i_best];
   1490             variables[i_best] = swapi;
   1491         }                       /* if */
   1492 
   1493         for( i = row + 1; i < M; i++ )
   1494         {                       /* recounting A and B */
   1495 
   1496             ratio = -A[i * N + row] / A[row * N + row];
   1497             B[i] += B[row] * ratio;
   1498 
   1499             for( j = N - 1; j >= row; j-- )
   1500             {
   1501 
   1502                 A[i * N + j] += A[row * N + j] * ratio;
   1503             }                   /* for */
   1504         }                       /* for */
   1505     }                           /* for */
   1506 
   1507     if( row < M )
   1508     {                           /* if rank(A)<M */
   1509 
   1510         for( j = row; j < M; j++ )
   1511         {
   1512             if( !REAL_ZERO( B[j] ))
   1513             {
   1514 
   1515                 cvFree( &variables );
   1516                 return -1;      /* if system is antithetic */
   1517             }                   /* if */
   1518         }                       /* for */
   1519 
   1520         M = row;                /* decreasing size of the task */
   1521     }                           /* if */
   1522 
   1523     /* ----- Reverse way ----- */
   1524 
   1525     if( M < N )
   1526     {                           /* if solution are not exclusive */
   1527 
   1528         *solutions = (double *) cvAlloc( ((N - M + 1) * N) * sizeof( double ));
   1529 
   1530         if( *solutions == 0 )
   1531         {
   1532             cvFree( &variables );
   1533             return -1;
   1534         }
   1535 
   1536 
   1537         for( t = M; t <= N; t++ )
   1538         {
   1539             for( j = M; j < N; j++ )
   1540             {
   1541 
   1542                 (*solutions)[(t - M) * N + variables[j]] = (double) (t == j);
   1543             }                   /* for */
   1544 
   1545             for( i = M - 1; i >= 0; i-- )
   1546             {                   /* finding component of solution */
   1547 
   1548                 if( t < N )
   1549                 {
   1550                     (*solutions)[(t - M) * N + variables[i]] = 0;
   1551                 }
   1552                 else
   1553                 {
   1554                     (*solutions)[(t - M) * N + variables[i]] = B[i] / A[i * N + i];
   1555                 }               /* if */
   1556 
   1557                 for( j = i + 1; j < N; j++ )
   1558                 {
   1559 
   1560                     (*solutions)[(t - M) * N + variables[i]] -=
   1561                         (*solutions)[(t - M) * N + variables[j]] * A[i * N + j] / A[i * N + i];
   1562                 }               /* for */
   1563             }                   /* for */
   1564         }                       /* for */
   1565 
   1566         cvFree( &variables );
   1567         return N - M;
   1568     }                           /* if */
   1569 
   1570     *solutions = (double *) cvAlloc( (N) * sizeof( double ));
   1571 
   1572     if( solutions == 0 )
   1573         return -1;
   1574 
   1575     for( i = N - 1; i >= 0; i-- )
   1576     {                           /* finding exclusive solution */
   1577 
   1578         (*solutions)[variables[i]] = B[i] / A[i * N + i];
   1579 
   1580         for( j = i + 1; j < N; j++ )
   1581         {
   1582 
   1583             (*solutions)[variables[i]] -=
   1584                 (*solutions)[variables[j]] * A[i * N + j] / A[i * N + i];
   1585         }                       /* for */
   1586     }                           /* for */
   1587 
   1588     cvFree( &variables );
   1589     return 0;
   1590 
   1591 }                               /* icvGaussMxN */
   1592 
   1593 /*=====================================================================================*/
   1594 /*
   1595 static CvStatus
   1596 icvGetCoof( double *f1, double *f2, double *a2, double *a1, double *a0 )
   1597 {
   1598     double G[9], a3;
   1599     int i;
   1600 
   1601     if( !f1 || !f2 || !a0 || !a1 || !a2 )
   1602         return CV_BADFACTOR_ERR;
   1603 
   1604     for( i = 0; i < 9; i++ )
   1605     {
   1606 
   1607         G[i] = f1[i] - f2[i];
   1608     }
   1609 
   1610     a3 = icvDet( G );
   1611 
   1612     if( REAL_ZERO( a3 ))
   1613         return CV_BADFACTOR_ERR;
   1614 
   1615     *a2 = 0;
   1616     *a1 = 0;
   1617     *a0 = icvDet( f2 );
   1618 
   1619     for( i = 0; i < 9; i++ )
   1620     {
   1621 
   1622         *a2 += f2[i] * icvMinor( G, (int) (i % 3), (int) (i / 3) );
   1623         *a1 += G[i] * icvMinor( f2, (int) (i % 3), (int) (i / 3) );
   1624     }
   1625 
   1626     *a0 /= a3;
   1627     *a1 /= a3;
   1628     *a2 /= a3;
   1629 
   1630     return CV_NO_ERR;
   1631 
   1632 }*/                               /* icvGetCoof */
   1633 
   1634 
   1635 
   1636 /*======================================================================================*/
   1637 
   1638 /*F///////////////////////////////////////////////////////////////////////////////////////
   1639 //    Name:    icvLMedS7
   1640 //    Purpose:
   1641 //
   1642 //
   1643 //    Context:
   1644 //    Parameters:
   1645 //
   1646 //
   1647 //
   1648 //
   1649 //
   1650 //
   1651 //
   1652 //    Returns:
   1653 //      CV_NO_ERR if all Ok or error code
   1654 //    Notes:
   1655 //F*/
   1656 
   1657 CvStatus
   1658 icvLMedS7( int *points1, int *points2, CvMatrix3 * matrix )
   1659 {                               /* Incorrect realization */
   1660     CvStatus error = CV_NO_ERR;
   1661 
   1662 /*    int         amount; */
   1663     matrix = matrix;
   1664     points1 = points1;
   1665     points2 = points2;
   1666 
   1667 /*    error = cs_Point7( points1, points2, matrix ); */
   1668 /*    error = icvPoint7    ( points1, points2, matrix,&amount ); */
   1669     return error;
   1670 
   1671 }                               /* icvLMedS7 */
   1672 
   1673 
   1674 /*======================================================================================*/
   1675 /*F///////////////////////////////////////////////////////////////////////////////////////
   1676 //    Name:    icvPoint7
   1677 //    Purpose:
   1678 //
   1679 //
   1680 //    Context:
   1681 //    Parameters:
   1682 //
   1683 //
   1684 //
   1685 //
   1686 //
   1687 //
   1688 //
   1689 //    Returns:
   1690 //      CV_NO_ERR if all Ok or error code
   1691 //    Notes:
   1692 //F*/
   1693 
   1694 CvStatus
   1695 icvPoint7( int *ml, int *mr, double *F, int *amount )
   1696 {
   1697     double A[63], B[7];
   1698     double *solutions;
   1699     double a2, a1, a0;
   1700     double squares[6];
   1701     int i, j;
   1702 
   1703 /*    int         amount; */
   1704 /*    float*     F; */
   1705 
   1706     CvStatus error = CV_BADFACTOR_ERR;
   1707 
   1708 /*    F = (float*)matrix->m; */
   1709 
   1710     if( !ml || !mr || !F )
   1711         return CV_BADFACTOR_ERR;
   1712 
   1713     for( i = 0; i < 7; i++ )
   1714     {
   1715         for( j = 0; j < 9; j++ )
   1716         {
   1717 
   1718             A[i * 9 + j] = (double) ml[i * 3 + j / 3] * (double) mr[i * 3 + j % 3];
   1719         }                       /* for */
   1720         B[i] = 0;
   1721     }                           /* for */
   1722 
   1723     *amount = 0;
   1724 
   1725     if( icvGaussMxN( A, B, 7, 9, &solutions ) == 2 )
   1726     {
   1727         if( icvGetCoef( solutions, solutions + 9, &a2, &a1, &a0 ) == CV_NO_ERR )
   1728         {
   1729             icvCubic( a2, a1, a0, squares );
   1730 
   1731             for( i = 0; i < 1; i++ )
   1732             {
   1733 
   1734                 if( REAL_ZERO( squares[i * 2 + 1] ))
   1735                 {
   1736 
   1737                     for( j = 0; j < 9; j++ )
   1738                     {
   1739 
   1740                         F[*amount + j] = (float) (squares[i] * solutions[j] +
   1741                                                   (1 - squares[i]) * solutions[j + 9]);
   1742                     }           /* for */
   1743 
   1744                     *amount += 9;
   1745 
   1746                     error = CV_NO_ERR;
   1747                 }               /* if */
   1748             }                   /* for */
   1749 
   1750             cvFree( &solutions );
   1751             return error;
   1752         }
   1753         else
   1754         {
   1755             cvFree( &solutions );
   1756         }                       /* if */
   1757 
   1758     }
   1759     else
   1760     {
   1761         cvFree( &solutions );
   1762     }                           /* if */
   1763 
   1764     return error;
   1765 }                               /* icvPoint7 */
   1766 
   1767