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 42 #include "_cvaux.h" 43 #include <stdio.h> 44 45 #undef quad 46 47 #if _MSC_VER >= 1200 48 #pragma warning( disable: 4701 ) 49 #endif 50 51 CvCalibFilter::CvCalibFilter() 52 { 53 /* etalon data */ 54 etalonType = CV_CALIB_ETALON_USER; 55 etalonParamCount = 0; 56 etalonParams = 0; 57 etalonPointCount = 0; 58 etalonPoints = 0; 59 60 /* camera data */ 61 cameraCount = 1; 62 63 memset( points, 0, sizeof(points)); 64 memset( undistMap, 0, sizeof(undistMap)); 65 undistImg = 0; 66 memset( latestCounts, 0, sizeof(latestCounts)); 67 memset( latestPoints, 0, sizeof(latestPoints)); 68 memset( &stereo, 0, sizeof(stereo) ); 69 maxPoints = 0; 70 framesTotal = 15; 71 framesAccepted = 0; 72 isCalibrated = false; 73 74 imgSize = cvSize(0,0); 75 grayImg = 0; 76 tempImg = 0; 77 storage = 0; 78 79 memset( rectMap, 0, sizeof(rectMap)); 80 } 81 82 83 CvCalibFilter::~CvCalibFilter() 84 { 85 SetCameraCount(0); 86 cvFree( &etalonParams ); 87 cvFree( &etalonPoints ); 88 cvReleaseMat( &grayImg ); 89 cvReleaseMat( &tempImg ); 90 cvReleaseMat( &undistImg ); 91 cvReleaseMemStorage( &storage ); 92 } 93 94 95 bool CvCalibFilter::SetEtalon( CvCalibEtalonType type, double* params, 96 int pointCount, CvPoint2D32f* points ) 97 { 98 int i, arrSize; 99 100 Stop(); 101 102 for( i = 0; i < MAX_CAMERAS; i++ ) 103 cvFree( latestPoints + i ); 104 105 if( type == CV_CALIB_ETALON_USER || type != etalonType ) 106 { 107 cvFree( &etalonParams ); 108 } 109 110 etalonType = type; 111 112 switch( etalonType ) 113 { 114 case CV_CALIB_ETALON_CHESSBOARD: 115 etalonParamCount = 3; 116 if( !params || cvRound(params[0]) != params[0] || params[0] < 3 || 117 cvRound(params[1]) != params[1] || params[1] < 3 || params[2] <= 0 ) 118 { 119 assert(0); 120 return false; 121 } 122 123 pointCount = cvRound((params[0] - 1)*(params[1] - 1)); 124 break; 125 126 case CV_CALIB_ETALON_USER: 127 etalonParamCount = 0; 128 129 if( !points || pointCount < 4 ) 130 { 131 assert(0); 132 return false; 133 } 134 break; 135 136 default: 137 assert(0); 138 return false; 139 } 140 141 if( etalonParamCount > 0 ) 142 { 143 arrSize = etalonParamCount * sizeof(etalonParams[0]); 144 etalonParams = (double*)cvAlloc( arrSize ); 145 } 146 147 arrSize = pointCount * sizeof(etalonPoints[0]); 148 149 if( etalonPointCount != pointCount ) 150 { 151 cvFree( &etalonPoints ); 152 etalonPointCount = pointCount; 153 etalonPoints = (CvPoint2D32f*)cvAlloc( arrSize ); 154 } 155 156 switch( etalonType ) 157 { 158 case CV_CALIB_ETALON_CHESSBOARD: 159 { 160 int etalonWidth = cvRound( params[0] ) - 1; 161 int etalonHeight = cvRound( params[1] ) - 1; 162 int x, y, k = 0; 163 164 etalonParams[0] = etalonWidth; 165 etalonParams[1] = etalonHeight; 166 etalonParams[2] = params[2]; 167 168 for( y = 0; y < etalonHeight; y++ ) 169 for( x = 0; x < etalonWidth; x++ ) 170 { 171 etalonPoints[k++] = cvPoint2D32f( (etalonWidth - 1 - x)*params[2], 172 y*params[2] ); 173 } 174 } 175 break; 176 177 case CV_CALIB_ETALON_USER: 178 memcpy( etalonParams, params, arrSize ); 179 memcpy( etalonPoints, points, arrSize ); 180 break; 181 182 default: 183 assert(0); 184 return false; 185 } 186 187 return true; 188 } 189 190 191 CvCalibEtalonType 192 CvCalibFilter::GetEtalon( int* paramCount, const double** params, 193 int* pointCount, const CvPoint2D32f** points ) const 194 { 195 if( paramCount ) 196 *paramCount = etalonParamCount; 197 198 if( params ) 199 *params = etalonParams; 200 201 if( pointCount ) 202 *pointCount = etalonPointCount; 203 204 if( points ) 205 *points = etalonPoints; 206 207 return etalonType; 208 } 209 210 211 void CvCalibFilter::SetCameraCount( int count ) 212 { 213 Stop(); 214 215 if( count != cameraCount ) 216 { 217 for( int i = 0; i < cameraCount; i++ ) 218 { 219 cvFree( points + i ); 220 cvFree( latestPoints + i ); 221 cvReleaseMat( &undistMap[i][0] ); 222 cvReleaseMat( &undistMap[i][1] ); 223 cvReleaseMat( &rectMap[i][0] ); 224 cvReleaseMat( &rectMap[i][1] ); 225 } 226 227 memset( latestCounts, 0, sizeof(latestPoints) ); 228 maxPoints = 0; 229 cameraCount = count; 230 } 231 } 232 233 234 bool CvCalibFilter::SetFrames( int frames ) 235 { 236 if( frames < 5 ) 237 { 238 assert(0); 239 return false; 240 } 241 242 framesTotal = frames; 243 return true; 244 } 245 246 247 void CvCalibFilter::Stop( bool calibrate ) 248 { 249 int i, j; 250 isCalibrated = false; 251 252 // deallocate undistortion maps 253 for( i = 0; i < cameraCount; i++ ) 254 { 255 cvReleaseMat( &undistMap[i][0] ); 256 cvReleaseMat( &undistMap[i][1] ); 257 cvReleaseMat( &rectMap[i][0] ); 258 cvReleaseMat( &rectMap[i][1] ); 259 } 260 261 if( calibrate && framesAccepted > 0 ) 262 { 263 int n = framesAccepted; 264 CvPoint3D32f* buffer = 265 (CvPoint3D32f*)cvAlloc( n * etalonPointCount * sizeof(buffer[0])); 266 CvMat mat; 267 float* rotMatr = (float*)cvAlloc( n * 9 * sizeof(rotMatr[0])); 268 float* transVect = (float*)cvAlloc( n * 3 * sizeof(transVect[0])); 269 int* counts = (int*)cvAlloc( n * sizeof(counts[0])); 270 271 cvInitMatHeader( &mat, 1, sizeof(CvCamera)/sizeof(float), CV_32FC1, 0 ); 272 memset( cameraParams, 0, cameraCount * sizeof(cameraParams[0])); 273 274 for( i = 0; i < framesAccepted; i++ ) 275 { 276 counts[i] = etalonPointCount; 277 for( j = 0; j < etalonPointCount; j++ ) 278 buffer[i * etalonPointCount + j] = cvPoint3D32f( etalonPoints[j].x, 279 etalonPoints[j].y, 0 ); 280 } 281 282 for( i = 0; i < cameraCount; i++ ) 283 { 284 cvCalibrateCamera( framesAccepted, counts, 285 imgSize, points[i], buffer, 286 cameraParams[i].distortion, 287 cameraParams[i].matrix, 288 transVect, rotMatr, 0 ); 289 290 cameraParams[i].imgSize[0] = (float)imgSize.width; 291 cameraParams[i].imgSize[1] = (float)imgSize.height; 292 293 // cameraParams[i].focalLength[0] = cameraParams[i].matrix[0]; 294 // cameraParams[i].focalLength[1] = cameraParams[i].matrix[4]; 295 296 // cameraParams[i].principalPoint[0] = cameraParams[i].matrix[2]; 297 // cameraParams[i].principalPoint[1] = cameraParams[i].matrix[5]; 298 299 memcpy( cameraParams[i].rotMatr, rotMatr, 9 * sizeof(rotMatr[0])); 300 memcpy( cameraParams[i].transVect, transVect, 3 * sizeof(transVect[0])); 301 302 mat.data.ptr = (uchar*)(cameraParams + i); 303 304 /* check resultant camera parameters: if there are some INF's or NAN's, 305 stop and reset results */ 306 if( !cvCheckArr( &mat, CV_CHECK_RANGE | CV_CHECK_QUIET, -10000, 10000 )) 307 break; 308 } 309 310 311 312 isCalibrated = i == cameraCount; 313 314 {/* calibrate stereo cameras */ 315 if( cameraCount == 2 ) 316 { 317 stereo.camera[0] = &cameraParams[0]; 318 stereo.camera[1] = &cameraParams[1]; 319 320 icvStereoCalibration( framesAccepted, counts, 321 imgSize, 322 points[0],points[1], 323 buffer, 324 &stereo); 325 326 for( i = 0; i < 9; i++ ) 327 { 328 stereo.fundMatr[i] = stereo.fundMatr[i]; 329 } 330 331 } 332 333 } 334 335 cvFree( &buffer ); 336 cvFree( &counts ); 337 cvFree( &rotMatr ); 338 cvFree( &transVect ); 339 } 340 341 framesAccepted = 0; 342 } 343 344 345 bool CvCalibFilter::FindEtalon( IplImage** imgs ) 346 { 347 return FindEtalon( (CvMat**)imgs ); 348 } 349 350 351 bool CvCalibFilter::FindEtalon( CvMat** mats ) 352 { 353 bool result = true; 354 355 if( !mats || etalonPointCount == 0 ) 356 { 357 assert(0); 358 result = false; 359 } 360 361 if( result ) 362 { 363 int i, tempPointCount0 = etalonPointCount*2; 364 365 for( i = 0; i < cameraCount; i++ ) 366 { 367 if( !latestPoints[i] ) 368 latestPoints[i] = (CvPoint2D32f*) 369 cvAlloc( tempPointCount0*2*sizeof(latestPoints[0])); 370 } 371 372 for( i = 0; i < cameraCount; i++ ) 373 { 374 CvSize size; 375 int tempPointCount = tempPointCount0; 376 bool found = false; 377 378 if( !CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i])) 379 { 380 assert(0); 381 break; 382 } 383 384 size = cvGetSize(mats[i]); 385 386 if( size.width != imgSize.width || size.height != imgSize.height ) 387 { 388 imgSize = size; 389 } 390 391 if( !grayImg || grayImg->width != imgSize.width || 392 grayImg->height != imgSize.height ) 393 { 394 cvReleaseMat( &grayImg ); 395 cvReleaseMat( &tempImg ); 396 grayImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); 397 tempImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); 398 } 399 400 if( !storage ) 401 storage = cvCreateMemStorage(); 402 403 switch( etalonType ) 404 { 405 case CV_CALIB_ETALON_CHESSBOARD: 406 if( CV_MAT_CN(cvGetElemType(mats[i])) == 1 ) 407 cvCopy( mats[i], grayImg ); 408 else 409 cvCvtColor( mats[i], grayImg, CV_BGR2GRAY ); 410 found = cvFindChessBoardCornerGuesses( grayImg, tempImg, storage, 411 cvSize( cvRound(etalonParams[0]), 412 cvRound(etalonParams[1])), 413 latestPoints[i], &tempPointCount ) != 0; 414 if( found ) 415 cvFindCornerSubPix( grayImg, latestPoints[i], tempPointCount, 416 cvSize(5,5), cvSize(-1,-1), 417 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)); 418 break; 419 default: 420 assert(0); 421 result = false; 422 break; 423 } 424 425 latestCounts[i] = found ? tempPointCount : -tempPointCount; 426 result = result && found; 427 } 428 } 429 430 if( storage ) 431 cvClearMemStorage( storage ); 432 433 return result; 434 } 435 436 437 bool CvCalibFilter::Push( const CvPoint2D32f** pts ) 438 { 439 bool result = true; 440 int i, newMaxPoints = etalonPointCount*(MAX(framesAccepted,framesTotal) + 1); 441 442 isCalibrated = false; 443 444 if( !pts ) 445 { 446 for( i = 0; i < cameraCount; i++ ) 447 if( latestCounts[i] <= 0 ) 448 return false; 449 pts = (const CvPoint2D32f**)latestPoints; 450 } 451 452 for( i = 0; i < cameraCount; i++ ) 453 { 454 if( !pts[i] ) 455 { 456 assert(0); 457 break; 458 } 459 460 if( maxPoints < newMaxPoints ) 461 { 462 CvPoint2D32f* prev = points[i]; 463 cvFree( points + i ); 464 points[i] = (CvPoint2D32f*)cvAlloc( newMaxPoints * sizeof(prev[0])); 465 memcpy( points[i], prev, maxPoints * sizeof(prev[0])); 466 } 467 468 memcpy( points[i] + framesAccepted*etalonPointCount, pts[i], 469 etalonPointCount*sizeof(points[0][0])); 470 } 471 472 if( maxPoints < newMaxPoints ) 473 maxPoints = newMaxPoints; 474 475 result = i == cameraCount; 476 477 if( ++framesAccepted >= framesTotal ) 478 Stop( true ); 479 return result; 480 } 481 482 483 bool CvCalibFilter::GetLatestPoints( int idx, CvPoint2D32f** pts, 484 int* count, bool* found ) 485 { 486 int n; 487 488 if( (unsigned)idx >= (unsigned)cameraCount || 489 !pts || !count || !found ) 490 { 491 assert(0); 492 return false; 493 } 494 495 n = latestCounts[idx]; 496 497 *found = n > 0; 498 *count = abs(n); 499 *pts = latestPoints[idx]; 500 501 return true; 502 } 503 504 505 void CvCalibFilter::DrawPoints( IplImage** dst ) 506 { 507 DrawPoints( (CvMat**)dst ); 508 } 509 510 511 void CvCalibFilter::DrawPoints( CvMat** dstarr ) 512 { 513 int i, j; 514 515 if( !dstarr ) 516 { 517 assert(0); 518 return; 519 } 520 521 if( latestCounts ) 522 { 523 for( i = 0; i < cameraCount; i++ ) 524 { 525 if( dstarr[i] && latestCounts[i] ) 526 { 527 CvMat dst_stub, *dst; 528 int count = 0; 529 bool found = false; 530 CvPoint2D32f* pts = 0; 531 532 GetLatestPoints( i, &pts, &count, &found ); 533 534 dst = cvGetMat( dstarr[i], &dst_stub ); 535 536 static const CvScalar line_colors[] = 537 { 538 {{0,0,255}}, 539 {{0,128,255}}, 540 {{0,200,200}}, 541 {{0,255,0}}, 542 {{200,200,0}}, 543 {{255,0,0}}, 544 {{255,0,255}} 545 }; 546 547 const int colorCount = sizeof(line_colors)/sizeof(line_colors[0]); 548 const int r = 4; 549 CvScalar color = line_colors[0]; 550 CvPoint prev_pt = { 0, 0}; 551 552 for( j = 0; j < count; j++ ) 553 { 554 CvPoint pt; 555 pt.x = cvRound(pts[j].x); 556 pt.y = cvRound(pts[j].y); 557 558 if( found ) 559 { 560 if( etalonType == CV_CALIB_ETALON_CHESSBOARD ) 561 color = line_colors[(j/cvRound(etalonParams[0]))%colorCount]; 562 else 563 color = CV_RGB(0,255,0); 564 565 if( j != 0 ) 566 cvLine( dst, prev_pt, pt, color, 1, CV_AA ); 567 } 568 569 cvLine( dst, cvPoint( pt.x - r, pt.y - r ), 570 cvPoint( pt.x + r, pt.y + r ), color, 1, CV_AA ); 571 572 cvLine( dst, cvPoint( pt.x - r, pt.y + r), 573 cvPoint( pt.x + r, pt.y - r), color, 1, CV_AA ); 574 575 cvCircle( dst, pt, r+1, color, 1, CV_AA ); 576 577 prev_pt = pt; 578 } 579 } 580 } 581 } 582 } 583 584 585 /* Get total number of frames and already accepted pair of frames */ 586 int CvCalibFilter::GetFrameCount( int* total ) const 587 { 588 if( total ) 589 *total = framesTotal; 590 591 return framesAccepted; 592 } 593 594 595 /* Get camera parameters for specified camera. If camera is not calibrated 596 the function returns 0 */ 597 const CvCamera* CvCalibFilter::GetCameraParams( int idx ) const 598 { 599 if( (unsigned)idx >= (unsigned)cameraCount ) 600 { 601 assert(0); 602 return 0; 603 } 604 605 return isCalibrated ? cameraParams + idx : 0; 606 } 607 608 609 /* Get camera parameters for specified camera. If camera is not calibrated 610 the function returns 0 */ 611 const CvStereoCamera* CvCalibFilter::GetStereoParams() const 612 { 613 if( !(isCalibrated && cameraCount == 2) ) 614 { 615 assert(0); 616 return 0; 617 } 618 619 return &stereo; 620 } 621 622 623 /* Sets camera parameters for all cameras */ 624 bool CvCalibFilter::SetCameraParams( CvCamera* params ) 625 { 626 CvMat mat; 627 int arrSize; 628 629 Stop(); 630 631 if( !params ) 632 { 633 assert(0); 634 return false; 635 } 636 637 arrSize = cameraCount * sizeof(params[0]); 638 639 cvInitMatHeader( &mat, 1, cameraCount * (arrSize/sizeof(float)), 640 CV_32FC1, params ); 641 cvCheckArr( &mat, CV_CHECK_RANGE, -10000, 10000 ); 642 643 memcpy( cameraParams, params, arrSize ); 644 isCalibrated = true; 645 646 return true; 647 } 648 649 650 bool CvCalibFilter::SaveCameraParams( const char* filename ) 651 { 652 if( isCalibrated ) 653 { 654 int i, j; 655 656 FILE* f = fopen( filename, "w" ); 657 658 if( !f ) return false; 659 660 fprintf( f, "%d\n\n", cameraCount ); 661 662 for( i = 0; i < cameraCount; i++ ) 663 { 664 for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ ) 665 { 666 fprintf( f, "%15.10f ", ((float*)(cameraParams + i))[j] ); 667 } 668 fprintf( f, "\n\n" ); 669 } 670 671 /* Save stereo params */ 672 673 /* Save quad */ 674 for( i = 0; i < 2; i++ ) 675 { 676 for( j = 0; j < 4; j++ ) 677 { 678 fprintf(f, "%15.10f ", stereo.quad[i][j].x ); 679 fprintf(f, "%15.10f ", stereo.quad[i][j].y ); 680 } 681 fprintf(f, "\n"); 682 } 683 684 /* Save coeffs */ 685 for( i = 0; i < 2; i++ ) 686 { 687 for( j = 0; j < 9; j++ ) 688 { 689 fprintf(f, "%15.10lf ", stereo.coeffs[i][j/3][j%3] ); 690 } 691 fprintf(f, "\n"); 692 } 693 694 695 fclose(f); 696 return true; 697 } 698 699 return true; 700 } 701 702 703 bool CvCalibFilter::LoadCameraParams( const char* filename ) 704 { 705 int i, j; 706 int d = 0; 707 FILE* f = fopen( filename, "r" ); 708 709 isCalibrated = false; 710 711 if( !f ) return false; 712 713 if( fscanf( f, "%d", &d ) != 1 || d <= 0 || d > 10 ) 714 return false; 715 716 SetCameraCount( d ); 717 718 for( i = 0; i < cameraCount; i++ ) 719 { 720 for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ ) 721 { 722 fscanf( f, "%f", &((float*)(cameraParams + i))[j] ); 723 } 724 } 725 726 727 /* Load stereo params */ 728 729 /* load quad */ 730 for( i = 0; i < 2; i++ ) 731 { 732 for( j = 0; j < 4; j++ ) 733 { 734 fscanf(f, "%f ", &(stereo.quad[i][j].x) ); 735 fscanf(f, "%f ", &(stereo.quad[i][j].y) ); 736 } 737 } 738 739 /* Load coeffs */ 740 for( i = 0; i < 2; i++ ) 741 { 742 for( j = 0; j < 9; j++ ) 743 { 744 fscanf(f, "%lf ", &(stereo.coeffs[i][j/3][j%3]) ); 745 } 746 } 747 748 749 750 751 fclose(f); 752 753 stereo.warpSize = cvSize( cvRound(cameraParams[0].imgSize[0]), cvRound(cameraParams[0].imgSize[1])); 754 755 isCalibrated = true; 756 757 return true; 758 } 759 760 761 bool CvCalibFilter::Rectify( IplImage** srcarr, IplImage** dstarr ) 762 { 763 return Rectify( (CvMat**)srcarr, (CvMat**)dstarr ); 764 } 765 766 bool CvCalibFilter::Rectify( CvMat** srcarr, CvMat** dstarr ) 767 { 768 int i; 769 770 if( !srcarr || !dstarr ) 771 { 772 assert(0); 773 return false; 774 } 775 776 if( isCalibrated && cameraCount == 2 ) 777 { 778 for( i = 0; i < cameraCount; i++ ) 779 { 780 if( srcarr[i] && dstarr[i] ) 781 { 782 IplImage src_stub, *src; 783 IplImage dst_stub, *dst; 784 785 src = cvGetImage( srcarr[i], &src_stub ); 786 dst = cvGetImage( dstarr[i], &dst_stub ); 787 788 if( src->imageData == dst->imageData ) 789 { 790 if( !undistImg || 791 undistImg->width != src->width || 792 undistImg->height != src->height || 793 CV_MAT_CN(undistImg->type) != src->nChannels ) 794 { 795 cvReleaseMat( &undistImg ); 796 undistImg = cvCreateMat( src->height, src->width, 797 CV_8U + (src->nChannels-1)*8 ); 798 } 799 cvCopy( src, undistImg ); 800 src = cvGetImage( undistImg, &src_stub ); 801 } 802 803 cvZero( dst ); 804 805 if( !rectMap[i][0] || rectMap[i][0]->width != src->width || 806 rectMap[i][0]->height != src->height ) 807 { 808 cvReleaseMat( &rectMap[i][0] ); 809 cvReleaseMat( &rectMap[i][1] ); 810 rectMap[i][0] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); 811 rectMap[i][1] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); 812 cvComputePerspectiveMap(stereo.coeffs[i], rectMap[i][0], rectMap[i][1]); 813 } 814 cvRemap( src, dst, rectMap[i][0], rectMap[i][1] ); 815 } 816 } 817 } 818 else 819 { 820 for( i = 0; i < cameraCount; i++ ) 821 { 822 if( srcarr[i] != dstarr[i] ) 823 cvCopy( srcarr[i], dstarr[i] ); 824 } 825 } 826 827 return true; 828 } 829 830 bool CvCalibFilter::Undistort( IplImage** srcarr, IplImage** dstarr ) 831 { 832 return Undistort( (CvMat**)srcarr, (CvMat**)dstarr ); 833 } 834 835 836 bool CvCalibFilter::Undistort( CvMat** srcarr, CvMat** dstarr ) 837 { 838 int i; 839 840 if( !srcarr || !dstarr ) 841 { 842 assert(0); 843 return false; 844 } 845 846 if( isCalibrated ) 847 { 848 for( i = 0; i < cameraCount; i++ ) 849 { 850 if( srcarr[i] && dstarr[i] ) 851 { 852 CvMat src_stub, *src; 853 CvMat dst_stub, *dst; 854 855 src = cvGetMat( srcarr[i], &src_stub ); 856 dst = cvGetMat( dstarr[i], &dst_stub ); 857 858 if( src->data.ptr == dst->data.ptr ) 859 { 860 if( !undistImg || undistImg->width != src->width || 861 undistImg->height != src->height || 862 CV_ARE_TYPES_EQ( undistImg, src )) 863 { 864 cvReleaseMat( &undistImg ); 865 undistImg = cvCreateMat( src->height, src->width, src->type ); 866 } 867 868 cvCopy( src, undistImg ); 869 src = undistImg; 870 } 871 872 #if 1 873 { 874 CvMat A = cvMat( 3, 3, CV_32FC1, cameraParams[i].matrix ); 875 CvMat k = cvMat( 1, 4, CV_32FC1, cameraParams[i].distortion ); 876 877 if( !undistMap[i][0] || undistMap[i][0]->width != src->width || 878 undistMap[i][0]->height != src->height ) 879 { 880 cvReleaseMat( &undistMap[i][0] ); 881 cvReleaseMat( &undistMap[i][1] ); 882 undistMap[i][0] = cvCreateMat( src->height, src->width, CV_32FC1 ); 883 undistMap[i][1] = cvCreateMat( src->height, src->width, CV_32FC1 ); 884 cvInitUndistortMap( &A, &k, undistMap[i][0], undistMap[i][1] ); 885 } 886 887 cvRemap( src, dst, undistMap[i][0], undistMap[i][1] ); 888 #else 889 cvUndistort2( src, dst, &A, &k ); 890 #endif 891 } 892 } 893 } 894 } 895 else 896 { 897 for( i = 0; i < cameraCount; i++ ) 898 { 899 if( srcarr[i] != dstarr[i] ) 900 cvCopy( srcarr[i], dstarr[i] ); 901 } 902 } 903 904 905 return true; 906 } 907