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/*===========================================================================*/
47CvStatus
48icvLMedS( 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/*===========================================================================*/
165void
166icvChoose7( 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/*===========================================================================*/
196CvStatus
197icvCubic( 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/*======================================================================================*/
326double
327icvDet( 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/*===============================================================================*/
342double
343icvMinor( 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/*======================================================================================*/
365CvStatus
366icvGetCoef( 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/*===========================================================================*/
405double
406icvMedian( 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/*===========================================================================*/
452CvStatus
453icvSort( 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/*===========================================================================*/
487int
488icvBoltingPoints( 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/*===========================================================================*/
580CvStatus
581icvPoints8( 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/*===========================================================================*/
671double
672icvAnalyticPoints8( 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/*===========================================================================*/
845CvStatus
846icvRank2Constraint( 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
929int
930icvSingularValueDecomposition( 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
1417int
1418icvGaussMxN( 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/*
1595static CvStatus
1596icvGetCoof( 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
1657CvStatus
1658icvLMedS7( 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
1694CvStatus
1695icvPoint7( 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