Home | History | Annotate | Download | only in src
      1 /*M///////////////////////////////////////////////////////////////////////////////////////
      2 //
      3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
      4 //
      5 //  By downloading, copying, installing or using the software you agree to this license.
      6 //  If you do not agree to this license, do not download, install,
      7 //  copy or use the software.
      8 //
      9 //
     10 //                        Intel License Agreement
     11 //                For Open Source Computer Vision Library
     12 //
     13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
     14 // Third party copyrights are property of their respective owners.
     15 //
     16 // Redistribution and use in source and binary forms, with or without modification,
     17 // are permitted provided that the following conditions are met:
     18 //
     19 //   * Redistribution's of source code must retain the above copyright notice,
     20 //     this list of conditions and the following disclaimer.
     21 //
     22 //   * Redistribution's in binary form must reproduce the above copyright notice,
     23 //     this list of conditions and the following disclaimer in the documentation
     24 //     and/or other materials provided with the distribution.
     25 //
     26 //   * The name of Intel Corporation may not be used to endorse or promote products
     27 //     derived from this software without specific prior written permission.
     28 //
     29 // This software is provided by the copyright holders and contributors "as is" and
     30 // any express or implied warranties, including, but not limited to, the implied
     31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
     32 // In no event shall the Intel Corporation or contributors be liable for any direct,
     33 // indirect, incidental, special, exemplary, or consequential damages
     34 // (including, but not limited to, procurement of substitute goods or services;
     35 // loss of use, data, or profits; or business interruption) however caused
     36 // and on any theory of liability, whether in contract, strict liability,
     37 // or tort (including negligence or otherwise) arising in any way out of
     38 // the use of this software, even if advised of the possibility of such damage.
     39 //
     40 //M*/
     41 #include "_cvaux.h"
     42 #include "_cvvm.h"
     43 
     44 //#define REAL_ZERO(x) ( (x) < 1e-8 && (x) > -1e-8)
     45 
     46 static CvStatus
     47 icvGetNormalVector3( CvMatrix3 * Matrix, float *v )
     48 {
     49 /*  return vector v that is any 3-vector perpendicular
     50     to all the row vectors of Matrix */
     51 
     52     double *solutions = 0;
     53     double M[3 * 3];
     54     double B[3] = { 0.f, 0.f, 0.f };
     55     int i, j, res;
     56 
     57     if( Matrix == 0 || v == 0 )
     58         return CV_NULLPTR_ERR;
     59 
     60     for( i = 0; i < 3; i++ )
     61     {
     62         for( j = 0; j < 3; j++ )
     63             M[i * 3 + j] = (double) (Matrix->m[i][j]);
     64     }                           /* for */
     65 
     66     res = icvGaussMxN( M, B, 3, 3, &solutions );
     67 
     68     if( res == -1 )
     69         return CV_BADFACTOR_ERR;
     70 
     71     if( res > 0 && solutions )
     72     {
     73         v[0] = (float) solutions[0];
     74         v[1] = (float) solutions[1];
     75         v[2] = (float) solutions[2];
     76         res = 0;
     77     }
     78     else
     79         res = 1;
     80 
     81     if( solutions )
     82         cvFree( &solutions );
     83 
     84     if( res )
     85         return CV_BADFACTOR_ERR;
     86     else
     87         return CV_NO_ERR;
     88 
     89 }                               /* icvgetNormalVector3 */
     90 
     91 
     92 /*=====================================================================================*/
     93 
     94 static CvStatus
     95 icvMultMatrixVector3( CvMatrix3 * m, float *src, float *dst )
     96 {
     97     if( m == 0 || src == 0 || dst == 0 )
     98         return CV_NULLPTR_ERR;
     99 
    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];
    103 
    104     return CV_NO_ERR;
    105 
    106 }                               /* icvMultMatrixVector3 */
    107 
    108 
    109 /*=====================================================================================*/
    110 
    111 static CvStatus
    112 icvMultMatrixTVector3( CvMatrix3 * m, float *src, float *dst )
    113 {
    114     if( m == 0 || src == 0 || dst == 0 )
    115         return CV_NULLPTR_ERR;
    116 
    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];
    120 
    121     return CV_NO_ERR;
    122 
    123 }                               /* icvMultMatrixTVector3 */
    124 
    125 /*=====================================================================================*/
    126 
    127 static CvStatus
    128 icvCrossLines( float *line1, float *line2, float *cross_point )
    129 {
    130     float delta;
    131 
    132     if( line1 == 0 && line2 == 0 && cross_point == 0 )
    133         return CV_NULLPTR_ERR;
    134 
    135     delta = line1[0] * line2[1] - line1[1] * line2[0];
    136 
    137     if( REAL_ZERO( delta ))
    138         return CV_BADFACTOR_ERR;
    139 
    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;
    142     cross_point[2] = 1;
    143 
    144     return CV_NO_ERR;
    145 }                               /* icvCrossLines */
    146 
    147 
    148 
    149 /*======================================================================================*/
    150 
    151 static CvStatus
    152 icvMakeScanlines( CvMatrix3 * matrix,
    153                   CvSize imgSize,
    154                   int *scanlines_1, int *scanlines_2, int *lens_1, int *lens_2, int *numlines )
    155 {
    156 
    157     CvStatus error;
    158 
    159     error = icvGetCoefficient( matrix, imgSize, scanlines_2, scanlines_1, numlines );
    160 
    161     /* Make Length of scanlines */
    162 
    163     if( scanlines_1 == 0 && scanlines_2 == 0 )
    164         return error;
    165 
    166     icvMakeScanlinesLengths( scanlines_1, *numlines, lens_1 );
    167 
    168     icvMakeScanlinesLengths( scanlines_2, *numlines, lens_2 );
    169 
    170     matrix = matrix;
    171     return CV_NO_ERR;
    172 
    173 
    174 }                               /* icvMakeScanlines */
    175 
    176 
    177 /*======================================================================================*/
    178 
    179 CvStatus
    180 icvMakeScanlinesLengths( int *scanlines, int numlines, int *lens )
    181 {
    182     int index;
    183     int x1, y1, x2, y2, dx, dy;
    184     int curr;
    185 
    186     curr = 0;
    187 
    188     for( index = 0; index < numlines; index++ )
    189     {
    190 
    191         x1 = scanlines[curr++];
    192         y1 = scanlines[curr++];
    193         x2 = scanlines[curr++];
    194         y2 = scanlines[curr++];
    195 
    196         dx = abs( x1 - x2 ) + 1;
    197         dy = abs( y1 - y2 ) + 1;
    198 
    199         lens[index] = MAX( dx, dy );
    200 
    201     }
    202     return CV_NO_ERR;
    203 }
    204 
    205 /*======================================================================================*/
    206 
    207 static CvStatus
    208 icvMakeAlphaScanlines( int *scanlines_1,
    209                        int *scanlines_2,
    210                        int *scanlines_a, int *lens, int numlines, float alpha )
    211 {
    212     int index;
    213     int x1, y1, x2, y2;
    214     int curr;
    215     int dx, dy;
    216     int curr_len;
    217 
    218     curr = 0;
    219     curr_len = 0;
    220     for( index = 0; index < numlines; index++ )
    221     {
    222 
    223         x1 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
    224 
    225         scanlines_a[curr++] = x1;
    226 
    227         y1 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
    228 
    229         scanlines_a[curr++] = y1;
    230 
    231         x2 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
    232 
    233         scanlines_a[curr++] = x2;
    234 
    235         y2 = (int) (scanlines_1[curr] * alpha + scanlines_2[curr] * (1.0 - alpha));
    236 
    237         scanlines_a[curr++] = y2;
    238 
    239         dx = abs( x1 - x2 ) + 1;
    240         dy = abs( y1 - y2 ) + 1;
    241 
    242         lens[curr_len++] = MAX( dx, dy );
    243 
    244     }
    245 
    246     return CV_NO_ERR;
    247 }
    248 
    249 /*======================================================================================*/
    250 
    251 
    252 
    253 
    254 
    255 
    256 
    257 /* //////////////////////////////////////////////////////////////////////////////////// */
    258 
    259 CvStatus
    260 icvGetCoefficient( CvMatrix3 * matrix,
    261                    CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
    262 {
    263     float l_epipole[3];
    264     float r_epipole[3];
    265     CvMatrix3 *F;
    266     CvMatrix3 Ft;
    267     CvStatus error;
    268     int i, j;
    269 
    270     F = matrix;
    271 
    272     l_epipole[2] = -1;
    273     r_epipole[2] = -1;
    274 
    275     if( F == 0 )
    276     {
    277         error = icvGetCoefficientDefault( matrix,
    278                                           imgSize, scanlines_1, scanlines_2, numlines );
    279         return error;
    280     }
    281 
    282 
    283     for( i = 0; i < 3; i++ )
    284         for( j = 0; j < 3; j++ )
    285             Ft.m[i][j] = F->m[j][i];
    286 
    287 
    288     error = icvGetNormalVector3( &Ft, l_epipole );
    289     if( error == CV_NO_ERR && !REAL_ZERO( l_epipole[2] ) && !REAL_ZERO( l_epipole[2] - 1 ))
    290     {
    291 
    292         l_epipole[0] /= l_epipole[2];
    293         l_epipole[1] /= l_epipole[2];
    294         l_epipole[2] = 1;
    295     }                           /* if */
    296 
    297     error = icvGetNormalVector3( F, r_epipole );
    298     if( error == CV_NO_ERR && !REAL_ZERO( r_epipole[2] ) && !REAL_ZERO( r_epipole[2] - 1 ))
    299     {
    300 
    301         r_epipole[0] /= r_epipole[2];
    302         r_epipole[1] /= r_epipole[2];
    303         r_epipole[2] = 1;
    304     }                           /* if */
    305 
    306     if( REAL_ZERO( l_epipole[2] - 1 ) && REAL_ZERO( r_epipole[2] - 1 ))
    307     {
    308         error = icvGetCoefficientStereo( matrix,
    309                                          imgSize,
    310                                          l_epipole,
    311                                          r_epipole, scanlines_1, scanlines_2, numlines );
    312         if( error == CV_NO_ERR )
    313             return CV_NO_ERR;
    314     }
    315     else
    316     {
    317         if( REAL_ZERO( l_epipole[2] ) && REAL_ZERO( r_epipole[2] ))
    318         {
    319             error = icvGetCoefficientOrto( matrix,
    320                                            imgSize, scanlines_1, scanlines_2, numlines );
    321             if( error == CV_NO_ERR )
    322                 return CV_NO_ERR;
    323         }
    324     }
    325 
    326 
    327     error = icvGetCoefficientDefault( matrix, imgSize, scanlines_1, scanlines_2, numlines );
    328 
    329     return error;
    330 
    331 }                               /* icvlGetCoefficient */
    332 
    333 /*===========================================================================*/
    334 CvStatus
    335 icvGetCoefficientDefault( CvMatrix3 * matrix,
    336                           CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
    337 {
    338     int curr;
    339     int y;
    340 
    341     *numlines = imgSize.height;
    342 
    343     if( scanlines_1 == 0 && scanlines_2 == 0 )
    344         return CV_NO_ERR;
    345 
    346     curr = 0;
    347     for( y = 0; y < imgSize.height; y++ )
    348     {
    349         scanlines_1[curr] = 0;
    350         scanlines_1[curr + 1] = y;
    351         scanlines_1[curr + 2] = imgSize.width - 1;
    352         scanlines_1[curr + 3] = y;
    353 
    354         scanlines_2[curr] = 0;
    355         scanlines_2[curr + 1] = y;
    356         scanlines_2[curr + 2] = imgSize.width - 1;
    357         scanlines_2[curr + 3] = y;
    358 
    359         curr += 4;
    360     }
    361 
    362     matrix = matrix;
    363     return CV_NO_ERR;
    364 
    365 }                               /* icvlGetCoefficientDefault */
    366 
    367 /*===========================================================================*/
    368 CvStatus
    369 icvGetCoefficientOrto( CvMatrix3 * matrix,
    370                        CvSize imgSize, int *scanlines_1, int *scanlines_2, int *numlines )
    371 {
    372     float l_start_end[4], r_start_end[4];
    373     double a, b;
    374     CvStatus error;
    375     CvMatrix3 *F;
    376 
    377     F = matrix;
    378 
    379     if( F->m[0][2] * F->m[1][2] < 0 )
    380     {                           /* on left / */
    381 
    382         if( F->m[2][0] * F->m[2][1] < 0 )
    383         {                       /* on right / */
    384             error = icvGetStartEnd1( F, imgSize, l_start_end, r_start_end );
    385 
    386 
    387         }
    388         else
    389         {                       /* on right \ */
    390             error = icvGetStartEnd2( F, imgSize, l_start_end, r_start_end );
    391         }                       /* if */
    392 
    393     }
    394     else
    395     {                           /* on left \ */
    396 
    397         if( F->m[2][0] * F->m[2][1] < 0 )
    398         {                       /* on right / */
    399             error = icvGetStartEnd3( F, imgSize, l_start_end, r_start_end );
    400         }
    401         else
    402         {                       /* on right \ */
    403             error = icvGetStartEnd4( F, imgSize, l_start_end, r_start_end );
    404         }                       /* if */
    405     }                           /* if */
    406 
    407     if( error != CV_NO_ERR )
    408         return error;
    409 
    410     a = fabs( l_start_end[0] - l_start_end[2] );
    411     b = fabs( r_start_end[0] - r_start_end[2] );
    412     if( a > b )
    413     {
    414 
    415         error = icvBuildScanlineLeft( F,
    416                                       imgSize,
    417                                       scanlines_1, scanlines_2, l_start_end, numlines );
    418 
    419     }
    420     else
    421     {
    422 
    423         error = icvBuildScanlineRight( F,
    424                                        imgSize,
    425                                        scanlines_1, scanlines_2, r_start_end, numlines );
    426 
    427     }                           /* if */
    428 
    429     return error;
    430 
    431 }                               /* icvlGetCoefficientOrto */
    432 
    433 /*===========================================================================*/
    434 CvStatus
    435 icvGetStartEnd1( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
    436 {
    437 
    438     CvMatrix3 *F;
    439     int width, height;
    440     float l_diagonal[3];
    441     float r_diagonal[3];
    442     float l_point[3], r_point[3], epiline[3];
    443     CvStatus error = CV_OK;
    444 
    445     F = matrix;
    446     width = imgSize.width - 1;
    447     height = imgSize.height - 1;
    448 
    449     l_diagonal[0] = (float) 1 / width;
    450     l_diagonal[1] = (float) 1 / height;
    451     l_diagonal[2] = -1;
    452 
    453     r_diagonal[0] = (float) 1 / width;
    454     r_diagonal[1] = (float) 1 / height;
    455     r_diagonal[2] = -1;
    456 
    457     r_point[0] = (float) width;
    458     r_point[1] = 0;
    459     r_point[2] = 1;
    460 
    461     icvMultMatrixVector3( F, r_point, epiline );
    462     error = icvCrossLines( l_diagonal, epiline, l_point );
    463 
    464     assert( error == CV_NO_ERR );
    465 
    466     if( l_point[0] >= 0 && l_point[0] <= width )
    467     {
    468 
    469         l_start_end[0] = l_point[0];
    470         l_start_end[1] = l_point[1];
    471 
    472         r_start_end[0] = r_point[0];
    473         r_start_end[1] = r_point[1];
    474 
    475     }
    476     else
    477     {
    478 
    479         if( l_point[0] < 0 )
    480         {
    481 
    482             l_point[0] = 0;
    483             l_point[1] = (float) height;
    484             l_point[2] = 1;
    485 
    486             icvMultMatrixTVector3( F, l_point, epiline );
    487             error = icvCrossLines( r_diagonal, epiline, r_point );
    488             assert( error == CV_NO_ERR );
    489 
    490             if( r_point[0] >= 0 && r_point[0] <= width )
    491             {
    492                 l_start_end[0] = l_point[0];
    493                 l_start_end[1] = l_point[1];
    494 
    495                 r_start_end[0] = r_point[0];
    496                 r_start_end[1] = r_point[1];
    497             }
    498             else
    499                 return CV_BADFACTOR_ERR;
    500 
    501         }
    502         else
    503         {                       /* if( l_point[0] > width ) */
    504 
    505             l_point[0] = (float) width;
    506             l_point[1] = 0;
    507             l_point[2] = 1;
    508 
    509             icvMultMatrixTVector3( F, l_point, epiline );
    510             error = icvCrossLines( r_diagonal, epiline, r_point );
    511             assert( error == CV_NO_ERR );
    512 
    513             if( r_point[0] >= 0 && r_point[0] <= width )
    514             {
    515 
    516                 l_start_end[0] = l_point[0];
    517                 l_start_end[1] = l_point[1];
    518 
    519                 r_start_end[0] = r_point[0];
    520                 r_start_end[1] = r_point[1];
    521             }
    522             else
    523                 return CV_BADFACTOR_ERR;
    524 
    525         }                       /* if */
    526     }                           /* if */
    527 
    528     r_point[0] = 0;
    529     r_point[1] = (float) height;
    530     r_point[2] = 1;
    531 
    532     icvMultMatrixVector3( F, r_point, epiline );
    533     error = icvCrossLines( l_diagonal, epiline, l_point );
    534     assert( error == CV_NO_ERR );
    535 
    536     if( l_point[0] >= 0 && l_point[0] <= width )
    537     {
    538 
    539         l_start_end[2] = l_point[0];
    540         l_start_end[3] = l_point[1];
    541 
    542         r_start_end[2] = r_point[0];
    543         r_start_end[3] = r_point[1];
    544 
    545     }
    546     else
    547     {
    548 
    549         if( l_point[0] < 0 )
    550         {
    551 
    552             l_point[0] = 0;
    553             l_point[1] = (float) height;
    554             l_point[2] = 1;
    555 
    556             icvMultMatrixTVector3( F, l_point, epiline );
    557             error = icvCrossLines( r_diagonal, epiline, r_point );
    558             assert( error == CV_NO_ERR );
    559 
    560             if( r_point[0] >= 0 && r_point[0] <= width )
    561             {
    562 
    563                 l_start_end[2] = l_point[0];
    564                 l_start_end[3] = l_point[1];
    565 
    566                 r_start_end[2] = r_point[0];
    567                 r_start_end[3] = r_point[1];
    568             }
    569             else
    570                 return CV_BADFACTOR_ERR;
    571 
    572         }
    573         else
    574         {                       /* if( l_point[0] > width ) */
    575 
    576             l_point[0] = (float) width;
    577             l_point[1] = 0;
    578             l_point[2] = 1;
    579 
    580             icvMultMatrixTVector3( F, l_point, epiline );
    581             error = icvCrossLines( r_diagonal, epiline, r_point );
    582             assert( error == CV_NO_ERR );
    583 
    584             if( r_point[0] >= 0 && r_point[0] <= width )
    585             {
    586 
    587                 l_start_end[2] = l_point[0];
    588                 l_start_end[3] = l_point[1];
    589 
    590                 r_start_end[2] = r_point[0];
    591                 r_start_end[3] = r_point[1];
    592             }
    593             else
    594                 return CV_BADFACTOR_ERR;
    595         }                       /* if */
    596     }                           /* if */
    597 
    598     return error;
    599 
    600 }                               /* icvlGetStartEnd1 */
    601 
    602 /*===========================================================================*/
    603 CvStatus
    604 icvGetStartEnd2( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
    605 {
    606 
    607 
    608     CvMatrix3 *F;
    609     int width, height;
    610     float l_diagonal[3];
    611     float r_diagonal[3];
    612     float l_point[3], r_point[3], epiline[3];
    613     CvStatus error = CV_OK;
    614 
    615     F = matrix;
    616 
    617     width = imgSize.width - 1;
    618     height = imgSize.height - 1;
    619 
    620     l_diagonal[0] = (float) 1 / width;
    621     l_diagonal[1] = (float) 1 / height;
    622     l_diagonal[2] = -1;
    623 
    624     r_diagonal[0] = (float) height / width;
    625     r_diagonal[1] = -1;
    626     r_diagonal[2] = 0;
    627 
    628     r_point[0] = 0;
    629     r_point[1] = 0;
    630     r_point[2] = 1;
    631 
    632     icvMultMatrixVector3( F, r_point, epiline );
    633 
    634     error = icvCrossLines( l_diagonal, epiline, l_point );
    635 
    636     assert( error == CV_NO_ERR );
    637 
    638     if( l_point[0] >= 0 && l_point[0] <= width )
    639     {
    640 
    641         l_start_end[0] = l_point[0];
    642         l_start_end[1] = l_point[1];
    643 
    644         r_start_end[0] = r_point[0];
    645         r_start_end[1] = r_point[1];
    646 
    647     }
    648     else
    649     {
    650 
    651         if( l_point[0] < 0 )
    652         {
    653 
    654             l_point[0] = 0;
    655             l_point[1] = (float) height;
    656             l_point[2] = 1;
    657 
    658             icvMultMatrixTVector3( F, l_point, epiline );
    659             error = icvCrossLines( r_diagonal, epiline, r_point );
    660 
    661             assert( error == CV_NO_ERR );
    662 
    663             if( r_point[0] >= 0 && r_point[0] <= width )
    664             {
    665 
    666                 l_start_end[0] = l_point[0];
    667                 l_start_end[1] = l_point[1];
    668 
    669                 r_start_end[0] = r_point[0];
    670                 r_start_end[1] = r_point[1];
    671             }
    672             else
    673                 return CV_BADFACTOR_ERR;
    674 
    675         }
    676         else
    677         {                       /* if( l_point[0] > width ) */
    678 
    679             l_point[0] = (float) width;
    680             l_point[1] = 0;
    681             l_point[2] = 1;
    682 
    683             icvMultMatrixTVector3( F, l_point, epiline );
    684             error = icvCrossLines( r_diagonal, epiline, r_point );
    685             assert( error == CV_NO_ERR );
    686 
    687             if( r_point[0] >= 0 && r_point[0] <= width )
    688             {
    689 
    690                 l_start_end[0] = l_point[0];
    691                 l_start_end[1] = l_point[1];
    692 
    693                 r_start_end[0] = r_point[0];
    694                 r_start_end[1] = r_point[1];
    695             }
    696             else
    697                 return CV_BADFACTOR_ERR;
    698         }                       /* if */
    699     }                           /* if */
    700 
    701     r_point[0] = (float) width;
    702     r_point[1] = (float) height;
    703     r_point[2] = 1;
    704 
    705     icvMultMatrixVector3( F, r_point, epiline );
    706     error = icvCrossLines( l_diagonal, epiline, l_point );
    707     assert( error == CV_NO_ERR );
    708 
    709     if( l_point[0] >= 0 && l_point[0] <= width )
    710     {
    711 
    712         l_start_end[2] = l_point[0];
    713         l_start_end[3] = l_point[1];
    714 
    715         r_start_end[2] = r_point[0];
    716         r_start_end[3] = r_point[1];
    717 
    718     }
    719     else
    720     {
    721 
    722         if( l_point[0] < 0 )
    723         {
    724 
    725             l_point[0] = 0;
    726             l_point[1] = (float) height;
    727             l_point[2] = 1;
    728 
    729             icvMultMatrixTVector3( F, l_point, epiline );
    730             error = icvCrossLines( r_diagonal, epiline, r_point );
    731             assert( error == CV_NO_ERR );
    732 
    733             if( r_point[0] >= 0 && r_point[0] <= width )
    734             {
    735 
    736                 l_start_end[2] = l_point[0];
    737                 l_start_end[3] = l_point[1];
    738 
    739                 r_start_end[2] = r_point[0];
    740                 r_start_end[3] = r_point[1];
    741             }
    742             else
    743                 return CV_BADFACTOR_ERR;
    744 
    745         }
    746         else
    747         {                       /* if( l_point[0] > width ) */
    748 
    749             l_point[0] = (float) width;
    750             l_point[1] = 0;
    751             l_point[2] = 1;
    752 
    753             icvMultMatrixTVector3( F, l_point, epiline );
    754             error = icvCrossLines( r_diagonal, epiline, r_point );
    755             assert( error == CV_NO_ERR );
    756 
    757             if( r_point[0] >= 0 && r_point[0] <= width )
    758             {
    759 
    760                 l_start_end[2] = l_point[0];
    761                 l_start_end[3] = l_point[1];
    762 
    763                 r_start_end[2] = r_point[0];
    764                 r_start_end[3] = r_point[1];
    765             }
    766             else
    767                 return CV_BADFACTOR_ERR;
    768         }
    769     }                           /* if */
    770 
    771     return error;
    772 
    773 }                               /* icvlGetStartEnd2 */
    774 
    775 /*===========================================================================*/
    776 CvStatus
    777 icvGetStartEnd3( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
    778 {
    779 
    780     CvMatrix3 *F;
    781     int width, height;
    782     float l_diagonal[3];
    783     float r_diagonal[3];
    784     float l_point[3], r_point[3], epiline[3];
    785     CvStatus error = CV_OK;
    786 
    787     F = matrix;
    788 
    789     width = imgSize.width - 1;
    790     height = imgSize.height - 1;
    791 
    792     l_diagonal[0] = (float) height / width;
    793     l_diagonal[1] = -1;
    794     l_diagonal[2] = 0;
    795 
    796     r_diagonal[0] = (float) 1 / width;
    797     r_diagonal[1] = (float) 1 / height;
    798     r_diagonal[2] = -1;
    799 
    800     r_point[0] = 0;
    801     r_point[1] = 0;
    802     r_point[2] = 1;
    803 
    804     icvMultMatrixVector3( F, r_point, epiline );
    805 
    806     error = icvCrossLines( l_diagonal, epiline, l_point );
    807 
    808     assert( error == CV_NO_ERR );
    809 
    810     if( l_point[0] >= 0 && l_point[0] <= width )
    811     {
    812 
    813         l_start_end[0] = l_point[0];
    814         l_start_end[1] = l_point[1];
    815 
    816         r_start_end[0] = r_point[0];
    817         r_start_end[1] = r_point[1];
    818 
    819     }
    820     else
    821     {
    822 
    823         if( l_point[0] < 0 )
    824         {
    825 
    826             l_point[0] = 0;
    827             l_point[1] = (float) height;
    828             l_point[2] = 1;
    829 
    830             icvMultMatrixTVector3( F, l_point, epiline );
    831             error = icvCrossLines( r_diagonal, epiline, r_point );
    832             assert( error == CV_NO_ERR );
    833 
    834             if( r_point[0] >= 0 && r_point[0] <= width )
    835             {
    836 
    837                 l_start_end[0] = l_point[0];
    838                 l_start_end[1] = l_point[1];
    839 
    840                 r_start_end[0] = r_point[0];
    841                 r_start_end[1] = r_point[1];
    842             }
    843             else
    844                 return CV_BADFACTOR_ERR;
    845 
    846         }
    847         else
    848         {                       /* if( l_point[0] > width ) */
    849 
    850             l_point[0] = (float) width;
    851             l_point[1] = 0;
    852             l_point[2] = 1;
    853 
    854             icvMultMatrixTVector3( F, l_point, epiline );
    855             error = icvCrossLines( r_diagonal, epiline, r_point );
    856             assert( error == CV_NO_ERR );
    857 
    858             if( r_point[0] >= 0 && r_point[0] <= width )
    859             {
    860 
    861                 l_start_end[0] = l_point[0];
    862                 l_start_end[1] = l_point[1];
    863 
    864                 r_start_end[0] = r_point[0];
    865                 r_start_end[1] = r_point[1];
    866             }
    867             else
    868                 return CV_BADFACTOR_ERR;
    869         }                       /* if */
    870     }                           /* if */
    871 
    872     r_point[0] = (float) width;
    873     r_point[1] = (float) height;
    874     r_point[2] = 1;
    875 
    876     icvMultMatrixVector3( F, r_point, epiline );
    877     error = icvCrossLines( l_diagonal, epiline, l_point );
    878     assert( error == CV_NO_ERR );
    879 
    880     if( l_point[0] >= 0 && l_point[0] <= width )
    881     {
    882 
    883         l_start_end[2] = l_point[0];
    884         l_start_end[3] = l_point[1];
    885 
    886         r_start_end[2] = r_point[0];
    887         r_start_end[3] = r_point[1];
    888 
    889     }
    890     else
    891     {
    892 
    893         if( l_point[0] < 0 )
    894         {
    895 
    896             l_point[0] = 0;
    897             l_point[1] = (float) height;
    898             l_point[2] = 1;
    899 
    900             icvMultMatrixTVector3( F, l_point, epiline );
    901 
    902             error = icvCrossLines( r_diagonal, epiline, r_point );
    903 
    904             assert( error == CV_NO_ERR );
    905 
    906             if( r_point[0] >= 0 && r_point[0] <= width )
    907             {
    908 
    909                 l_start_end[2] = l_point[0];
    910                 l_start_end[3] = l_point[1];
    911 
    912                 r_start_end[2] = r_point[0];
    913                 r_start_end[3] = r_point[1];
    914             }
    915             else
    916                 return CV_BADFACTOR_ERR;
    917 
    918         }
    919         else
    920         {                       /* if( l_point[0] > width ) */
    921 
    922             l_point[0] = (float) width;
    923             l_point[1] = 0;
    924             l_point[2] = 1;
    925 
    926             icvMultMatrixTVector3( F, l_point, epiline );
    927 
    928             error = icvCrossLines( r_diagonal, epiline, r_point );
    929 
    930             assert( error == CV_NO_ERR );
    931 
    932             if( r_point[0] >= 0 && r_point[0] <= width )
    933             {
    934 
    935                 l_start_end[2] = l_point[0];
    936                 l_start_end[3] = l_point[1];
    937 
    938                 r_start_end[2] = r_point[0];
    939                 r_start_end[3] = r_point[1];
    940             }
    941             else
    942                 return CV_BADFACTOR_ERR;
    943         }                       /* if */
    944     }                           /* if */
    945 
    946     return error;
    947 
    948 }                               /* icvlGetStartEnd3 */
    949 
    950 /*===========================================================================*/
    951 CvStatus
    952 icvGetStartEnd4( CvMatrix3 * matrix, CvSize imgSize, float *l_start_end, float *r_start_end )
    953 {
    954     CvMatrix3 *F;
    955     int width, height;
    956     float l_diagonal[3];
    957     float r_diagonal[3];
    958     float l_point[3], r_point[3], epiline[3];
    959     CvStatus error;
    960 
    961     F = matrix;
    962 
    963     width = imgSize.width - 1;
    964     height = imgSize.height - 1;
    965 
    966     l_diagonal[0] = (float) height / width;
    967     l_diagonal[1] = -1;
    968     l_diagonal[2] = 0;
    969 
    970     r_diagonal[0] = (float) height / width;
    971     r_diagonal[1] = -1;
    972     r_diagonal[2] = 0;
    973 
    974     r_point[0] = 0;
    975     r_point[1] = 0;
    976     r_point[2] = 1;
    977 
    978     icvMultMatrixVector3( F, r_point, epiline );
    979     error = icvCrossLines( l_diagonal, epiline, l_point );
    980 
    981     if( error != CV_NO_ERR )
    982         return error;
    983 
    984     if( l_point[0] >= 0 && l_point[0] <= width )
    985     {
    986 
    987         l_start_end[0] = l_point[0];
    988         l_start_end[1] = l_point[1];
    989 
    990         r_start_end[0] = r_point[0];
    991         r_start_end[1] = r_point[1];
    992 
    993     }
    994     else
    995     {
    996 
    997         if( l_point[0] < 0 )
    998         {
    999 
   1000             l_point[0] = 0;
   1001             l_point[1] = 0;
   1002             l_point[2] = 1;
   1003 
   1004             icvMultMatrixTVector3( F, l_point, epiline );
   1005             error = icvCrossLines( r_diagonal, epiline, r_point );
   1006             assert( error == CV_NO_ERR );
   1007 
   1008             if( r_point[0] >= 0 && r_point[0] <= width )
   1009             {
   1010 
   1011                 l_start_end[0] = l_point[0];
   1012                 l_start_end[1] = l_point[1];
   1013 
   1014                 r_start_end[0] = r_point[0];
   1015                 r_start_end[1] = r_point[1];
   1016             }
   1017             else
   1018                 return CV_BADFACTOR_ERR;
   1019 
   1020         }
   1021         else
   1022         {                       /* if( l_point[0] > width ) */
   1023 
   1024             l_point[0] = (float) width;
   1025             l_point[1] = (float) height;
   1026             l_point[2] = 1;
   1027 
   1028             icvMultMatrixTVector3( F, l_point, epiline );
   1029             error = icvCrossLines( r_diagonal, epiline, r_point );
   1030             assert( error == CV_NO_ERR );
   1031 
   1032             if( r_point[0] >= 0 && r_point[0] <= width )
   1033             {
   1034 
   1035                 l_start_end[0] = l_point[0];
   1036                 l_start_end[1] = l_point[1];
   1037 
   1038                 r_start_end[0] = r_point[0];
   1039                 r_start_end[1] = r_point[1];
   1040             }
   1041             else
   1042                 return CV_BADFACTOR_ERR;
   1043         }                       /* if */
   1044     }                           /* if */
   1045 
   1046     r_point[0] = (float) width;
   1047     r_point[1] = (float) height;
   1048     r_point[2] = 1;
   1049 
   1050     icvMultMatrixVector3( F, r_point, epiline );
   1051     error = icvCrossLines( l_diagonal, epiline, l_point );
   1052     assert( error == CV_NO_ERR );
   1053 
   1054     if( l_point[0] >= 0 && l_point[0] <= width )
   1055     {
   1056 
   1057         l_start_end[2] = l_point[0];
   1058         l_start_end[3] = l_point[1];
   1059 
   1060         r_start_end[2] = r_point[0];
   1061         r_start_end[3] = r_point[1];
   1062 
   1063     }
   1064     else
   1065     {
   1066 
   1067         if( l_point[0] < 0 )
   1068         {
   1069 
   1070             l_point[0] = 0;
   1071             l_point[1] = 0;
   1072             l_point[2] = 1;
   1073 
   1074             icvMultMatrixTVector3( F, l_point, epiline );
   1075             error = icvCrossLines( r_diagonal, epiline, r_point );
   1076             assert( error == CV_NO_ERR );
   1077 
   1078             if( r_point[0] >= 0 && r_point[0] <= width )
   1079             {
   1080 
   1081                 l_start_end[2] = l_point[0];
   1082                 l_start_end[3] = l_point[1];
   1083 
   1084                 r_start_end[2] = r_point[0];
   1085                 r_start_end[3] = r_point[1];
   1086             }
   1087             else
   1088                 return CV_BADFACTOR_ERR;
   1089 
   1090         }
   1091         else
   1092         {                       /* if( l_point[0] > width ) */
   1093 
   1094             l_point[0] = (float) width;
   1095             l_point[1] = (float) height;
   1096             l_point[2] = 1;
   1097 
   1098             icvMultMatrixTVector3( F, l_point, epiline );
   1099             error = icvCrossLines( r_diagonal, epiline, r_point );
   1100             assert( error == CV_NO_ERR );
   1101 
   1102             if( r_point[0] >= 0 && r_point[0] <= width )
   1103             {
   1104 
   1105                 l_start_end[2] = l_point[0];
   1106                 l_start_end[3] = l_point[1];
   1107 
   1108                 r_start_end[2] = r_point[0];
   1109                 r_start_end[3] = r_point[1];
   1110             }
   1111             else
   1112                 return CV_BADFACTOR_ERR;
   1113         }                       /* if */
   1114     }                           /* if */
   1115 
   1116     return CV_NO_ERR;
   1117 
   1118 }                               /* icvlGetStartEnd4 */
   1119 
   1120 /*===========================================================================*/
   1121 CvStatus
   1122 icvBuildScanlineLeft( CvMatrix3 * matrix,
   1123                       CvSize imgSize,
   1124                       int *scanlines_1, int *scanlines_2, float *l_start_end, int *numlines )
   1125 {
   1126     int prewarp_height;
   1127     float l_point[3];
   1128     float r_point[3];
   1129     float height;
   1130     float delta_x;
   1131     float delta_y;
   1132     CvStatus error = CV_OK;
   1133     CvMatrix3 *F;
   1134     float i;
   1135     int offset;
   1136     float epiline[3];
   1137     double a, b;
   1138 
   1139     assert( l_start_end != 0 );
   1140 
   1141     a = fabs( l_start_end[2] - l_start_end[0] );
   1142     b = fabs( l_start_end[3] - l_start_end[1] );
   1143     prewarp_height = cvRound( MAX(a, b) );
   1144 
   1145     *numlines = prewarp_height;
   1146 
   1147     if( scanlines_1 == 0 && scanlines_2 == 0 )
   1148         return CV_NO_ERR;
   1149 
   1150     F = matrix;
   1151 
   1152 
   1153     l_point[2] = 1;
   1154     height = (float) prewarp_height;
   1155 
   1156     delta_x = (l_start_end[2] - l_start_end[0]) / height;
   1157 
   1158     l_start_end[0] += delta_x;
   1159     l_start_end[2] -= delta_x;
   1160 
   1161     delta_x = (l_start_end[2] - l_start_end[0]) / height;
   1162     delta_y = (l_start_end[3] - l_start_end[1]) / height;
   1163 
   1164     l_start_end[1] += delta_y;
   1165     l_start_end[3] -= delta_y;
   1166 
   1167     delta_y = (l_start_end[3] - l_start_end[1]) / height;
   1168 
   1169     for( i = 0, offset = 0; i < height; i++, offset += 4 )
   1170     {
   1171 
   1172         l_point[0] = l_start_end[0] + i * delta_x;
   1173         l_point[1] = l_start_end[1] + i * delta_y;
   1174 
   1175         icvMultMatrixTVector3( F, l_point, epiline );
   1176 
   1177         error = icvGetCrossEpilineFrame( imgSize, epiline,
   1178                                          scanlines_2 + offset,
   1179                                          scanlines_2 + offset + 1,
   1180                                          scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
   1181 
   1182 
   1183 
   1184         assert( error == CV_NO_ERR );
   1185 
   1186         r_point[0] = -(float) (*(scanlines_2 + offset));
   1187         r_point[1] = -(float) (*(scanlines_2 + offset + 1));
   1188         r_point[2] = -1;
   1189 
   1190         icvMultMatrixVector3( F, r_point, epiline );
   1191 
   1192         error = icvGetCrossEpilineFrame( imgSize, epiline,
   1193                                          scanlines_1 + offset,
   1194                                          scanlines_1 + offset + 1,
   1195                                          scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
   1196 
   1197         assert( error == CV_NO_ERR );
   1198     }                           /* for */
   1199 
   1200     *numlines = prewarp_height;
   1201 
   1202     return error;
   1203 
   1204 } /*icvlBuildScanlineLeft */
   1205 
   1206 /*===========================================================================*/
   1207 CvStatus
   1208 icvBuildScanlineRight( CvMatrix3 * matrix,
   1209                        CvSize imgSize,
   1210                        int *scanlines_1, int *scanlines_2, float *r_start_end, int *numlines )
   1211 {
   1212     int prewarp_height;
   1213     float l_point[3];
   1214     float r_point[3];
   1215     float height;
   1216     float delta_x;
   1217     float delta_y;
   1218     CvStatus error = CV_OK;
   1219     CvMatrix3 *F;
   1220     float i;
   1221     int offset;
   1222     float epiline[3];
   1223     double a, b;
   1224 
   1225     assert( r_start_end != 0 );
   1226 
   1227     a = fabs( r_start_end[2] - r_start_end[0] );
   1228     b = fabs( r_start_end[3] - r_start_end[1] );
   1229     prewarp_height = cvRound( MAX(a, b) );
   1230 
   1231     *numlines = prewarp_height;
   1232 
   1233     if( scanlines_1 == 0 && scanlines_2 == 0 )
   1234         return CV_NO_ERR;
   1235 
   1236     F = matrix;
   1237 
   1238     r_point[2] = 1;
   1239     height = (float) prewarp_height;
   1240 
   1241     delta_x = (r_start_end[2] - r_start_end[0]) / height;
   1242 
   1243     r_start_end[0] += delta_x;
   1244     r_start_end[2] -= delta_x;
   1245 
   1246     delta_x = (r_start_end[2] - r_start_end[0]) / height;
   1247     delta_y = (r_start_end[3] - r_start_end[1]) / height;
   1248 
   1249     r_start_end[1] += delta_y;
   1250     r_start_end[3] -= delta_y;
   1251 
   1252     delta_y = (r_start_end[3] - r_start_end[1]) / height;
   1253 
   1254     for( i = 0, offset = 0; i < height; i++, offset += 4 )
   1255     {
   1256 
   1257         r_point[0] = r_start_end[0] + i * delta_x;
   1258         r_point[1] = r_start_end[1] + i * delta_y;
   1259 
   1260         icvMultMatrixVector3( F, r_point, epiline );
   1261 
   1262         error = icvGetCrossEpilineFrame( imgSize, epiline,
   1263                                          scanlines_1 + offset,
   1264                                          scanlines_1 + offset + 1,
   1265                                          scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
   1266 
   1267 
   1268         assert( error == CV_NO_ERR );
   1269 
   1270         l_point[0] = -(float) (*(scanlines_1 + offset));
   1271         l_point[1] = -(float) (*(scanlines_1 + offset + 1));
   1272 
   1273         l_point[2] = -1;
   1274 
   1275         icvMultMatrixTVector3( F, l_point, epiline );
   1276         error = icvGetCrossEpilineFrame( imgSize, epiline,
   1277                                          scanlines_2 + offset,
   1278                                          scanlines_2 + offset + 1,
   1279                                          scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
   1280 
   1281 
   1282         assert( error == CV_NO_ERR );
   1283     }                           /* for */
   1284 
   1285     *numlines = prewarp_height;
   1286 
   1287     return error;
   1288 
   1289 } /*icvlBuildScanlineRight */
   1290 
   1291 /*===========================================================================*/
   1292 #define Abs(x)              ( (x)<0 ? -(x):(x) )
   1293 #define Sgn(x)              ( (x)<0 ? -1:1 )    /* Sgn(0) = 1 ! */
   1294 
   1295 static CvStatus
   1296 icvBuildScanline( CvSize imgSize, float *epiline, float *kx, float *cx, float *ky, float *cy )
   1297 {
   1298     float point[4][2], d;
   1299     int sign[4], i;
   1300 
   1301     float width, height;
   1302 
   1303     if( REAL_ZERO( epiline[0] ) && REAL_ZERO( epiline[1] ))
   1304         return CV_BADFACTOR_ERR;
   1305 
   1306     width = (float) imgSize.width - 1;
   1307     height = (float) imgSize.height - 1;
   1308 
   1309     sign[0] = Sgn( epiline[2] );
   1310     sign[1] = Sgn( epiline[0] * width + epiline[2] );
   1311     sign[2] = Sgn( epiline[1] * height + epiline[2] );
   1312     sign[3] = Sgn( epiline[0] * width + epiline[1] * height + epiline[2] );
   1313 
   1314     i = 0;
   1315 
   1316     if( sign[0] * sign[1] < 0 )
   1317     {
   1318 
   1319         point[i][0] = -epiline[2] / epiline[0];
   1320         point[i][1] = 0;
   1321         i++;
   1322     }                           /* if */
   1323 
   1324     if( sign[0] * sign[2] < 0 )
   1325     {
   1326 
   1327         point[i][0] = 0;
   1328         point[i][1] = -epiline[2] / epiline[1];
   1329         i++;
   1330     }                           /* if */
   1331 
   1332     if( sign[1] * sign[3] < 0 )
   1333     {
   1334 
   1335         point[i][0] = width;
   1336         point[i][1] = -(epiline[0] * width + epiline[2]) / epiline[1];
   1337         i++;
   1338     }                           /* if */
   1339 
   1340     if( sign[2] * sign[3] < 0 )
   1341     {
   1342 
   1343         point[i][0] = -(epiline[1] * height + epiline[2]) / epiline[0];
   1344         point[i][1] = height;
   1345     }                           /* if */
   1346 
   1347     if( sign[0] == sign[1] && sign[0] == sign[2] && sign[0] == sign[3] )
   1348         return CV_BADFACTOR_ERR;
   1349 
   1350     if( !kx && !ky && !cx && !cy )
   1351         return CV_BADFACTOR_ERR;
   1352 
   1353     if( kx && ky )
   1354     {
   1355 
   1356         *kx = -epiline[1];
   1357         *ky = epiline[0];
   1358 
   1359         d = (float) MAX( Abs( *kx ), Abs( *ky ));
   1360 
   1361         *kx /= d;
   1362         *ky /= d;
   1363     }                           /* if */
   1364 
   1365     if( cx && cy )
   1366     {
   1367 
   1368         if( (point[0][0] - point[1][0]) * epiline[1] +
   1369             (point[1][1] - point[0][1]) * epiline[0] > 0 )
   1370         {
   1371 
   1372             *cx = point[0][0];
   1373             *cy = point[0][1];
   1374 
   1375         }
   1376         else
   1377         {
   1378 
   1379             *cx = point[1][0];
   1380             *cy = point[1][1];
   1381         }                       /* if */
   1382     }                           /* if */
   1383 
   1384     return CV_NO_ERR;
   1385 
   1386 }                               /* icvlBuildScanline */
   1387 
   1388 /*===========================================================================*/
   1389 CvStatus
   1390 icvGetCoefficientStereo( CvMatrix3 * matrix,
   1391                          CvSize imgSize,
   1392                          float *l_epipole,
   1393                          float *r_epipole, int *scanlines_1, int *scanlines_2, int *numlines )
   1394 {
   1395     int i, j, turn;
   1396     float width, height;
   1397     float l_angle[2], r_angle[2];
   1398     float l_radius, r_radius;
   1399     float r_point[3], l_point[3];
   1400     float l_epiline[3], r_epiline[3], x, y;
   1401     float swap;
   1402 
   1403     float radius1, radius2, radius3, radius4;
   1404 
   1405     float l_start_end[4], r_start_end[4];
   1406     CvMatrix3 *F;
   1407     CvStatus error;
   1408     float Region[3][3][4] = {
   1409        {{0.f, 0.f, 1.f, 1.f}, {0.f, 1.f, 1.f, 1.f}, {0.f, 1.f, 1.f, 0.f}},
   1410         {{0.f, 0.f, 0.f, 1.f}, {2.f, 2.f, 2.f, 2.f}, {1.f, 1.f, 1.f, 0.f}},
   1411         {{1.f, 0.f, 0.f, 1.f}, {1.f, 0.f, 0.f, 0.f}, {1.f, 1.f, 0.f, 0.f}}
   1412     };
   1413 
   1414 
   1415     width = (float) imgSize.width - 1;
   1416     height = (float) imgSize.height - 1;
   1417 
   1418     F = matrix;
   1419 
   1420     if( F->m[0][0] * F->m[1][1] - F->m[1][0] * F->m[0][1] > 0 )
   1421         turn = 1;
   1422     else
   1423         turn = -1;
   1424 
   1425     if( l_epipole[0] < 0 )
   1426         i = 0;
   1427     else if( l_epipole[0] < width )
   1428         i = 1;
   1429     else
   1430         i = 2;
   1431 
   1432     if( l_epipole[1] < 0 )
   1433         j = 2;
   1434     else if( l_epipole[1] < height )
   1435         j = 1;
   1436     else
   1437         j = 0;
   1438 
   1439     l_start_end[0] = Region[j][i][0];
   1440     l_start_end[1] = Region[j][i][1];
   1441     l_start_end[2] = Region[j][i][2];
   1442     l_start_end[3] = Region[j][i][3];
   1443 
   1444     if( r_epipole[0] < 0 )
   1445         i = 0;
   1446     else if( r_epipole[0] < width )
   1447         i = 1;
   1448     else
   1449         i = 2;
   1450 
   1451     if( r_epipole[1] < 0 )
   1452         j = 2;
   1453     else if( r_epipole[1] < height )
   1454         j = 1;
   1455     else
   1456         j = 0;
   1457 
   1458     r_start_end[0] = Region[j][i][0];
   1459     r_start_end[1] = Region[j][i][1];
   1460     r_start_end[2] = Region[j][i][2];
   1461     r_start_end[3] = Region[j][i][3];
   1462 
   1463     radius1 = l_epipole[0] * l_epipole[0] + (l_epipole[1] - height) * (l_epipole[1] - height);
   1464 
   1465     radius2 = (l_epipole[0] - width) * (l_epipole[0] - width) +
   1466         (l_epipole[1] - height) * (l_epipole[1] - height);
   1467 
   1468     radius3 = l_epipole[0] * l_epipole[0] + l_epipole[1] * l_epipole[1];
   1469 
   1470     radius4 = (l_epipole[0] - width) * (l_epipole[0] - width) + l_epipole[1] * l_epipole[1];
   1471 
   1472 
   1473     l_radius = (float) sqrt( (double)MAX( MAX( radius1, radius2 ), MAX( radius3, radius4 )));
   1474 
   1475     radius1 = r_epipole[0] * r_epipole[0] + (r_epipole[1] - height) * (r_epipole[1] - height);
   1476 
   1477     radius2 = (r_epipole[0] - width) * (r_epipole[0] - width) +
   1478         (r_epipole[1] - height) * (r_epipole[1] - height);
   1479 
   1480     radius3 = r_epipole[0] * r_epipole[0] + r_epipole[1] * r_epipole[1];
   1481 
   1482     radius4 = (r_epipole[0] - width) * (r_epipole[0] - width) + r_epipole[1] * r_epipole[1];
   1483 
   1484 
   1485     r_radius = (float) sqrt( (double)MAX( MAX( radius1, radius2 ), MAX( radius3, radius4 )));
   1486 
   1487     if( l_start_end[0] == 2 && r_start_end[0] == 2 )
   1488 
   1489         if( l_radius > r_radius )
   1490         {
   1491 
   1492             l_angle[0] = 0.0f;
   1493             l_angle[1] = (float) CV_PI;
   1494 
   1495             error = icvBuildScanlineLeftStereo( imgSize,
   1496                                                 matrix,
   1497                                                 l_epipole,
   1498                                                 l_angle,
   1499                                                 l_radius, scanlines_1, scanlines_2, numlines );
   1500 
   1501             return error;
   1502 
   1503         }
   1504         else
   1505         {
   1506 
   1507             r_angle[0] = 0.0f;
   1508             r_angle[1] = (float) CV_PI;
   1509 
   1510             error = icvBuildScanlineRightStereo( imgSize,
   1511                                                  matrix,
   1512                                                  r_epipole,
   1513                                                  r_angle,
   1514                                                  r_radius,
   1515                                                  scanlines_1, scanlines_2, numlines );
   1516 
   1517             return error;
   1518         }                       /* if */
   1519 
   1520     if( l_start_end[0] == 2 )
   1521     {
   1522 
   1523         r_angle[0] = (float) atan2( r_start_end[1] * height - r_epipole[1],
   1524                                     r_start_end[0] * width - r_epipole[0] );
   1525         r_angle[1] = (float) atan2( r_start_end[3] * height - r_epipole[1],
   1526                                     r_start_end[2] * width - r_epipole[0] );
   1527 
   1528         if( r_angle[0] > r_angle[1] )
   1529             r_angle[1] += (float) (CV_PI * 2);
   1530 
   1531         error = icvBuildScanlineRightStereo( imgSize,
   1532                                              matrix,
   1533                                              r_epipole,
   1534                                              r_angle,
   1535                                              r_radius, scanlines_1, scanlines_2, numlines );
   1536 
   1537         return error;
   1538     }                           /* if */
   1539 
   1540     if( r_start_end[0] == 2 )
   1541     {
   1542 
   1543         l_point[0] = l_start_end[0] * width;
   1544         l_point[1] = l_start_end[1] * height;
   1545         l_point[2] = 1;
   1546 
   1547         icvMultMatrixTVector3( F, l_point, r_epiline );
   1548 
   1549         l_angle[0] = (float) atan2( l_start_end[1] * height - l_epipole[1],
   1550                                     l_start_end[0] * width - l_epipole[0] );
   1551         l_angle[1] = (float) atan2( l_start_end[3] * height - l_epipole[1],
   1552                                     l_start_end[2] * width - l_epipole[0] );
   1553 
   1554         if( l_angle[0] > l_angle[1] )
   1555             l_angle[1] += (float) (CV_PI * 2);
   1556 
   1557         error = icvBuildScanlineLeftStereo( imgSize,
   1558                                             matrix,
   1559                                             l_epipole,
   1560                                             l_angle,
   1561                                             l_radius, scanlines_1, scanlines_2, numlines );
   1562 
   1563         return error;
   1564 
   1565     }                           /* if */
   1566 
   1567     l_start_end[0] *= width;
   1568     l_start_end[1] *= height;
   1569     l_start_end[2] *= width;
   1570     l_start_end[3] *= height;
   1571 
   1572     r_start_end[0] *= width;
   1573     r_start_end[1] *= height;
   1574     r_start_end[2] *= width;
   1575     r_start_end[3] *= height;
   1576 
   1577     r_point[0] = r_start_end[0];
   1578     r_point[1] = r_start_end[1];
   1579     r_point[2] = 1;
   1580 
   1581     icvMultMatrixVector3( F, r_point, l_epiline );
   1582     error = icvBuildScanline( imgSize, l_epiline, 0, &x, 0, &y );
   1583 
   1584     if( error == CV_NO_ERR )
   1585     {
   1586 
   1587         l_angle[0] = (float) atan2( y - l_epipole[1], x - l_epipole[0] );
   1588 
   1589         r_angle[0] = (float) atan2( r_point[1] - r_epipole[1], r_point[0] - r_epipole[0] );
   1590 
   1591     }
   1592     else
   1593     {
   1594 
   1595         if( turn == 1 )
   1596         {
   1597 
   1598             l_point[0] = l_start_end[0];
   1599             l_point[1] = l_start_end[1];
   1600 
   1601         }
   1602         else
   1603         {
   1604 
   1605             l_point[0] = l_start_end[2];
   1606             l_point[1] = l_start_end[3];
   1607         }                       /* if */
   1608 
   1609         l_point[2] = 1;
   1610 
   1611         icvMultMatrixTVector3( F, l_point, r_epiline );
   1612         error = icvBuildScanline( imgSize, r_epiline, 0, &x, 0, &y );
   1613 
   1614         if( error == CV_NO_ERR )
   1615         {
   1616 
   1617             r_angle[0] = (float) atan2( y - r_epipole[1], x - r_epipole[0] );
   1618 
   1619             l_angle[0] = (float) atan2( l_point[1] - l_epipole[1], l_point[0] - l_epipole[0] );
   1620 
   1621         }
   1622         else
   1623             return CV_BADFACTOR_ERR;
   1624     }                           /* if */
   1625 
   1626     r_point[0] = r_start_end[2];
   1627     r_point[1] = r_start_end[3];
   1628     r_point[2] = 1;
   1629 
   1630     icvMultMatrixVector3( F, r_point, l_epiline );
   1631     error = icvBuildScanline( imgSize, l_epiline, 0, &x, 0, &y );
   1632 
   1633     if( error == CV_NO_ERR )
   1634     {
   1635 
   1636         l_angle[1] = (float) atan2( y - l_epipole[1], x - l_epipole[0] );
   1637 
   1638         r_angle[1] = (float) atan2( r_point[1] - r_epipole[1], r_point[0] - r_epipole[0] );
   1639 
   1640     }
   1641     else
   1642     {
   1643 
   1644         if( turn == 1 )
   1645         {
   1646 
   1647             l_point[0] = l_start_end[2];
   1648             l_point[1] = l_start_end[3];
   1649 
   1650         }
   1651         else
   1652         {
   1653 
   1654             l_point[0] = l_start_end[0];
   1655             l_point[1] = l_start_end[1];
   1656         }                       /* if */
   1657 
   1658         l_point[2] = 1;
   1659 
   1660         icvMultMatrixTVector3( F, l_point, r_epiline );
   1661         error = icvBuildScanline( imgSize, r_epiline, 0, &x, 0, &y );
   1662 
   1663         if( error == CV_NO_ERR )
   1664         {
   1665 
   1666             r_angle[1] = (float) atan2( y - r_epipole[1], x - r_epipole[0] );
   1667 
   1668             l_angle[1] = (float) atan2( l_point[1] - l_epipole[1], l_point[0] - l_epipole[0] );
   1669 
   1670         }
   1671         else
   1672             return CV_BADFACTOR_ERR;
   1673     }                           /* if */
   1674 
   1675     if( l_angle[0] > l_angle[1] )
   1676     {
   1677 
   1678         swap = l_angle[0];
   1679         l_angle[0] = l_angle[1];
   1680         l_angle[1] = swap;
   1681     }                           /* if */
   1682 
   1683     if( l_angle[1] - l_angle[0] > CV_PI )
   1684     {
   1685 
   1686         swap = l_angle[0];
   1687         l_angle[0] = l_angle[1];
   1688         l_angle[1] = swap + (float) (CV_PI * 2);
   1689     }                           /* if */
   1690 
   1691     if( r_angle[0] > r_angle[1] )
   1692     {
   1693 
   1694         swap = r_angle[0];
   1695         r_angle[0] = r_angle[1];
   1696         r_angle[1] = swap;
   1697     }                           /* if */
   1698 
   1699     if( r_angle[1] - r_angle[0] > CV_PI )
   1700     {
   1701 
   1702         swap = r_angle[0];
   1703         r_angle[0] = r_angle[1];
   1704         r_angle[1] = swap + (float) (CV_PI * 2);
   1705     }                           /* if */
   1706 
   1707     if( l_radius * (l_angle[1] - l_angle[0]) > r_radius * (r_angle[1] - r_angle[0]) )
   1708         error = icvBuildScanlineLeftStereo( imgSize,
   1709                                             matrix,
   1710                                             l_epipole,
   1711                                             l_angle,
   1712                                             l_radius, scanlines_1, scanlines_2, numlines );
   1713 
   1714     else
   1715         error = icvBuildScanlineRightStereo( imgSize,
   1716                                              matrix,
   1717                                              r_epipole,
   1718                                              r_angle,
   1719                                              r_radius, scanlines_1, scanlines_2, numlines );
   1720 
   1721 
   1722     return error;
   1723 
   1724 }                               /* icvGetCoefficientStereo */
   1725 
   1726 /*===========================================================================*/
   1727 CvStatus
   1728 icvBuildScanlineLeftStereo( CvSize imgSize,
   1729                             CvMatrix3 * matrix,
   1730                             float *l_epipole,
   1731                             float *l_angle,
   1732                             float l_radius, int *scanlines_1, int *scanlines_2, int *numlines )
   1733 {
   1734     //int prewarp_width;
   1735     int prewarp_height;
   1736     float i;
   1737     int offset;
   1738     float height;
   1739     float delta;
   1740     float angle;
   1741     float l_point[3];
   1742     float l_epiline[3];
   1743     float r_epiline[3];
   1744     CvStatus error = CV_OK;
   1745     CvMatrix3 *F;
   1746 
   1747 
   1748     assert( l_angle != 0 && !REAL_ZERO( l_radius ));
   1749 
   1750     /*prewarp_width = (int) (sqrt( image_width * image_width +
   1751                                  image_height * image_height ) + 1);*/
   1752 
   1753     prewarp_height = (int) (l_radius * (l_angle[1] - l_angle[0]));
   1754 
   1755     *numlines = prewarp_height;
   1756 
   1757     if( scanlines_1 == 0 && scanlines_2 == 0 )
   1758         return CV_NO_ERR;
   1759 
   1760     F = matrix;
   1761 
   1762     l_point[2] = 1;
   1763     height = (float) prewarp_height;
   1764 
   1765     delta = (l_angle[1] - l_angle[0]) / height;
   1766 
   1767     l_angle[0] += delta;
   1768     l_angle[1] -= delta;
   1769 
   1770     delta = (l_angle[1] - l_angle[0]) / height;
   1771 
   1772     for( i = 0, offset = 0; i < height; i++, offset += 4 )
   1773     {
   1774 
   1775         angle = l_angle[0] + i * delta;
   1776 
   1777         l_point[0] = l_epipole[0] + l_radius * (float) cos( angle );
   1778         l_point[1] = l_epipole[1] + l_radius * (float) sin( angle );
   1779 
   1780         icvMultMatrixTVector3( F, l_point, r_epiline );
   1781 
   1782         error = icvGetCrossEpilineFrame( imgSize, r_epiline,
   1783                                          scanlines_2 + offset,
   1784                                          scanlines_2 + offset + 1,
   1785                                          scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
   1786 
   1787 
   1788         l_epiline[0] = l_point[1] - l_epipole[1];
   1789         l_epiline[1] = l_epipole[0] - l_point[0];
   1790         l_epiline[2] = l_point[0] * l_epipole[1] - l_point[1] * l_epipole[0];
   1791 
   1792         if( Sgn( l_epiline[0] * r_epiline[0] + l_epiline[1] * r_epiline[1] ) < 0 )
   1793         {
   1794 
   1795             l_epiline[0] = -l_epiline[0];
   1796             l_epiline[1] = -l_epiline[1];
   1797             l_epiline[2] = -l_epiline[2];
   1798         }                       /* if */
   1799 
   1800         error = icvGetCrossEpilineFrame( imgSize, l_epiline,
   1801                                          scanlines_1 + offset,
   1802                                          scanlines_1 + offset + 1,
   1803                                          scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
   1804 
   1805     }                           /* for */
   1806 
   1807     *numlines = prewarp_height;
   1808 
   1809     return error;
   1810 
   1811 }                               /* icvlBuildScanlineLeftStereo */
   1812 
   1813 /*===========================================================================*/
   1814 CvStatus
   1815 icvBuildScanlineRightStereo( CvSize imgSize,
   1816                              CvMatrix3 * matrix,
   1817                              float *r_epipole,
   1818                              float *r_angle,
   1819                              float r_radius,
   1820                              int *scanlines_1, int *scanlines_2, int *numlines )
   1821 {
   1822     //int prewarp_width;
   1823     int prewarp_height;
   1824     float i;
   1825     int offset;
   1826     float height;
   1827     float delta;
   1828     float angle;
   1829     float r_point[3];
   1830     float l_epiline[3];
   1831     float r_epiline[3];
   1832     CvStatus error = CV_OK;
   1833     CvMatrix3 *F;
   1834 
   1835     assert( r_angle != 0 && !REAL_ZERO( r_radius ));
   1836 
   1837     /*prewarp_width = (int) (sqrt( image_width * image_width +
   1838                                  image_height * image_height ) + 1);*/
   1839 
   1840     prewarp_height = (int) (r_radius * (r_angle[1] - r_angle[0]));
   1841 
   1842     *numlines = prewarp_height;
   1843 
   1844     if( scanlines_1 == 0 && scanlines_2 == 0 )
   1845         return CV_NO_ERR;
   1846 
   1847     F = matrix;
   1848 
   1849     r_point[2] = 1;
   1850     height = (float) prewarp_height;
   1851 
   1852     delta = (r_angle[1] - r_angle[0]) / height;
   1853 
   1854     r_angle[0] += delta;
   1855     r_angle[1] -= delta;
   1856 
   1857     delta = (r_angle[1] - r_angle[0]) / height;
   1858 
   1859     for( i = 0, offset = 0; i < height; i++, offset += 4 )
   1860     {
   1861 
   1862         angle = r_angle[0] + i * delta;
   1863 
   1864         r_point[0] = r_epipole[0] + r_radius * (float) cos( angle );
   1865         r_point[1] = r_epipole[1] + r_radius * (float) sin( angle );
   1866 
   1867         icvMultMatrixVector3( F, r_point, l_epiline );
   1868 
   1869         error = icvGetCrossEpilineFrame( imgSize, l_epiline,
   1870                                          scanlines_1 + offset,
   1871                                          scanlines_1 + offset + 1,
   1872                                          scanlines_1 + offset + 2, scanlines_1 + offset + 3 );
   1873 
   1874         assert( error == CV_NO_ERR );
   1875 
   1876         r_epiline[0] = r_point[1] - r_epipole[1];
   1877         r_epiline[1] = r_epipole[0] - r_point[0];
   1878         r_epiline[2] = r_point[0] * r_epipole[1] - r_point[1] * r_epipole[0];
   1879 
   1880         if( Sgn( l_epiline[0] * r_epiline[0] + l_epiline[1] * r_epiline[1] ) < 0 )
   1881         {
   1882 
   1883             r_epiline[0] = -r_epiline[0];
   1884             r_epiline[1] = -r_epiline[1];
   1885             r_epiline[2] = -r_epiline[2];
   1886         }                       /* if */
   1887 
   1888         error = icvGetCrossEpilineFrame( imgSize, r_epiline,
   1889                                          scanlines_2 + offset,
   1890                                          scanlines_2 + offset + 1,
   1891                                          scanlines_2 + offset + 2, scanlines_2 + offset + 3 );
   1892 
   1893         assert( error == CV_NO_ERR );
   1894     }                           /* for */
   1895 
   1896     *numlines = prewarp_height;
   1897 
   1898     return error;
   1899 
   1900 }                               /* icvlBuildScanlineRightStereo */
   1901 
   1902 /*===========================================================================*/
   1903 CvStatus
   1904 icvGetCrossEpilineFrame( CvSize imgSize, float *epiline, int *x1, int *y1, int *x2, int *y2 )
   1905 {
   1906     int tx, ty;
   1907     float point[2][2];
   1908     int sign[4], i;
   1909     float width, height;
   1910     double tmpvalue;
   1911 
   1912     if( REAL_ZERO( epiline[0] ) && REAL_ZERO( epiline[1] ))
   1913         return CV_BADFACTOR_ERR;
   1914 
   1915     width = (float) imgSize.width - 1;
   1916     height = (float) imgSize.height - 1;
   1917 
   1918     tmpvalue = epiline[2];
   1919     sign[0] = SIGN( tmpvalue );
   1920 
   1921     tmpvalue = epiline[0] * width + epiline[2];
   1922     sign[1] = SIGN( tmpvalue );
   1923 
   1924     tmpvalue = epiline[1] * height + epiline[2];
   1925     sign[2] = SIGN( tmpvalue );
   1926 
   1927     tmpvalue = epiline[0] * width + epiline[1] * height + epiline[2];
   1928     sign[3] = SIGN( tmpvalue );
   1929 
   1930     i = 0;
   1931     for( tx = 0; tx < 2; tx++ )
   1932     {
   1933         for( ty = 0; ty < 2; ty++ )
   1934         {
   1935 
   1936             if( sign[ty * 2 + tx] == 0 )
   1937             {
   1938 
   1939                 point[i][0] = width * tx;
   1940                 point[i][1] = height * ty;
   1941                 i++;
   1942 
   1943             }                   /* if */
   1944         }                       /* for */
   1945     }                           /* for */
   1946 
   1947     if( sign[0] * sign[1] < 0 )
   1948     {
   1949         point[i][0] = -epiline[2] / epiline[0];
   1950         point[i][1] = 0;
   1951         i++;
   1952     }                           /* if */
   1953 
   1954     if( sign[0] * sign[2] < 0 )
   1955     {
   1956         point[i][0] = 0;
   1957         point[i][1] = -epiline[2] / epiline[1];
   1958         i++;
   1959     }                           /* if */
   1960 
   1961     if( sign[1] * sign[3] < 0 )
   1962     {
   1963         point[i][0] = width;
   1964         point[i][1] = -(epiline[0] * width + epiline[2]) / epiline[1];
   1965         i++;
   1966     }                           /* if */
   1967 
   1968     if( sign[2] * sign[3] < 0 )
   1969     {
   1970         point[i][0] = -(epiline[1] * height + epiline[2]) / epiline[0];
   1971         point[i][1] = height;
   1972     }                           /* if */
   1973 
   1974     if( sign[0] == sign[1] && sign[0] == sign[2] && sign[0] == sign[3] )
   1975         return CV_BADFACTOR_ERR;
   1976 
   1977     if( (point[0][0] - point[1][0]) * epiline[1] +
   1978         (point[1][1] - point[0][1]) * epiline[0] > 0 )
   1979     {
   1980         *x1 = (int) point[0][0];
   1981         *y1 = (int) point[0][1];
   1982         *x2 = (int) point[1][0];
   1983         *y2 = (int) point[1][1];
   1984     }
   1985     else
   1986     {
   1987         *x1 = (int) point[1][0];
   1988         *y1 = (int) point[1][1];
   1989         *x2 = (int) point[0][0];
   1990         *y2 = (int) point[0][1];
   1991     }                           /* if */
   1992 
   1993     return CV_NO_ERR;
   1994 }                               /* icvlGetCrossEpilineFrame */
   1995 
   1996 /*=====================================================================================*/
   1997 
   1998 CV_IMPL void
   1999 cvMakeScanlines( const CvMatrix3* matrix, CvSize imgSize,
   2000                  int *scanlines_1, int *scanlines_2,
   2001                  int *lens_1, int *lens_2, int *numlines )
   2002 {
   2003     CV_FUNCNAME( "cvMakeScanlines" );
   2004 
   2005     __BEGIN__;
   2006 
   2007     IPPI_CALL( icvMakeScanlines( (CvMatrix3*)matrix, imgSize, scanlines_1,
   2008                                  scanlines_2, lens_1, lens_2, numlines ));
   2009     __END__;
   2010 }
   2011 
   2012 /*F///////////////////////////////////////////////////////////////////////////////////////
   2013 //    Name: cvDeleteMoire
   2014 //    Purpose: The functions
   2015 //    Context:
   2016 //    Parameters:
   2017 //
   2018 //    Notes:
   2019 //F*/
   2020 CV_IMPL void
   2021 cvMakeAlphaScanlines( int *scanlines_1,
   2022                       int *scanlines_2,
   2023                       int *scanlines_a, int *lens, int numlines, float alpha )
   2024 {
   2025     CV_FUNCNAME( "cvMakeAlphaScanlines" );
   2026 
   2027     __BEGIN__;
   2028 
   2029     IPPI_CALL( icvMakeAlphaScanlines( scanlines_1, scanlines_2, scanlines_a,
   2030                                       lens, numlines, alpha ));
   2031 
   2032     __END__;
   2033 }
   2034