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"
44 //#define REAL_ZERO(x) ( (x) < 1e-8 && (x) > -1e-8)
47 icvGetNormalVector3( CvMatrix3 * Matrix, float *v )
49 /* return vector v that is any 3-vector perpendicular
50 to all the row vectors of Matrix */
52 double *solutions = 0;
54 double B[3] = { 0.f, 0.f, 0.f };
57 if( Matrix == 0 || v == 0 )
58 return CV_NULLPTR_ERR;
60 for( i = 0; i < 3; i++ )
62 for( j = 0; j < 3; j++ )
63 M[i * 3 + j] = (double) (Matrix->m[i][j]);
66 res = icvGaussMxN( M, B, 3, 3, &solutions );
69 return CV_BADFACTOR_ERR;
71 if( res > 0 && solutions )
73 v[0] = (float) solutions[0];
74 v[1] = (float) solutions[1];
75 v[2] = (float) solutions[2];
85 return CV_BADFACTOR_ERR;
89 } /* icvgetNormalVector3 */
92 /*=====================================================================================*/
95 icvMultMatrixVector3( CvMatrix3 * m, float *src, float *dst )
97 if( m == 0 || src == 0 || dst == 0 )
98 return CV_NULLPTR_ERR;
100 dst[0] = m->m[0][0] * src[0] + m->m[0][1] * src[1] + m->m[0][2] * src[2];
101 dst[1] = m->m[1][0] * src[0] + m->m[1][1] * src[1] + m->m[1][2] * src[2];
102 dst[2] = m->m[2][0] * src[0] + m->m[2][1] * src[1] + m->m[2][2] * src[2];
106 } /* icvMultMatrixVector3 */
109 /*=====================================================================================*/
112 icvMultMatrixTVector3( CvMatrix3 * m, float *src, float *dst )
114 if( m == 0 || src == 0 || dst == 0 )
115 return CV_NULLPTR_ERR;
117 dst[0] = m->m[0][0] * src[0] + m->m[1][0] * src[1] + m->m[2][0] * src[2];
118 dst[1] = m->m[0][1] * src[0] + m->m[1][1] * src[1] + m->m[2][1] * src[2];
119 dst[2] = m->m[0][2] * src[0] + m->m[1][2] * src[1] + m->m[2][2] * src[2];
123 } /* icvMultMatrixTVector3 */
125 /*=====================================================================================*/
128 icvCrossLines( float *line1, float *line2, float *cross_point )
132 if( line1 == 0 && line2 == 0 && cross_point == 0 )
133 return CV_NULLPTR_ERR;
135 delta = line1[0] * line2[1] - line1[1] * line2[0];
137 if( REAL_ZERO( delta ))
138 return CV_BADFACTOR_ERR;
140 cross_point[0] = (-line1[2] * line2[1] + line1[1] * line2[2]) / delta;
141 cross_point[1] = (-line1[0] * line2[2] + line1[2] * line2[0]) / delta;
145 } /* icvCrossLines */
149 /*======================================================================================*/
152 icvMakeScanlines( CvMatrix3 * matrix,
154 int *scanlines_1, int *scanlines_2, int *lens_1, int *lens_2, int *numlines )
157 CvStatus error = icvGetCoefficient( matrix, imgSize, scanlines_2, scanlines_1, numlines );
159 /* Make Length of scanlines */
160 if( scanlines_1 == 0 && scanlines_2 == 0 )
163 icvMakeScanlinesLengths( scanlines_1, *numlines, lens_1 );
164 icvMakeScanlinesLengths( scanlines_2, *numlines, lens_2 );
167 } /* icvMakeScanlines */
170 /*======================================================================================*/
173 icvMakeScanlinesLengths( int *scanlines, int numlines, int *lens )
176 int x1, y1, x2, y2, dx, dy;
181 for( index = 0; index < numlines; index++ )
184 x1 = scanlines[curr++];
185 y1 = scanlines[curr++];
186 x2 = scanlines[curr++];
187 y2 = scanlines[curr++];
189 dx = abs( x1 - x2 ) + 1;
190 dy = abs( y1 - y2 ) + 1;
192 lens[index] = MAX( dx, dy );
198 /*======================================================================================*/
201 icvMakeAlphaScanlines( int *scanlines_1,
203 int *scanlines_a, int *lens, int numlines, float alpha )
213 for( index = 0; index < numlines; index++ )
216 x1 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
218 scanlines_a[curr++] = x1;
220 y1 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
222 scanlines_a[curr++] = y1;
224 x2 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
226 scanlines_a[curr++] = x2;
228 y2 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
230 scanlines_a[curr++] = y2;
232 dx = abs( x1 - x2 ) + 1;
233 dy = abs( y1 - y2 ) + 1;
235 lens[curr_len++] = MAX( dx, dy );
242 /*======================================================================================*/
250 /* //////////////////////////////////////////////////////////////////////////////////// */
253 icvGetCoefficient( CvMatrix3 * matrix,
254 CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
270 error = icvGetCoefficientDefault( matrix,
271 imgSize, scanlines_1, scanlines_2, numlines );
276 for( i = 0; i < 3; i++ )
277 for( j = 0; j < 3; j++ )
278 Ft.m[i][j] = F->m[j][i];
281 error = icvGetNormalVector3( &Ft, l_epipole );
282 if( error == CV_NO_ERR && !REAL_ZERO( l_epipole[2] ) && !REAL_ZERO( l_epipole[2] - 1 ))
285 l_epipole[0] /= l_epipole[2];
286 l_epipole[1] /= l_epipole[2];
290 error = icvGetNormalVector3( F, r_epipole );
291 if( error == CV_NO_ERR && !REAL_ZERO( r_epipole[2] ) && !REAL_ZERO( r_epipole[2] - 1 ))
294 r_epipole[0] /= r_epipole[2];
295 r_epipole[1] /= r_epipole[2];
299 if( REAL_ZERO( l_epipole[2] - 1 ) && REAL_ZERO( r_epipole[2] - 1 ))
301 error = icvGetCoefficientStereo( matrix,
304 r_epipole, scanlines_1, scanlines_2, numlines );
305 if( error == CV_NO_ERR )
310 if( REAL_ZERO( l_epipole[2] ) && REAL_ZERO( r_epipole[2] ))
312 error = icvGetCoefficientOrto( matrix,
313 imgSize, scanlines_1, scanlines_2, numlines );
314 if( error == CV_NO_ERR )
320 error = icvGetCoefficientDefault( matrix, imgSize, scanlines_1, scanlines_2, numlines );
324 } /* icvlGetCoefficient */
326 /*===========================================================================*/
328 icvGetCoefficientDefault( CvMatrix3 *,
329 CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
334 *numlines = imgSize.height;
336 if( scanlines_1 == 0 && scanlines_2 == 0 )
340 for( y = 0; y < imgSize.height; y++ )
342 scanlines_1[curr] = 0;
343 scanlines_1[curr + 1] = y;
344 scanlines_1[curr + 2] = imgSize.width - 1;
345 scanlines_1[curr + 3] = y;
347 scanlines_2[curr] = 0;
348 scanlines_2[curr + 1] = y;
349 scanlines_2[curr + 2] = imgSize.width - 1;
350 scanlines_2[curr + 3] = y;
357 } /* icvlGetCoefficientDefault */
359 /*===========================================================================*/
361 icvGetCoefficientOrto( CvMatrix3 * matrix,
362 CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
364 float l_start_end[4], r_start_end[4];
371 if( F->m[0][2] * F->m[1][2] < 0 )
374 if( F->m[2][0] * F->m[2][1] < 0 )
376 error = icvGetStartEnd1( F, imgSize, l_start_end, r_start_end );
382 error = icvGetStartEnd2( F, imgSize, l_start_end, r_start_end );
389 if( F->m[2][0] * F->m[2][1] < 0 )
391 error = icvGetStartEnd3( F, imgSize, l_start_end, r_start_end );
395 error = icvGetStartEnd4( F, imgSize, l_start_end, r_start_end );
399 if( error != CV_NO_ERR )
402 a = fabs( l_start_end[0] - l_start_end[2] );
403 b = fabs( r_start_end[0] - r_start_end[2] );
407 error = icvBuildScanlineLeft( F,
409 scanlines_1, scanlines_2, l_start_end, numlines );
415 error = icvBuildScanlineRight( F,
417 scanlines_1, scanlines_2, r_start_end, numlines );
423 } /* icvlGetCoefficientOrto */
425 /*===========================================================================*/
427 icvGetStartEnd1( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
434 float l_point[3]={0,0,0}, r_point[3], epiline[3]={0,0,0};
435 CvStatus error = CV_OK;
438 width = imgSize.width - 1;
439 height = imgSize.height - 1;
441 l_diagonal[0] = (float) 1 / width;
442 l_diagonal[1] = (float) 1 / height;
445 r_diagonal[0] = (float) 1 / width;
446 r_diagonal[1] = (float) 1 / height;
449 r_point[0] = (float) width;
453 icvMultMatrixVector3( F, r_point, epiline );
454 error = icvCrossLines( l_diagonal, epiline, l_point );
456 assert( error == CV_NO_ERR );
458 if( l_point[0] >= 0 && l_point[0] <= width )
461 l_start_end[0] = l_point[0];
462 l_start_end[1] = l_point[1];
464 r_start_end[0] = r_point[0];
465 r_start_end[1] = r_point[1];
475 l_point[1] = (float) height;
478 icvMultMatrixTVector3( F, l_point, epiline );
479 error = icvCrossLines( r_diagonal, epiline, r_point );
480 assert( error == CV_NO_ERR );
482 if( r_point[0] >= 0 && r_point[0] <= width )
484 l_start_end[0] = l_point[0];
485 l_start_end[1] = l_point[1];
487 r_start_end[0] = r_point[0];
488 r_start_end[1] = r_point[1];
491 return CV_BADFACTOR_ERR;
495 { /* if( l_point[0] > width ) */
497 l_point[0] = (float) width;
501 icvMultMatrixTVector3( F, l_point, epiline );
502 error = icvCrossLines( r_diagonal, epiline, r_point );
503 assert( error == CV_NO_ERR );
505 if( r_point[0] >= 0 && r_point[0] <= width )
508 l_start_end[0] = l_point[0];
509 l_start_end[1] = l_point[1];
511 r_start_end[0] = r_point[0];
512 r_start_end[1] = r_point[1];
515 return CV_BADFACTOR_ERR;
521 r_point[1] = (float) height;
524 icvMultMatrixVector3( F, r_point, epiline );
525 error = icvCrossLines( l_diagonal, epiline, l_point );
526 assert( error == CV_NO_ERR );
528 if( l_point[0] >= 0 && l_point[0] <= width )
531 l_start_end[2] = l_point[0];
532 l_start_end[3] = l_point[1];
534 r_start_end[2] = r_point[0];
535 r_start_end[3] = r_point[1];
545 l_point[1] = (float) height;
548 icvMultMatrixTVector3( F, l_point, epiline );
549 error = icvCrossLines( r_diagonal, epiline, r_point );
550 assert( error == CV_NO_ERR );
552 if( r_point[0] >= 0 && r_point[0] <= width )
555 l_start_end[2] = l_point[0];
556 l_start_end[3] = l_point[1];
558 r_start_end[2] = r_point[0];
559 r_start_end[3] = r_point[1];
562 return CV_BADFACTOR_ERR;
566 { /* if( l_point[0] > width ) */
568 l_point[0] = (float) width;
572 icvMultMatrixTVector3( F, l_point, epiline );
573 error = icvCrossLines( r_diagonal, epiline, r_point );
574 assert( error == CV_NO_ERR );
576 if( r_point[0] >= 0 && r_point[0] <= width )
579 l_start_end[2] = l_point[0];
580 l_start_end[3] = l_point[1];
582 r_start_end[2] = r_point[0];
583 r_start_end[3] = r_point[1];
586 return CV_BADFACTOR_ERR;
592 } /* icvlGetStartEnd1 */
594 /*===========================================================================*/
596 icvGetStartEnd2( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
604 float l_point[3]={0,0,0}, r_point[3], epiline[3]={0,0,0};
605 CvStatus error = CV_OK;
609 width = imgSize.width - 1;
610 height = imgSize.height - 1;
612 l_diagonal[0] = (float) 1 / width;
613 l_diagonal[1] = (float) 1 / height;
616 r_diagonal[0] = (float) height / width;
624 icvMultMatrixVector3( F, r_point, epiline );
626 error = icvCrossLines( l_diagonal, epiline, l_point );
628 assert( error == CV_NO_ERR );
630 if( l_point[0] >= 0 && l_point[0] <= width )
633 l_start_end[0] = l_point[0];
634 l_start_end[1] = l_point[1];
636 r_start_end[0] = r_point[0];
637 r_start_end[1] = r_point[1];
647 l_point[1] = (float) height;
650 icvMultMatrixTVector3( F, l_point, epiline );
651 error = icvCrossLines( r_diagonal, epiline, r_point );
653 assert( error == CV_NO_ERR );
655 if( r_point[0] >= 0 && r_point[0] <= width )
658 l_start_end[0] = l_point[0];
659 l_start_end[1] = l_point[1];
661 r_start_end[0] = r_point[0];
662 r_start_end[1] = r_point[1];
665 return CV_BADFACTOR_ERR;
669 { /* if( l_point[0] > width ) */
671 l_point[0] = (float) width;
675 icvMultMatrixTVector3( F, l_point, epiline );
676 error = icvCrossLines( r_diagonal, epiline, r_point );
677 assert( error == CV_NO_ERR );
679 if( r_point[0] >= 0 && r_point[0] <= width )
682 l_start_end[0] = l_point[0];
683 l_start_end[1] = l_point[1];
685 r_start_end[0] = r_point[0];
686 r_start_end[1] = r_point[1];
689 return CV_BADFACTOR_ERR;
693 r_point[0] = (float) width;
694 r_point[1] = (float) height;
697 icvMultMatrixVector3( F, r_point, epiline );
698 error = icvCrossLines( l_diagonal, epiline, l_point );
699 assert( error == CV_NO_ERR );
701 if( l_point[0] >= 0 && l_point[0] <= width )
704 l_start_end[2] = l_point[0];
705 l_start_end[3] = l_point[1];
707 r_start_end[2] = r_point[0];
708 r_start_end[3] = r_point[1];
718 l_point[1] = (float) height;
721 icvMultMatrixTVector3( F, l_point, epiline );
722 error = icvCrossLines( r_diagonal, epiline, r_point );
723 assert( error == CV_NO_ERR );
725 if( r_point[0] >= 0 && r_point[0] <= width )
728 l_start_end[2] = l_point[0];
729 l_start_end[3] = l_point[1];
731 r_start_end[2] = r_point[0];
732 r_start_end[3] = r_point[1];
735 return CV_BADFACTOR_ERR;
739 { /* if( l_point[0] > width ) */
741 l_point[0] = (float) width;
745 icvMultMatrixTVector3( F, l_point, epiline );
746 error = icvCrossLines( r_diagonal, epiline, r_point );
747 assert( error == CV_NO_ERR );
749 if( r_point[0] >= 0 && r_point[0] <= width )
752 l_start_end[2] = l_point[0];
753 l_start_end[3] = l_point[1];
755 r_start_end[2] = r_point[0];
756 r_start_end[3] = r_point[1];
759 return CV_BADFACTOR_ERR;
765 } /* icvlGetStartEnd2 */
767 /*===========================================================================*/
769 icvGetStartEnd3( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
776 float l_point[3]={0,0,0}, r_point[3], epiline[3]={0,0,0};
777 CvStatus error = CV_OK;
781 width = imgSize.width - 1;
782 height = imgSize.height - 1;
784 l_diagonal[0] = (float) height / width;
788 r_diagonal[0] = (float) 1 / width;
789 r_diagonal[1] = (float) 1 / height;
796 icvMultMatrixVector3( F, r_point, epiline );
798 error = icvCrossLines( l_diagonal, epiline, l_point );
800 assert( error == CV_NO_ERR );
802 if( l_point[0] >= 0 && l_point[0] <= width )
805 l_start_end[0] = l_point[0];
806 l_start_end[1] = l_point[1];
808 r_start_end[0] = r_point[0];
809 r_start_end[1] = r_point[1];
819 l_point[1] = (float) height;
822 icvMultMatrixTVector3( F, l_point, epiline );
823 error = icvCrossLines( r_diagonal, epiline, r_point );
824 assert( error == CV_NO_ERR );
826 if( r_point[0] >= 0 && r_point[0] <= width )
829 l_start_end[0] = l_point[0];
830 l_start_end[1] = l_point[1];
832 r_start_end[0] = r_point[0];
833 r_start_end[1] = r_point[1];
836 return CV_BADFACTOR_ERR;
840 { /* if( l_point[0] > width ) */
842 l_point[0] = (float) width;
846 icvMultMatrixTVector3( F, l_point, epiline );
847 error = icvCrossLines( r_diagonal, epiline, r_point );
848 assert( error == CV_NO_ERR );
850 if( r_point[0] >= 0 && r_point[0] <= width )
853 l_start_end[0] = l_point[0];
854 l_start_end[1] = l_point[1];
856 r_start_end[0] = r_point[0];
857 r_start_end[1] = r_point[1];
860 return CV_BADFACTOR_ERR;
864 r_point[0] = (float) width;
865 r_point[1] = (float) height;
868 icvMultMatrixVector3( F, r_point, epiline );
869 error = icvCrossLines( l_diagonal, epiline, l_point );
870 assert( error == CV_NO_ERR );
872 if( l_point[0] >= 0 && l_point[0] <= width )
875 l_start_end[2] = l_point[0];
876 l_start_end[3] = l_point[1];
878 r_start_end[2] = r_point[0];
879 r_start_end[3] = r_point[1];
889 l_point[1] = (float) height;
892 icvMultMatrixTVector3( F, l_point, epiline );
894 error = icvCrossLines( r_diagonal, epiline, r_point );
896 assert( error == CV_NO_ERR );
898 if( r_point[0] >= 0 && r_point[0] <= width )
901 l_start_end[2] = l_point[0];
902 l_start_end[3] = l_point[1];
904 r_start_end[2] = r_point[0];
905 r_start_end[3] = r_point[1];
908 return CV_BADFACTOR_ERR;
912 { /* if( l_point[0] > width ) */
914 l_point[0] = (float) width;
918 icvMultMatrixTVector3( F, l_point, epiline );
920 error = icvCrossLines( r_diagonal, epiline, r_point );
922 assert( error == CV_NO_ERR );
924 if( r_point[0] >= 0 && r_point[0] <= width )
927 l_start_end[2] = l_point[0];
928 l_start_end[3] = l_point[1];
930 r_start_end[2] = r_point[0];
931 r_start_end[3] = r_point[1];
934 return CV_BADFACTOR_ERR;
940 } /* icvlGetStartEnd3 */
942 /*===========================================================================*/
944 icvGetStartEnd4( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
950 float l_point[3], r_point[3], epiline[3]={0,0,0};
955 width = imgSize.width - 1;
956 height = imgSize.height - 1;
958 l_diagonal[0] = (float) height / width;
962 r_diagonal[0] = (float) height / width;
970 icvMultMatrixVector3( F, r_point, epiline );
971 error = icvCrossLines( l_diagonal, epiline, l_point );
973 if( error != CV_NO_ERR )
976 if( l_point[0] >= 0 && l_point[0] <= width )
979 l_start_end[0] = l_point[0];
980 l_start_end[1] = l_point[1];
982 r_start_end[0] = r_point[0];
983 r_start_end[1] = r_point[1];
996 icvMultMatrixTVector3( F, l_point, epiline );
997 error = icvCrossLines( r_diagonal, epiline, r_point );
998 assert( error == CV_NO_ERR );
1000 if( r_point[0] >= 0 && r_point[0] <= width )
1003 l_start_end[0] = l_point[0];
1004 l_start_end[1] = l_point[1];
1006 r_start_end[0] = r_point[0];
1007 r_start_end[1] = r_point[1];
1010 return CV_BADFACTOR_ERR;
1014 { /* if( l_point[0] > width ) */
1016 l_point[0] = (float) width;
1017 l_point[1] = (float) height;
1020 icvMultMatrixTVector3( F, l_point, epiline );
1021 error = icvCrossLines( r_diagonal, epiline, r_point );
1022 assert( error == CV_NO_ERR );
1024 if( r_point[0] >= 0 && r_point[0] <= width )
1027 l_start_end[0] = l_point[0];
1028 l_start_end[1] = l_point[1];
1030 r_start_end[0] = r_point[0];
1031 r_start_end[1] = r_point[1];
1034 return CV_BADFACTOR_ERR;
1038 r_point[0] = (float) width;
1039 r_point[1] = (float) height;
1042 icvMultMatrixVector3( F, r_point, epiline );
1043 error = icvCrossLines( l_diagonal, epiline, l_point );
1044 assert( error == CV_NO_ERR );
1046 if( l_point[0] >= 0 && l_point[0] <= width )
1049 l_start_end[2] = l_point[0];
1050 l_start_end[3] = l_point[1];
1052 r_start_end[2] = r_point[0];
1053 r_start_end[3] = r_point[1];
1059 if( l_point[0] < 0 )
1066 icvMultMatrixTVector3( F, l_point, epiline );
1067 error = icvCrossLines( r_diagonal, epiline, r_point );
1068 assert( error == CV_NO_ERR );
1070 if( r_point[0] >= 0 && r_point[0] <= width )
1073 l_start_end[2] = l_point[0];
1074 l_start_end[3] = l_point[1];
1076 r_start_end[2] = r_point[0];
1077 r_start_end[3] = r_point[1];
1080 return CV_BADFACTOR_ERR;
1084 { /* if( l_point[0] > width ) */
1086 l_point[0] = (float) width;
1087 l_point[1] = (float) height;
1090 icvMultMatrixTVector3( F, l_point, epiline );
1091 error = icvCrossLines( r_diagonal, epiline, r_point );
1092 assert( error == CV_NO_ERR );
1094 if( r_point[0] >= 0 && r_point[0] <= width )
1097 l_start_end[2] = l_point[0];
1098 l_start_end[3] = l_point[1];
1100 r_start_end[2] = r_point[0];
1101 r_start_end[3] = r_point[1];
1104 return CV_BADFACTOR_ERR;
1110 } /* icvlGetStartEnd4 */
1112 /*===========================================================================*/
1114 icvBuildScanlineLeft( CvMatrix3 * matrix,
1116 int *scanlines_1, int *scanlines_2, float *l_start_end, int *numlines )
1124 CvStatus error = CV_OK;
1128 float epiline[3] = {0,};
1131 assert( l_start_end != 0 );
1133 a = fabs( l_start_end[2] - l_start_end[0] );
1134 b = fabs( l_start_end[3] - l_start_end[1] );
1135 prewarp_height = cvRound( MAX(a, b) );
1137 *numlines = prewarp_height;
1139 if( scanlines_1 == 0 && scanlines_2 == 0 )
1146 height = (float) prewarp_height;
1148 delta_x = (l_start_end[2] - l_start_end[0]) / height;
1150 l_start_end[0] += delta_x;
1151 l_start_end[2] -= delta_x;
1153 delta_x = (l_start_end[2] - l_start_end[0]) / height;
1154 delta_y = (l_start_end[3] - l_start_end[1]) / height;
1156 l_start_end[1] += delta_y;
1157 l_start_end[3] -= delta_y;
1159 delta_y = (l_start_end[3] - l_start_end[1]) / height;
1161 for( i = 0, offset = 0; i < height; i++, offset += 4 )
1164 l_point[0] = l_start_end[0] + i * delta_x;
1165 l_point[1] = l_start_end[1] + i * delta_y;
1167 icvMultMatrixTVector3( F, l_point, epiline );
1169 error = icvGetCrossEpilineFrame( imgSize, epiline,
1170 scanlines_2 + offset,
1171 scanlines_2 + offset + 1,
1172 scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
1176 assert( error == CV_NO_ERR );
1178 r_point[0] = -(float) (*(scanlines_2 + offset));
1179 r_point[1] = -(float) (*(scanlines_2 + offset + 1));
1182 icvMultMatrixVector3( F, r_point, epiline );
1184 error = icvGetCrossEpilineFrame( imgSize, epiline,
1185 scanlines_1 + offset,
1186 scanlines_1 + offset + 1,
1187 scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
1189 assert( error == CV_NO_ERR );
1192 *numlines = prewarp_height;
1196 } /*icvlBuildScanlineLeft */
1198 /*===========================================================================*/
1200 icvBuildScanlineRight( CvMatrix3 * matrix,
1202 int *scanlines_1, int *scanlines_2, float *r_start_end, int *numlines )
1210 CvStatus error = CV_OK;
1214 float epiline[3] = {0,};
1217 assert( r_start_end != 0 );
1219 a = fabs( r_start_end[2] - r_start_end[0] );
1220 b = fabs( r_start_end[3] - r_start_end[1] );
1221 prewarp_height = cvRound( MAX(a, b) );
1223 *numlines = prewarp_height;
1225 if( scanlines_1 == 0 && scanlines_2 == 0 )
1231 height = (float) prewarp_height;
1233 delta_x = (r_start_end[2] - r_start_end[0]) / height;
1235 r_start_end[0] += delta_x;
1236 r_start_end[2] -= delta_x;
1238 delta_x = (r_start_end[2] - r_start_end[0]) / height;
1239 delta_y = (r_start_end[3] - r_start_end[1]) / height;
1241 r_start_end[1] += delta_y;
1242 r_start_end[3] -= delta_y;
1244 delta_y = (r_start_end[3] - r_start_end[1]) / height;
1246 for( i = 0, offset = 0; i < height; i++, offset += 4 )
1249 r_point[0] = r_start_end[0] + i * delta_x;
1250 r_point[1] = r_start_end[1] + i * delta_y;
1252 icvMultMatrixVector3( F, r_point, epiline );
1254 error = icvGetCrossEpilineFrame( imgSize, epiline,
1255 scanlines_1 + offset,
1256 scanlines_1 + offset + 1,
1257 scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
1260 assert( error == CV_NO_ERR );
1262 l_point[0] = -(float) (*(scanlines_1 + offset));
1263 l_point[1] = -(float) (*(scanlines_1 + offset + 1));
1267 icvMultMatrixTVector3( F, l_point, epiline );
1268 error = icvGetCrossEpilineFrame( imgSize, epiline,
1269 scanlines_2 + offset,
1270 scanlines_2 + offset + 1,
1271 scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
1274 assert( error == CV_NO_ERR );
1277 *numlines = prewarp_height;
1281 } /*icvlBuildScanlineRight */
1283 /*===========================================================================*/
1284 #define Abs(x) ( (x)<0 ? -(x):(x) )
1285 #define Sgn(x) ( (x)<0 ? -1:1 ) /* Sgn(0) = 1 ! */
1288 icvBuildScanline( CvSize imgSize, float *epiline, float *kx, float *cx, float *ky, float *cy )
1290 float point[4][2], d;
1293 float width, height;
1295 if( REAL_ZERO( epiline[0] ) && REAL_ZERO( epiline[1] ))
1296 return CV_BADFACTOR_ERR;
1298 width = (float) imgSize.width - 1;
1299 height = (float) imgSize.height - 1;
1301 sign[0] = Sgn( epiline[2] );
1302 sign[1] = Sgn( epiline[0] * width + epiline[2] );
1303 sign[2] = Sgn( epiline[1] * height + epiline[2] );
1304 sign[3] = Sgn( epiline[0] * width + epiline[1] * height + epiline[2] );
1308 if( sign[0] * sign[1] < 0 )
1311 point[i][0] = -epiline[2] / epiline[0];
1316 if( sign[0] * sign[2] < 0 )
1320 point[i][1] = -epiline[2] / epiline[1];
1324 if( sign[1] * sign[3] < 0 )
1327 point[i][0] = width;
1328 point[i][1] = -(epiline[0] * width + epiline[2]) / epiline[1];
1332 if( sign[2] * sign[3] < 0 )
1335 point[i][0] = -(epiline[1] * height + epiline[2]) / epiline[0];
1336 point[i][1] = height;
1339 if( sign[0] == sign[1] && sign[0] == sign[2] && sign[0] == sign[3] )
1340 return CV_BADFACTOR_ERR;
1342 if( !kx && !ky && !cx && !cy )
1343 return CV_BADFACTOR_ERR;
1351 d = (float) MAX( Abs( *kx ), Abs( *ky ));
1360 if( (point[0][0] - point[1][0]) * epiline[1] +
1361 (point[1][1] - point[0][1]) * epiline[0] > 0 )
1378 } /* icvlBuildScanline */
1380 /*===========================================================================*/
1382 icvGetCoefficientStereo( CvMatrix3 * matrix,
1385 float *r_epipole, int *scanlines_1, int *scanlines_2, int *numlines )
1388 float width, height;
1389 float l_angle[2], r_angle[2];
1390 float l_radius, r_radius;
1391 float r_point[3], l_point[3];
1392 float l_epiline[3] = {0,};
1393 float r_epiline[3] = {0,};
1397 float radius1, radius2, radius3, radius4;
1399 float l_start_end[4], r_start_end[4];
1402 float Region[3][3][4] = {
1403 {{0.f, 0.f, 1.f, 1.f}, {0.f, 1.f, 1.f, 1.f}, {0.f, 1.f, 1.f, 0.f}},
1404 {{0.f, 0.f, 0.f, 1.f}, {2.f, 2.f, 2.f, 2.f}, {1.f, 1.f, 1.f, 0.f}},
1405 {{1.f, 0.f, 0.f, 1.f}, {1.f, 0.f, 0.f, 0.f}, {1.f, 1.f, 0.f, 0.f}}
1409 width = (float) imgSize.width - 1;
1410 height = (float) imgSize.height - 1;
1414 if( F->m[0][0] * F->m[1][1] - F->m[1][0] * F->m[0][1] > 0 )
1419 if( l_epipole[0] < 0 )
1421 else if( l_epipole[0] < width )
1426 if( l_epipole[1] < 0 )
1428 else if( l_epipole[1] < height )
1433 l_start_end[0] = Region[j][i][0];
1434 l_start_end[1] = Region[j][i][1];
1435 l_start_end[2] = Region[j][i][2];
1436 l_start_end[3] = Region[j][i][3];
1438 if( r_epipole[0] < 0 )
1440 else if( r_epipole[0] < width )
1445 if( r_epipole[1] < 0 )
1447 else if( r_epipole[1] < height )
1452 r_start_end[0] = Region[j][i][0];
1453 r_start_end[1] = Region[j][i][1];
1454 r_start_end[2] = Region[j][i][2];
1455 r_start_end[3] = Region[j][i][3];
1457 radius1 = l_epipole[0] * l_epipole[0] + (l_epipole[1] - height) * (l_epipole[1] - height);
1459 radius2 = (l_epipole[0] - width) * (l_epipole[0] - width) +
1460 (l_epipole[1] - height) * (l_epipole[1] - height);
1462 radius3 = l_epipole[0] * l_epipole[0] + l_epipole[1] * l_epipole[1];
1464 radius4 = (l_epipole[0] - width) * (l_epipole[0] - width) + l_epipole[1] * l_epipole[1];
1467 l_radius = (float) sqrt( (double)MAX( MAX( radius1, radius2 ), MAX( radius3, radius4 )));
1469 radius1 = r_epipole[0] * r_epipole[0] + (r_epipole[1] - height) * (r_epipole[1] - height);
1471 radius2 = (r_epipole[0] - width) * (r_epipole[0] - width) +
1472 (r_epipole[1] - height) * (r_epipole[1] - height);
1474 radius3 = r_epipole[0] * r_epipole[0] + r_epipole[1] * r_epipole[1];
1476 radius4 = (r_epipole[0] - width) * (r_epipole[0] - width) + r_epipole[1] * r_epipole[1];
1479 r_radius = (float) sqrt( (double)MAX( MAX( radius1, radius2 ), MAX( radius3, radius4 )));
1481 if( l_start_end[0] == 2 && r_start_end[0] == 2 )
1483 if( l_radius > r_radius )
1487 l_angle[1] = (float) CV_PI;
1489 error = icvBuildScanlineLeftStereo( imgSize,
1493 l_radius, scanlines_1, scanlines_2, numlines );
1501 r_angle[1] = (float) CV_PI;
1503 error = icvBuildScanlineRightStereo( imgSize,
1508 scanlines_1, scanlines_2, numlines );
1514 if( l_start_end[0] == 2 )
1517 r_angle[0] = (float) atan2( r_start_end[1] * height - r_epipole[1],
1518 r_start_end[0] * width - r_epipole[0] );
1519 r_angle[1] = (float) atan2( r_start_end[3] * height - r_epipole[1],
1520 r_start_end[2] * width - r_epipole[0] );
1522 if( r_angle[0] > r_angle[1] )
1523 r_angle[1] += (float) (CV_PI * 2);
1525 error = icvBuildScanlineRightStereo( imgSize,
1529 r_radius, scanlines_1, scanlines_2, numlines );
1534 if( r_start_end[0] == 2 )
1537 l_point[0] = l_start_end[0] * width;
1538 l_point[1] = l_start_end[1] * height;
1541 icvMultMatrixTVector3( F, l_point, r_epiline );
1543 l_angle[0] = (float) atan2( l_start_end[1] * height - l_epipole[1],
1544 l_start_end[0] * width - l_epipole[0] );
1545 l_angle[1] = (float) atan2( l_start_end[3] * height - l_epipole[1],
1546 l_start_end[2] * width - l_epipole[0] );
1548 if( l_angle[0] > l_angle[1] )
1549 l_angle[1] += (float) (CV_PI * 2);
1551 error = icvBuildScanlineLeftStereo( imgSize,
1555 l_radius, scanlines_1, scanlines_2, numlines );
1561 l_start_end[0] *= width;
1562 l_start_end[1] *= height;
1563 l_start_end[2] *= width;
1564 l_start_end[3] *= height;
1566 r_start_end[0] *= width;
1567 r_start_end[1] *= height;
1568 r_start_end[2] *= width;
1569 r_start_end[3] *= height;
1571 r_point[0] = r_start_end[0];
1572 r_point[1] = r_start_end[1];
1575 icvMultMatrixVector3( F, r_point, l_epiline );
1576 error = icvBuildScanline( imgSize, l_epiline, 0, &x, 0, &y );
1578 if( error == CV_NO_ERR )
1581 l_angle[0] = (float) atan2( y - l_epipole[1], x - l_epipole[0] );
1583 r_angle[0] = (float) atan2( r_point[1] - r_epipole[1], r_point[0] - r_epipole[0] );
1592 l_point[0] = l_start_end[0];
1593 l_point[1] = l_start_end[1];
1599 l_point[0] = l_start_end[2];
1600 l_point[1] = l_start_end[3];
1605 icvMultMatrixTVector3( F, l_point, r_epiline );
1606 error = icvBuildScanline( imgSize, r_epiline, 0, &x, 0, &y );
1608 if( error == CV_NO_ERR )
1611 r_angle[0] = (float) atan2( y - r_epipole[1], x - r_epipole[0] );
1613 l_angle[0] = (float) atan2( l_point[1] - l_epipole[1], l_point[0] - l_epipole[0] );
1617 return CV_BADFACTOR_ERR;
1620 r_point[0] = r_start_end[2];
1621 r_point[1] = r_start_end[3];
1624 icvMultMatrixVector3( F, r_point, l_epiline );
1625 error = icvBuildScanline( imgSize, l_epiline, 0, &x, 0, &y );
1627 if( error == CV_NO_ERR )
1630 l_angle[1] = (float) atan2( y - l_epipole[1], x - l_epipole[0] );
1632 r_angle[1] = (float) atan2( r_point[1] - r_epipole[1], r_point[0] - r_epipole[0] );
1641 l_point[0] = l_start_end[2];
1642 l_point[1] = l_start_end[3];
1648 l_point[0] = l_start_end[0];
1649 l_point[1] = l_start_end[1];
1654 icvMultMatrixTVector3( F, l_point, r_epiline );
1655 error = icvBuildScanline( imgSize, r_epiline, 0, &x, 0, &y );
1657 if( error == CV_NO_ERR )
1660 r_angle[1] = (float) atan2( y - r_epipole[1], x - r_epipole[0] );
1662 l_angle[1] = (float) atan2( l_point[1] - l_epipole[1], l_point[0] - l_epipole[0] );
1666 return CV_BADFACTOR_ERR;
1669 if( l_angle[0] > l_angle[1] )
1673 l_angle[0] = l_angle[1];
1677 if( l_angle[1] - l_angle[0] > CV_PI )
1681 l_angle[0] = l_angle[1];
1682 l_angle[1] = swap + (float) (CV_PI * 2);
1685 if( r_angle[0] > r_angle[1] )
1689 r_angle[0] = r_angle[1];
1693 if( r_angle[1] - r_angle[0] > CV_PI )
1697 r_angle[0] = r_angle[1];
1698 r_angle[1] = swap + (float) (CV_PI * 2);
1701 if( l_radius * (l_angle[1] - l_angle[0]) > r_radius * (r_angle[1] - r_angle[0]) )
1702 error = icvBuildScanlineLeftStereo( imgSize,
1706 l_radius, scanlines_1, scanlines_2, numlines );
1709 error = icvBuildScanlineRightStereo( imgSize,
1713 r_radius, scanlines_1, scanlines_2, numlines );
1718 } /* icvGetCoefficientStereo */
1720 /*===========================================================================*/
1722 icvBuildScanlineLeftStereo( CvSize imgSize,
1726 float l_radius, int *scanlines_1, int *scanlines_2, int *numlines )
1728 //int prewarp_width;
1736 float l_epiline[3] = {0,};
1737 float r_epiline[3] = {0,};
1738 CvStatus error = CV_OK;
1742 assert( l_angle != 0 && !REAL_ZERO( l_radius ));
1744 /*prewarp_width = (int) (sqrt( image_width * image_width +
1745 image_height * image_height ) + 1);*/
1747 prewarp_height = (int) (l_radius * (l_angle[1] - l_angle[0]));
1749 *numlines = prewarp_height;
1751 if( scanlines_1 == 0 && scanlines_2 == 0 )
1757 height = (float) prewarp_height;
1759 delta = (l_angle[1] - l_angle[0]) / height;
1761 l_angle[0] += delta;
1762 l_angle[1] -= delta;
1764 delta = (l_angle[1] - l_angle[0]) / height;
1766 for( i = 0, offset = 0; i < height; i++, offset += 4 )
1769 angle = l_angle[0] + i * delta;
1771 l_point[0] = l_epipole[0] + l_radius * (float) cos( angle );
1772 l_point[1] = l_epipole[1] + l_radius * (float) sin( angle );
1774 icvMultMatrixTVector3( F, l_point, r_epiline );
1776 error = icvGetCrossEpilineFrame( imgSize, r_epiline,
1777 scanlines_2 + offset,
1778 scanlines_2 + offset + 1,
1779 scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
1782 l_epiline[0] = l_point[1] - l_epipole[1];
1783 l_epiline[1] = l_epipole[0] - l_point[0];
1784 l_epiline[2] = l_point[0] * l_epipole[1] - l_point[1] * l_epipole[0];
1786 if( Sgn( l_epiline[0] * r_epiline[0] + l_epiline[1] * r_epiline[1] ) < 0 )
1789 l_epiline[0] = -l_epiline[0];
1790 l_epiline[1] = -l_epiline[1];
1791 l_epiline[2] = -l_epiline[2];
1794 error = icvGetCrossEpilineFrame( imgSize, l_epiline,
1795 scanlines_1 + offset,
1796 scanlines_1 + offset + 1,
1797 scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
1801 *numlines = prewarp_height;
1805 } /* icvlBuildScanlineLeftStereo */
1807 /*===========================================================================*/
1809 icvBuildScanlineRightStereo( CvSize imgSize,
1814 int *scanlines_1, int *scanlines_2, int *numlines )
1816 //int prewarp_width;
1824 float l_epiline[3] = {0,};
1825 float r_epiline[3] = {0,};
1826 CvStatus error = CV_OK;
1829 assert( r_angle != 0 && !REAL_ZERO( r_radius ));
1831 /*prewarp_width = (int) (sqrt( image_width * image_width +
1832 image_height * image_height ) + 1);*/
1834 prewarp_height = (int) (r_radius * (r_angle[1] - r_angle[0]));
1836 *numlines = prewarp_height;
1838 if( scanlines_1 == 0 && scanlines_2 == 0 )
1844 height = (float) prewarp_height;
1846 delta = (r_angle[1] - r_angle[0]) / height;
1848 r_angle[0] += delta;
1849 r_angle[1] -= delta;
1851 delta = (r_angle[1] - r_angle[0]) / height;
1853 for( i = 0, offset = 0; i < height; i++, offset += 4 )
1856 angle = r_angle[0] + i * delta;
1858 r_point[0] = r_epipole[0] + r_radius * (float) cos( angle );
1859 r_point[1] = r_epipole[1] + r_radius * (float) sin( angle );
1861 icvMultMatrixVector3( F, r_point, l_epiline );
1863 error = icvGetCrossEpilineFrame( imgSize, l_epiline,
1864 scanlines_1 + offset,
1865 scanlines_1 + offset + 1,
1866 scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
1868 assert( error == CV_NO_ERR );
1870 r_epiline[0] = r_point[1] - r_epipole[1];
1871 r_epiline[1] = r_epipole[0] - r_point[0];
1872 r_epiline[2] = r_point[0] * r_epipole[1] - r_point[1] * r_epipole[0];
1874 if( Sgn( l_epiline[0] * r_epiline[0] + l_epiline[1] * r_epiline[1] ) < 0 )
1877 r_epiline[0] = -r_epiline[0];
1878 r_epiline[1] = -r_epiline[1];
1879 r_epiline[2] = -r_epiline[2];
1882 error = icvGetCrossEpilineFrame( imgSize, r_epiline,
1883 scanlines_2 + offset,
1884 scanlines_2 + offset + 1,
1885 scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
1887 assert( error == CV_NO_ERR );
1890 *numlines = prewarp_height;
1894 } /* icvlBuildScanlineRightStereo */
1896 /*===========================================================================*/
1898 icvGetCrossEpilineFrame( CvSize imgSize, float *epiline, int *x1, int *y1, int *x2, int *y2 )
1903 float width, height;
1906 if( REAL_ZERO( epiline[0] ) && REAL_ZERO( epiline[1] ))
1907 return CV_BADFACTOR_ERR;
1909 width = (float) imgSize.width - 1;
1910 height = (float) imgSize.height - 1;
1912 tmpvalue = epiline[2];
1913 sign[0] = SIGN( tmpvalue );
1915 tmpvalue = epiline[0] * width + epiline[2];
1916 sign[1] = SIGN( tmpvalue );
1918 tmpvalue = epiline[1] * height + epiline[2];
1919 sign[2] = SIGN( tmpvalue );
1921 tmpvalue = epiline[0] * width + epiline[1] * height + epiline[2];
1922 sign[3] = SIGN( tmpvalue );
1925 for( tx = 0; tx < 2; tx++ )
1927 for( ty = 0; ty < 2; ty++ )
1930 if( sign[ty * 2 + tx] == 0 )
1933 point[i][0] = width * tx;
1934 point[i][1] = height * ty;
1941 if( sign[0] * sign[1] < 0 )
1943 point[i][0] = -epiline[2] / epiline[0];
1948 if( sign[0] * sign[2] < 0 )
1951 point[i][1] = -epiline[2] / epiline[1];
1955 if( sign[1] * sign[3] < 0 )
1957 point[i][0] = width;
1958 point[i][1] = -(epiline[0] * width + epiline[2]) / epiline[1];
1962 if( sign[2] * sign[3] < 0 )
1964 point[i][0] = -(epiline[1] * height + epiline[2]) / epiline[0];
1965 point[i][1] = height;
1968 if( sign[0] == sign[1] && sign[0] == sign[2] && sign[0] == sign[3] )
1969 return CV_BADFACTOR_ERR;
1971 if( (point[0][0] - point[1][0]) * epiline[1] +
1972 (point[1][1] - point[0][1]) * epiline[0] > 0 )
1974 *x1 = (int) point[0][0];
1975 *y1 = (int) point[0][1];
1976 *x2 = (int) point[1][0];
1977 *y2 = (int) point[1][1];
1981 *x1 = (int) point[1][0];
1982 *y1 = (int) point[1][1];
1983 *x2 = (int) point[0][0];
1984 *y2 = (int) point[0][1];
1988 } /* icvlGetCrossEpilineFrame */
1990 /*=====================================================================================*/
1993 cvMakeScanlines( const CvMatrix3* matrix, CvSize imgSize,
1994 int *scanlines_1, int *scanlines_2,
1995 int *lens_1, int *lens_2, int *numlines )
1997 IPPI_CALL( icvMakeScanlines( (CvMatrix3*)matrix, imgSize, scanlines_1,
1998 scanlines_2, lens_1, lens_2, numlines ));
2001 /*F///////////////////////////////////////////////////////////////////////////////////////
2002 // Name: cvDeleteMoire
2003 // Purpose: The functions
2010 cvMakeAlphaScanlines( int *scanlines_1,
2012 int *scanlines_a, int *lens, int numlines, float alpha )
2014 IPPI_CALL( icvMakeAlphaScanlines( scanlines_1, scanlines_2, scanlines_a,
2015 lens, numlines, alpha ));