1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
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.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
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.
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.
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.
41 #include "precomp.hpp"
45 #define Sgn(x) ( (x)<0 ? -1:1 ) /* Sgn(0) = 1 ! */
46 /*===========================================================================*/
48 icvLMedS( int *points1, int *points2, int numPoints, CvMatrix3 * fundamentalMatrix )
50 int sample, j, amount_samples, done;
69 if( fundamentalMatrix == 0 )
70 return CV_BADFACTOR_ERR;
76 return CV_BADFACTOR_ERR;
79 ml = (int *) cvAlloc( sizeof( int ) * num * 3 );
80 mr = (int *) cvAlloc( sizeof( int ) * num * 3 );
82 for( i = 0; i < num; i++ )
85 ml[i * 3] = points1[i * 2];
86 ml[i * 3 + 1] = points1[i * 2 + 1];
90 mr[i * 3] = points2[i * 2];
91 mr[i * 3 + 1] = points2[i * 2 + 1];
100 amount_samples = 1000; /* ------- Must be changed ! --------- */
102 for( sample = 0; sample < amount_samples; sample++ )
105 icvChoose7( ml, mr, num, ml7, mr7 );
106 icvPoint7( ml7, mr7, F_try, &amount_solutions );
108 for( i = 0; i < amount_solutions / 9; i++ )
111 Mj_new = icvMedian( ml, mr, num, F_try + i * 9 );
113 if( Mj_new >= 0 && (Mj == -1 || Mj_new < Mj) )
116 for( j = 0; j < 9; j++ )
119 F[j] = F_try[i * 9 + j];
128 return CV_BADFACTOR_ERR;
130 done = icvBoltingPoints( ml, mr, num, F, Mj, &new_ml, &new_mr, &new_num );
137 return CV_OUTOFMEM_ERR;
141 error = icvPoints8( new_ml, new_mr, new_num, F );
149 error = icvPoint7( ml, mr, F, &i );
152 if( error == CV_NO_ERR )
153 error = icvRank2Constraint( F );
155 for( i = 0; i < 3; i++ )
156 for( j = 0; j < 3; j++ )
157 fundamentalMatrix->m[i][j] = (float) F[i * 3 + j];
163 /*===========================================================================*/
164 /*===========================================================================*/
166 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
167 # pragma GCC diagnostic push
168 # pragma GCC diagnostic ignored "-Warray-bounds"
172 icvChoose7( int *ml, int *mr, int num, int *ml7, int *mr7 )
174 int indexes[7], i, j;
176 if( !ml || !mr || num < 7 || !ml7 || !mr7 )
179 for( i = 0; i < 7; i++ )
182 indexes[i] = (int) ((double) rand() / RAND_MAX * num);
184 for( j = 0; j < i; j++ )
187 if( indexes[i] == indexes[j] )
192 for( i = 0; i < 21; i++ )
195 ml7[i] = ml[3 * indexes[i / 3] + i % 3];
196 mr7[i] = mr[3 * indexes[i / 3] + i % 3];
200 /*===========================================================================*/
201 /*===========================================================================*/
203 icvCubic( double a2, double a1, double a0, double *squares )
205 double p, q, D, c1, c2, b1, b2, ro1, ro2, fi1, fi2, tt;
210 return CV_BADFACTOR_ERR;
212 p = a1 - a2 * a2 / 3;
213 q = (9 * a1 * a2 - 27 * a0 - 2 * a2 * a2 * a2) / 27;
214 D = q * q / 4 + p * p * p / 27;
224 ro1 = sqrt( c1 * c1 - D );
227 fi1 = atan2( b1, c1 );
233 c1 = q / 2 + sqrt( D );
234 c2 = q / 2 - sqrt( D );
240 fi1 = CV_PI * (1 - SIGN( c1 )) / 2;
241 fi2 = CV_PI * (1 - SIGN( c2 )) / 2;
244 for( i = 0; i < 6; i++ )
251 squares[i] = x[i][i % 2];
254 if( !REAL_ZERO( ro1 ))
256 tt = SIGN( ro1 ) * pow( fabs( ro1 ), 0.333333333333 );
257 c1 = tt - p / (3. * tt);
258 c2 = tt + p / (3. * tt);
261 if( !REAL_ZERO( ro2 ))
263 tt = SIGN( ro2 ) * pow( fabs( ro2 ), 0.333333333333 );
264 b1 = tt - p / (3. * tt);
265 b2 = tt + p / (3. * tt);
268 for( i = 0; i < 6; i++ )
274 if( !REAL_ZERO( ro1 ))
277 x[i][0] = cos( fi1 / 3. + 2 * CV_PI * (i % 3) / 3. ) * c1 - a2 / 3;
278 x[i][1] = sin( fi1 / 3. + 2 * CV_PI * (i % 3) / 3. ) * c2;
289 if( !REAL_ZERO( ro2 ))
292 x[i][0] = cos( fi2 / 3. + 2 * CV_PI * (i % 3) / 3. ) * b1 - a2 / 3;
293 x[i][1] = sin( fi2 / 3. + 2 * CV_PI * (i % 3) / 3. ) * b2;
305 for( i = 0; i < 6; i++ )
311 squares[t++] = x[i][0];
312 squares[t++] = x[i][1];
315 for( j = i + 1; j < 6; j++ )
318 if( !x[j][2] && REAL_ZERO( x[i][0] - x[j][0] )
319 && REAL_ZERO( x[i][1] - x[j][1] ))
331 #if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 8)
332 # pragma GCC diagnostic pop
335 /*======================================================================================*/
344 value = M[0] * M[4] * M[8] + M[2] * M[3] * M[7] + M[1] * M[5] * M[6] -
345 M[2] * M[4] * M[6] - M[0] * M[5] * M[7] - M[1] * M[3] * M[8];
351 /*===============================================================================*/
353 icvMinor( double *M, int x, int y )
355 int row1, row2, col1, col2;
358 if( !M || x < 0 || x > 2 || y < 0 || y > 2 )
361 row1 = (y == 0 ? 1 : 0);
362 row2 = (y == 2 ? 1 : 2);
363 col1 = (x == 0 ? 1 : 0);
364 col2 = (x == 2 ? 1 : 2);
366 value = M[row1 * 3 + col1] * M[row2 * 3 + col2] - M[row2 * 3 + col1] * M[row1 * 3 + col2];
368 value *= 1 - (x + y) % 2 * 2;
374 /*======================================================================================*/
376 icvGetCoef( double *f1, double *f2, double *a2, double *a1, double *a0 )
381 if( !f1 || !f2 || !a0 || !a1 || !a2 )
382 return CV_BADFACTOR_ERR;
384 for( i = 0; i < 9; i++ )
387 G[i] = f1[i] - f2[i];
393 return CV_BADFACTOR_ERR;
399 for( i = 0; i < 9; i++ )
402 *a2 += f2[i] * icvMinor( G, (int) (i % 3), (int) (i / 3) );
403 *a1 += G[i] * icvMinor( f2, (int) (i % 3), (int) (i / 3) );
414 /*===========================================================================*/
416 icvMedian( int *ml, int *mr, int num, double *F )
418 double l1, l2, l3, d1, d2, value;
422 if( !ml || !mr || !F )
425 deviation = (double *) cvAlloc( (num) * sizeof( double ));
430 for( i = 0, i3 = 0; i < num; i++, i3 += 3 )
433 l1 = F[0] * mr[i3] + F[1] * mr[i3 + 1] + F[2];
434 l2 = F[3] * mr[i3] + F[4] * mr[i3 + 1] + F[5];
435 l3 = F[6] * mr[i3] + F[7] * mr[i3 + 1] + F[8];
437 d1 = (l1 * ml[i3] + l2 * ml[i3 + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
439 l1 = F[0] * ml[i3] + F[3] * ml[i3 + 1] + F[6];
440 l2 = F[1] * ml[i3] + F[4] * ml[i3 + 1] + F[7];
441 l3 = F[2] * ml[i3] + F[5] * ml[i3 + 1] + F[8];
443 d2 = (l1 * mr[i3] + l2 * mr[i3 + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
445 deviation[i] = (double) (d1 * d1 + d2 * d2);
448 if( icvSort( deviation, num ) != CV_NO_ERR )
451 cvFree( &deviation );
455 value = deviation[num / 2];
456 cvFree( &deviation );
461 /*===========================================================================*/
463 icvSort( double *array, int length )
468 if( !array || length < 1 )
469 return CV_BADFACTOR_ERR;
471 for( i = 0; i < length - 1; i++ )
476 for( j = i + 1; j < length; j++ )
479 if( array[j] < array[index] )
487 array[i] = array[index];
488 array[index] = swapd;
496 /*===========================================================================*/
498 icvBoltingPoints( int *ml, int *mr,
499 int num, double *F, double Mj, int **new_ml, int **new_mr, int *new_num )
501 double l1, l2, l3, d1, d2, sigma;
505 if( !ml || !mr || num < 1 || !F || Mj < 0 )
508 index = (int *) cvAlloc( (num) * sizeof( int ));
514 sigma = (double) (2.5 * 1.4826 * (1 + 5. / (num - 7)) * sqrt( Mj ));
516 for( i = 0; i < num * 3; i += 3 )
519 l1 = F[0] * mr[i] + F[1] * mr[i + 1] + F[2];
520 l2 = F[3] * mr[i] + F[4] * mr[i + 1] + F[5];
521 l3 = F[6] * mr[i] + F[7] * mr[i + 1] + F[8];
523 d1 = (l1 * ml[i] + l2 * ml[i + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
525 l1 = F[0] * ml[i] + F[3] * ml[i + 1] + F[6];
526 l2 = F[1] * ml[i] + F[4] * ml[i + 1] + F[7];
527 l3 = F[2] * ml[i] + F[5] * ml[i + 1] + F[8];
529 d2 = (l1 * mr[i] + l2 * mr[i + 1] + l3) / sqrt( l1 * l1 + l2 * l2 );
531 if( d1 * d1 + d2 * d2 <= sigma * sigma )
546 *new_ml = (int *) cvAlloc( (length * 3) * sizeof( int ));
555 *new_mr = (int *) cvAlloc( (length * 3) * sizeof( int ));
567 for( i = 0; i < num * 3; )
573 (*new_ml)[j] = ml[i];
574 (*new_mr)[j++] = mr[i++];
575 (*new_ml)[j] = ml[i];
576 (*new_mr)[j++] = mr[i++];
577 (*new_ml)[j] = ml[i];
578 (*new_mr)[j++] = mr[i++];
587 } /* cs_BoltingPoints */
589 /*===========================================================================*/
591 icvPoints8( int *ml, int *mr, int num, double *F )
594 double l1, l2, w, old_norm = -1, new_norm = -2, summ;
595 int i3, i9, j, num3, its = 0, a, t;
597 if( !ml || !mr || num < 8 || !F )
598 return CV_BADFACTOR_ERR;
600 U = (double *) cvAlloc( (num * 9) * sizeof( double ));
603 return CV_OUTOFMEM_ERR;
607 while( !REAL_ZERO( new_norm - old_norm ))
614 return CV_BADFACTOR_ERR;
619 for( i3 = 0, i9 = 0; i3 < num3; i3 += 3, i9 += 9 )
622 l1 = F[0] * mr[i3] + F[1] * mr[i3 + 1] + F[2];
623 l2 = F[3] * mr[i3] + F[4] * mr[i3 + 1] + F[5];
625 if( REAL_ZERO( l1 ) && REAL_ZERO( l2 ))
629 return CV_BADFACTOR_ERR;
632 w = 1 / (l1 * l1 + l2 * l2);
634 l1 = F[0] * ml[i3] + F[3] * ml[i3 + 1] + F[6];
635 l2 = F[1] * ml[i3] + F[4] * ml[i3 + 1] + F[7];
637 if( REAL_ZERO( l1 ) && REAL_ZERO( l2 ))
641 return CV_BADFACTOR_ERR;
644 w += 1 / (l1 * l1 + l2 * l2);
647 for( j = 0; j < 9; j++ )
650 U[i9 + j] = w * (double) ml[i3 + j / 3] * (double) mr[i3 + j % 3];
656 for( a = 0; a < num; a++ )
661 for( t = 0; t < 9; t++ )
664 summ += U[a * 9 + t] * F[t];
667 new_norm += summ * summ;
670 new_norm = sqrt( new_norm );
672 icvAnalyticPoints8( U, num, F );
680 /*===========================================================================*/
682 icvAnalyticPoints8( double *A, int num, double *F )
692 double norm, summ, best_norm;
693 int num8 = num * 8, num9 = num * 9;
694 int i, j, j8, j9, value, a, a8, a9, a_num, b, b8, t;
696 /* --------- Initialization data ------------------ */
698 if( !A || num < 8 || !F )
702 U = (double *) cvAlloc( (num8) * sizeof( double ));
707 f = (double *) cvAlloc( (num) * sizeof( double ));
715 temp2 = (double *) cvAlloc( (num8) * sizeof( double ));
724 A_short = (double *) cvAlloc( (num8) * sizeof( double ));
734 for( i = 0; i < 8; i++ )
736 for( j8 = 0, j9 = 0; j9 < num9; j8 += 8, j9 += 9 )
738 A_short[j8 + i] = A[j9 + i + 1];
742 for( i = 0; i < 9; i++ )
745 for( j = 0, j8 = 0, j9 = 0; j < num; j++, j8 += 8, j9 += 9 )
751 A_short[j8 + i - 1] = A[j9 + i - 1];
754 value = icvSingularValueDecomposition( num, 8, A_short, W, 1, U, 1, V );
757 { /* ----------- computing the solution ----------- */
759 /* ----------- W = W(-1) ----------- */
760 for( j = 0; j < 8; j++ )
762 if( !REAL_ZERO( W[j] ))
766 /* ----------- temp1 = V * W(-1) ----------- */
767 for( a8 = 0; a8 < 64; a8 += 8 )
769 for( b = 0; b < 8; b++ )
771 temp1[a8 + b] = V[a8 + b] * W[b];
775 /* ----------- temp2 = V * W(-1) * U(T) ----------- */
776 for( a8 = 0, a_num = 0; a8 < 64; a8 += 8, a_num += num )
778 for( b = 0, b8 = 0; b < num; b++, b8 += 8 )
781 temp2[a_num + b] = 0;
783 for( t = 0; t < 8; t++ )
786 temp2[a_num + b] += temp1[a8 + t] * U[b8 + t];
791 /* ----------- solution = V * W(-1) * U(T) * f ----------- */
792 for( a = 0, a_num = 0; a < 8; a++, a_num += num )
794 for( b = 0; b < num; b++ )
799 for( t = 0; t < num && W[a]; t++ )
801 solution[a] += temp2[a_num + t] * f[t];
806 for( a = 8; a > 0; a-- )
811 solution[a] = solution[a - 1];
818 for( a9 = 0; a9 < num9; a9 += 9 )
823 for( t = 0; t < 9; t++ )
826 summ += A[a9 + t] * solution[t];
834 if( best_norm == -1 || norm < best_norm )
837 for( j = 0; j < 9; j++ )
852 } /* cs_AnalyticPoints8 */
854 /*===========================================================================*/
856 icvRank2Constraint( double *F )
858 double U[9], V[9], W[3];
863 return CV_BADFACTOR_ERR;
865 if( icvSingularValueDecomposition( 3, 3, F, W, 1, U, 1, V ))
866 return CV_BADFACTOR_ERR;
877 if( REAL_ZERO( W[0] ))
885 if( REAL_ZERO( W[2] ))
897 if( REAL_ZERO( W[1] ))
904 if( REAL_ZERO( W[2] ))
911 for( i = 0; i < 3; i++ )
913 for( j3 = 0; j3 < 9; j3 += 3 )
919 for( i = 0, i3 = 0; i < 3; i++, i3 += 3 )
921 for( j = 0, j3 = 0; j < 3; j++, j3 += 3 )
926 for( t = 0; t < 3; t++ )
928 F[i3 + j] += U[i3 + t] * V[j3 + t];
934 } /* cs_Rank2Constraint */
937 /*===========================================================================*/
940 icvSingularValueDecomposition( int M,
943 double *W, int get_U, double *U, int get_V, double *V )
945 int i = 0, j, k, l = 0, i1, k1, l1 = 0;
946 int iterations, error = 0, jN, iN, kN, lN = 0;
948 double c, f, g, h, s, x, y, z, scale, anorm;
949 double af, ag, ah, t;
953 /* max_iterations - maximum number QR-iterations
954 cc - reduces requirements to number stitch (cc>1)
957 int max_iterations = 100;
963 rv1 = (double *) cvAlloc( N * sizeof( double ));
968 for( iN = 0; iN < MN; iN += N )
970 for( j = 0; j < N; j++ )
971 U[iN + j] = A[iN + j];
974 /* Adduction to bidiagonal type (transformations of reflection).
975 Bidiagonal matrix is located in W (diagonal elements)
976 and in rv1 (upperdiagonal elements)
983 for( i = 0, iN = 0; i < N; i++, iN += N )
990 /* Multiplyings on the left */
996 for( kN = iN; kN < MN; kN += N )
997 scale += fabs( U[kN + i] );
999 if( !REAL_ZERO( scale ))
1002 for( kN = iN; kN < MN; kN += N )
1006 s += U[kN + i] * U[kN + i];
1010 g = -sqrt( s ) * Sgn( f );
1014 for( j = l; j < N; j++ )
1019 for( kN = iN; kN < MN; kN += N )
1022 s += U[kN + i] * U[kN + j];
1027 for( kN = iN; kN < MN; kN += N )
1030 U[kN + j] += f * U[kN + i];
1034 for( kN = iN; kN < MN; kN += N )
1040 /* Multiplyings on the right */
1046 for( k = l; k < N; k++ )
1047 scale += fabs( U[iN + k] );
1049 if( !REAL_ZERO( scale ))
1052 for( k = l; k < N; k++ )
1056 s += (U[iN + k]) * (U[iN + k]);
1060 g = -sqrt( s ) * Sgn( f );
1062 U[i * N + l] = f - g;
1064 for( k = l; k < N; k++ )
1065 rv1[k] = U[iN + k] / h;
1067 for( jN = lN; jN < MN; jN += N )
1072 for( k = l; k < N; k++ )
1073 s += U[jN + k] * U[iN + k];
1075 for( k = l; k < N; k++ )
1076 U[jN + k] += s * rv1[k];
1080 for( k = l; k < N; k++ )
1085 t += fabs( rv1[i] );
1086 anorm = MAX( anorm, t );
1091 /* accumulation of right transformations, if needed */
1096 for( i = N - 1, iN = NN - N; i >= 0; i--, iN -= N )
1102 /* pass-by small g */
1103 if( !REAL_ZERO( g ))
1106 for( j = l, jN = lN; j < N; j++, jN += N )
1107 V[jN + i] = U[iN + j] / U[iN + l] / g;
1109 for( j = l; j < N; j++ )
1114 for( k = l, kN = lN; k < N; k++, kN += N )
1115 s += U[iN + k] * V[kN + j];
1117 for( kN = lN; kN < NN; kN += N )
1118 V[kN + j] += s * V[kN + i];
1122 for( j = l, jN = lN; j < N; j++, jN += N )
1136 /* accumulation of left transformations, if needed */
1141 for( i = N - 1, iN = NN - N; i >= 0; i--, iN -= N )
1148 for( j = l; j < N; j++ )
1151 /* pass-by small g */
1152 if( !REAL_ZERO( g ))
1155 for( j = l; j < N; j++ )
1160 for( kN = lN; kN < MN; kN += N )
1161 s += U[kN + i] * U[kN + j];
1163 f = s / U[iN + i] / g;
1165 for( kN = iN; kN < MN; kN += N )
1166 U[kN + j] += f * U[kN + i];
1169 for( jN = iN; jN < MN; jN += N )
1175 for( jN = iN; jN < MN; jN += N )
1183 /* Iterations QR-algorithm for bidiagonal matrices
1184 W[i] - is the main diagonal
1185 rv1[i] - is the top diagonal, rv1[0]=0.
1188 for( k = N - 1; k >= 0; k-- )
1197 /* Cycle: checking a possibility of fission matrix */
1198 for( l = k; l >= 0; l-- )
1203 if( REAL_ZERO( rv1[l] ) || REAL_ZERO( W[l1] ))
1207 if( !REAL_ZERO( rv1[l] ))
1210 /* W[l1] = 0, matrix possible to fission
1211 by clearing out rv1[l] */
1216 for( i = l; i <= k; i++ )
1220 rv1[i] = c * rv1[i];
1222 /* Rotations are done before the end of the block,
1223 or when element in the line is finagle.
1231 /* Scaling prevents finagling H ( F!=0!) */
1237 h = ag * sqrt( 1 + (f / g) * (f / g) );
1239 h = af * sqrt( 1 + (f / g) * (f / g) );
1248 for( jN = 0; jN < MN; jN += N )
1253 U[jN + l1] = y * c + z * s;
1254 U[jN + i] = -y * s + z * c;
1261 /* Output in this place of program means,
1262 that rv1[L] = 0, matrix fissioned
1263 Iterations of the process of the persecution
1264 will be executed always for
1265 the bottom block ( from l before k ),
1266 with increase l possible.
1274 /* Completion iterations: lower block
1275 became trivial ( rv1[K]=0) */
1277 if( iterations++ == max_iterations )
1280 /* Shift is computed on the lowest order 2 minor. */
1287 /* consequent fission prevents forming a machine zero */
1288 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2 * h) / y;
1290 /* prevented overflow */
1294 g *= sqrt( 1 + (1 / f) * (1 / f) );
1297 g = sqrt( f * f + 1 );
1299 f = ((x - z) * (x + z) + h * (y / (f + fabs( g ) * Sgn( f )) - h)) / x;
1303 for( i1 = l; i1 <= k1; i1++ )
1312 /* Scaling at calculation Z prevents its clearing,
1313 however if F and H both are zero - pass-by of fission on Z.
1320 z = ah * sqrt( 1 + (f / h) * (f / h) );
1326 if( !REAL_ZERO( af ))
1327 z = af * sqrt( 1 + (h / f) * (h / f) );
1332 /* if Z=0, the rotation is free. */
1333 if( !REAL_ZERO( z ))
1348 for( jN = 0; jN < NN; jN += N )
1353 V[jN + i1] = x * c + z * s;
1354 V[jN + i] = -x * s + z * c;
1362 z = ah * sqrt( 1 + (f / h) * (f / h) );
1367 if( !REAL_ZERO( af ))
1368 z = af * sqrt( 1 + (h / f) * (h / f) );
1373 if( !REAL_ZERO( z ))
1386 for( jN = 0; jN < MN; jN += N )
1391 U[jN + i1] = y * c + z * s;
1392 U[jN + i] = -y * s + z * c;
1410 for( jN = 0; jN < NN; jN += N )
1420 } /* vm_SingularValueDecomposition */
1422 /*========================================================================*/
1424 /* Obsolete functions. Just for ViewMorping */
1425 /*=====================================================================================*/
1428 icvGaussMxN( double *A, double *B, int M, int N, double **solutions )
1431 int row, swapi, i, i_best = 0, j, j_best = 0, t;
1432 double swapd, ratio, bigest;
1434 if( !A || !B || !M || !N )
1437 variables = (int *) cvAlloc( (size_t) N * sizeof( int ));
1439 if( variables == 0 )
1442 for( i = 0; i < N; i++ )
1447 /* ----- Direct way ----- */
1449 for( row = 0; row < M; row++ )
1454 for( j = row; j < M; j++ )
1455 { /* search non null element */
1456 for( i = row; i < N; i++ )
1458 double a = fabs( A[j * N + i] ), b = fabs( bigest );
1461 bigest = A[j * N + i];
1468 if( REAL_ZERO( bigest ))
1469 break; /* if all shank elements are null */
1474 for( t = 0; t < N; t++ )
1477 swapd = A[row * N + t];
1478 A[row * N + t] = A[j_best * N + t];
1479 A[j_best * N + t] = swapd;
1490 for( t = 0; t < M; t++ )
1491 { /* swap a columns */
1493 swapd = A[t * N + i_best];
1494 A[t * N + i_best] = A[t * N + row];
1495 A[t * N + row] = swapd;
1498 swapi = variables[row];
1499 variables[row] = variables[i_best];
1500 variables[i_best] = swapi;
1503 for( i = row + 1; i < M; i++ )
1504 { /* recounting A and B */
1506 ratio = -A[i * N + row] / A[row * N + row];
1507 B[i] += B[row] * ratio;
1509 for( j = N - 1; j >= row; j-- )
1512 A[i * N + j] += A[row * N + j] * ratio;
1518 { /* if rank(A)<M */
1520 for( j = row; j < M; j++ )
1522 if( !REAL_ZERO( B[j] ))
1525 cvFree( &variables );
1526 return -1; /* if system is antithetic */
1530 M = row; /* decreasing size of the task */
1533 /* ----- Reverse way ----- */
1536 { /* if solution are not exclusive */
1538 *solutions = (double *) cvAlloc( ((N - M + 1) * N) * sizeof( double ));
1540 if( *solutions == 0 )
1542 cvFree( &variables );
1547 for( t = M; t <= N; t++ )
1549 for( j = M; j < N; j++ )
1552 (*solutions)[(t - M) * N + variables[j]] = (double) (t == j);
1555 for( i = M - 1; i >= 0; i-- )
1556 { /* finding component of solution */
1560 (*solutions)[(t - M) * N + variables[i]] = 0;
1564 (*solutions)[(t - M) * N + variables[i]] = B[i] / A[i * N + i];
1567 for( j = i + 1; j < N; j++ )
1570 (*solutions)[(t - M) * N + variables[i]] -=
1571 (*solutions)[(t - M) * N + variables[j]] * A[i * N + j] / A[i * N + i];
1576 cvFree( &variables );
1580 *solutions = (double *) cvAlloc( (N) * sizeof( double ));
1582 if( solutions == 0 )
1585 for( i = N - 1; i >= 0; i-- )
1586 { /* finding exclusive solution */
1588 (*solutions)[variables[i]] = B[i] / A[i * N + i];
1590 for( j = i + 1; j < N; j++ )
1593 (*solutions)[variables[i]] -=
1594 (*solutions)[variables[j]] * A[i * N + j] / A[i * N + i];
1598 cvFree( &variables );
1604 /*======================================================================================*/
1605 /*F///////////////////////////////////////////////////////////////////////////////////////
1620 // CV_NO_ERR if all Ok or error code
1625 icvPoint7( int *ml, int *mr, double *F, int *amount )
1628 double *solutions = 0;
1636 CvStatus error = CV_BADFACTOR_ERR;
1638 /* F = (float*)matrix->m; */
1640 if( !ml || !mr || !F )
1641 return CV_BADFACTOR_ERR;
1643 for( i = 0; i < 7; i++ )
1645 for( j = 0; j < 9; j++ )
1648 A[i * 9 + j] = (double) ml[i * 3 + j / 3] * (double) mr[i * 3 + j % 3];
1655 if( icvGaussMxN( A, B, 7, 9, &solutions ) == 2 )
1657 if( icvGetCoef( solutions, solutions + 9, &a2, &a1, &a0 ) == CV_NO_ERR )
1659 icvCubic( a2, a1, a0, squares );
1661 for( i = 0; i < 1; i++ )
1664 if( REAL_ZERO( squares[i * 2 + 1] ))
1667 for( j = 0; j < 9; j++ )
1670 F[*amount + j] = (float) (squares[i] * solutions[j] +
1671 (1 - squares[i]) * solutions[j + 9]);
1680 cvFree( &solutions );
1685 cvFree( &solutions );
1691 cvFree( &solutions );