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