| /*M/////////////////////////////////////////////////////////////////////////////////////// |
| // |
| // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. |
| // |
| // By downloading, copying, installing or using the software you agree to this license. |
| // If you do not agree to this license, do not download, install, |
| // copy or use the software. |
| // |
| // |
| // Intel License Agreement |
| // For Open Source Computer Vision Library |
| // |
| // Copyright (C) 2000, Intel Corporation, all rights reserved. |
| // Third party copyrights are property of their respective owners. |
| // |
| // Redistribution and use in source and binary forms, with or without modification, |
| // are permitted provided that the following conditions are met: |
| // |
| // * Redistribution's of source code must retain the above copyright notice, |
| // this list of conditions and the following disclaimer. |
| // |
| // * Redistribution's in binary form must reproduce the above copyright notice, |
| // this list of conditions and the following disclaimer in the documentation |
| // and/or other materials provided with the distribution. |
| // |
| // * The name of Intel Corporation may not be used to endorse or promote products |
| // derived from this software without specific prior written permission. |
| // |
| // This software is provided by the copyright holders and contributors "as is" and |
| // any express or implied warranties, including, but not limited to, the implied |
| // warranties of merchantability and fitness for a particular purpose are disclaimed. |
| // In no event shall the Intel Corporation or contributors be liable for any direct, |
| // indirect, incidental, special, exemplary, or consequential damages |
| // (including, but not limited to, procurement of substitute goods or services; |
| // loss of use, data, or profits; or business interruption) however caused |
| // and on any theory of liability, whether in contract, strict liability, |
| // or tort (including negligence or otherwise) arising in any way out of |
| // the use of this software, even if advised of the possibility of such damage. |
| // |
| //M*/ |
| |
| #include "_cvaux.h" |
| #include <stdio.h> |
| |
| #undef quad |
| |
| #if _MSC_VER >= 1200 |
| #pragma warning( disable: 4701 ) |
| #endif |
| |
| CvCalibFilter::CvCalibFilter() |
| { |
| /* etalon data */ |
| etalonType = CV_CALIB_ETALON_USER; |
| etalonParamCount = 0; |
| etalonParams = 0; |
| etalonPointCount = 0; |
| etalonPoints = 0; |
| |
| /* camera data */ |
| cameraCount = 1; |
| |
| memset( points, 0, sizeof(points)); |
| memset( undistMap, 0, sizeof(undistMap)); |
| undistImg = 0; |
| memset( latestCounts, 0, sizeof(latestCounts)); |
| memset( latestPoints, 0, sizeof(latestPoints)); |
| memset( &stereo, 0, sizeof(stereo) ); |
| maxPoints = 0; |
| framesTotal = 15; |
| framesAccepted = 0; |
| isCalibrated = false; |
| |
| imgSize = cvSize(0,0); |
| grayImg = 0; |
| tempImg = 0; |
| storage = 0; |
| |
| memset( rectMap, 0, sizeof(rectMap)); |
| } |
| |
| |
| CvCalibFilter::~CvCalibFilter() |
| { |
| SetCameraCount(0); |
| cvFree( &etalonParams ); |
| cvFree( &etalonPoints ); |
| cvReleaseMat( &grayImg ); |
| cvReleaseMat( &tempImg ); |
| cvReleaseMat( &undistImg ); |
| cvReleaseMemStorage( &storage ); |
| } |
| |
| |
| bool CvCalibFilter::SetEtalon( CvCalibEtalonType type, double* params, |
| int pointCount, CvPoint2D32f* points ) |
| { |
| int i, arrSize; |
| |
| Stop(); |
| |
| for( i = 0; i < MAX_CAMERAS; i++ ) |
| cvFree( latestPoints + i ); |
| |
| if( type == CV_CALIB_ETALON_USER || type != etalonType ) |
| { |
| cvFree( &etalonParams ); |
| } |
| |
| etalonType = type; |
| |
| switch( etalonType ) |
| { |
| case CV_CALIB_ETALON_CHESSBOARD: |
| etalonParamCount = 3; |
| if( !params || cvRound(params[0]) != params[0] || params[0] < 3 || |
| cvRound(params[1]) != params[1] || params[1] < 3 || params[2] <= 0 ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| pointCount = cvRound((params[0] - 1)*(params[1] - 1)); |
| break; |
| |
| case CV_CALIB_ETALON_USER: |
| etalonParamCount = 0; |
| |
| if( !points || pointCount < 4 ) |
| { |
| assert(0); |
| return false; |
| } |
| break; |
| |
| default: |
| assert(0); |
| return false; |
| } |
| |
| if( etalonParamCount > 0 ) |
| { |
| arrSize = etalonParamCount * sizeof(etalonParams[0]); |
| etalonParams = (double*)cvAlloc( arrSize ); |
| } |
| |
| arrSize = pointCount * sizeof(etalonPoints[0]); |
| |
| if( etalonPointCount != pointCount ) |
| { |
| cvFree( &etalonPoints ); |
| etalonPointCount = pointCount; |
| etalonPoints = (CvPoint2D32f*)cvAlloc( arrSize ); |
| } |
| |
| switch( etalonType ) |
| { |
| case CV_CALIB_ETALON_CHESSBOARD: |
| { |
| int etalonWidth = cvRound( params[0] ) - 1; |
| int etalonHeight = cvRound( params[1] ) - 1; |
| int x, y, k = 0; |
| |
| etalonParams[0] = etalonWidth; |
| etalonParams[1] = etalonHeight; |
| etalonParams[2] = params[2]; |
| |
| for( y = 0; y < etalonHeight; y++ ) |
| for( x = 0; x < etalonWidth; x++ ) |
| { |
| etalonPoints[k++] = cvPoint2D32f( (etalonWidth - 1 - x)*params[2], |
| y*params[2] ); |
| } |
| } |
| break; |
| |
| case CV_CALIB_ETALON_USER: |
| memcpy( etalonParams, params, arrSize ); |
| memcpy( etalonPoints, points, arrSize ); |
| break; |
| |
| default: |
| assert(0); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| |
| CvCalibEtalonType |
| CvCalibFilter::GetEtalon( int* paramCount, const double** params, |
| int* pointCount, const CvPoint2D32f** points ) const |
| { |
| if( paramCount ) |
| *paramCount = etalonParamCount; |
| |
| if( params ) |
| *params = etalonParams; |
| |
| if( pointCount ) |
| *pointCount = etalonPointCount; |
| |
| if( points ) |
| *points = etalonPoints; |
| |
| return etalonType; |
| } |
| |
| |
| void CvCalibFilter::SetCameraCount( int count ) |
| { |
| Stop(); |
| |
| if( count != cameraCount ) |
| { |
| for( int i = 0; i < cameraCount; i++ ) |
| { |
| cvFree( points + i ); |
| cvFree( latestPoints + i ); |
| cvReleaseMat( &undistMap[i][0] ); |
| cvReleaseMat( &undistMap[i][1] ); |
| cvReleaseMat( &rectMap[i][0] ); |
| cvReleaseMat( &rectMap[i][1] ); |
| } |
| |
| memset( latestCounts, 0, sizeof(latestPoints) ); |
| maxPoints = 0; |
| cameraCount = count; |
| } |
| } |
| |
| |
| bool CvCalibFilter::SetFrames( int frames ) |
| { |
| if( frames < 5 ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| framesTotal = frames; |
| return true; |
| } |
| |
| |
| void CvCalibFilter::Stop( bool calibrate ) |
| { |
| int i, j; |
| isCalibrated = false; |
| |
| // deallocate undistortion maps |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| cvReleaseMat( &undistMap[i][0] ); |
| cvReleaseMat( &undistMap[i][1] ); |
| cvReleaseMat( &rectMap[i][0] ); |
| cvReleaseMat( &rectMap[i][1] ); |
| } |
| |
| if( calibrate && framesAccepted > 0 ) |
| { |
| int n = framesAccepted; |
| CvPoint3D32f* buffer = |
| (CvPoint3D32f*)cvAlloc( n * etalonPointCount * sizeof(buffer[0])); |
| CvMat mat; |
| float* rotMatr = (float*)cvAlloc( n * 9 * sizeof(rotMatr[0])); |
| float* transVect = (float*)cvAlloc( n * 3 * sizeof(transVect[0])); |
| int* counts = (int*)cvAlloc( n * sizeof(counts[0])); |
| |
| cvInitMatHeader( &mat, 1, sizeof(CvCamera)/sizeof(float), CV_32FC1, 0 ); |
| memset( cameraParams, 0, cameraCount * sizeof(cameraParams[0])); |
| |
| for( i = 0; i < framesAccepted; i++ ) |
| { |
| counts[i] = etalonPointCount; |
| for( j = 0; j < etalonPointCount; j++ ) |
| buffer[i * etalonPointCount + j] = cvPoint3D32f( etalonPoints[j].x, |
| etalonPoints[j].y, 0 ); |
| } |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| cvCalibrateCamera( framesAccepted, counts, |
| imgSize, points[i], buffer, |
| cameraParams[i].distortion, |
| cameraParams[i].matrix, |
| transVect, rotMatr, 0 ); |
| |
| cameraParams[i].imgSize[0] = (float)imgSize.width; |
| cameraParams[i].imgSize[1] = (float)imgSize.height; |
| |
| // cameraParams[i].focalLength[0] = cameraParams[i].matrix[0]; |
| // cameraParams[i].focalLength[1] = cameraParams[i].matrix[4]; |
| |
| // cameraParams[i].principalPoint[0] = cameraParams[i].matrix[2]; |
| // cameraParams[i].principalPoint[1] = cameraParams[i].matrix[5]; |
| |
| memcpy( cameraParams[i].rotMatr, rotMatr, 9 * sizeof(rotMatr[0])); |
| memcpy( cameraParams[i].transVect, transVect, 3 * sizeof(transVect[0])); |
| |
| mat.data.ptr = (uchar*)(cameraParams + i); |
| |
| /* check resultant camera parameters: if there are some INF's or NAN's, |
| stop and reset results */ |
| if( !cvCheckArr( &mat, CV_CHECK_RANGE | CV_CHECK_QUIET, -10000, 10000 )) |
| break; |
| } |
| |
| |
| |
| isCalibrated = i == cameraCount; |
| |
| {/* calibrate stereo cameras */ |
| if( cameraCount == 2 ) |
| { |
| stereo.camera[0] = &cameraParams[0]; |
| stereo.camera[1] = &cameraParams[1]; |
| |
| icvStereoCalibration( framesAccepted, counts, |
| imgSize, |
| points[0],points[1], |
| buffer, |
| &stereo); |
| |
| for( i = 0; i < 9; i++ ) |
| { |
| stereo.fundMatr[i] = stereo.fundMatr[i]; |
| } |
| |
| } |
| |
| } |
| |
| cvFree( &buffer ); |
| cvFree( &counts ); |
| cvFree( &rotMatr ); |
| cvFree( &transVect ); |
| } |
| |
| framesAccepted = 0; |
| } |
| |
| |
| bool CvCalibFilter::FindEtalon( IplImage** imgs ) |
| { |
| return FindEtalon( (CvMat**)imgs ); |
| } |
| |
| |
| bool CvCalibFilter::FindEtalon( CvMat** mats ) |
| { |
| bool result = true; |
| |
| if( !mats || etalonPointCount == 0 ) |
| { |
| assert(0); |
| result = false; |
| } |
| |
| if( result ) |
| { |
| int i, tempPointCount0 = etalonPointCount*2; |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( !latestPoints[i] ) |
| latestPoints[i] = (CvPoint2D32f*) |
| cvAlloc( tempPointCount0*2*sizeof(latestPoints[0])); |
| } |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| CvSize size; |
| int tempPointCount = tempPointCount0; |
| bool found = false; |
| |
| if( !CV_IS_MAT(mats[i]) && !CV_IS_IMAGE(mats[i])) |
| { |
| assert(0); |
| break; |
| } |
| |
| size = cvGetSize(mats[i]); |
| |
| if( size.width != imgSize.width || size.height != imgSize.height ) |
| { |
| imgSize = size; |
| } |
| |
| if( !grayImg || grayImg->width != imgSize.width || |
| grayImg->height != imgSize.height ) |
| { |
| cvReleaseMat( &grayImg ); |
| cvReleaseMat( &tempImg ); |
| grayImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); |
| tempImg = cvCreateMat( imgSize.height, imgSize.width, CV_8UC1 ); |
| } |
| |
| if( !storage ) |
| storage = cvCreateMemStorage(); |
| |
| switch( etalonType ) |
| { |
| case CV_CALIB_ETALON_CHESSBOARD: |
| if( CV_MAT_CN(cvGetElemType(mats[i])) == 1 ) |
| cvCopy( mats[i], grayImg ); |
| else |
| cvCvtColor( mats[i], grayImg, CV_BGR2GRAY ); |
| found = cvFindChessBoardCornerGuesses( grayImg, tempImg, storage, |
| cvSize( cvRound(etalonParams[0]), |
| cvRound(etalonParams[1])), |
| latestPoints[i], &tempPointCount ) != 0; |
| if( found ) |
| cvFindCornerSubPix( grayImg, latestPoints[i], tempPointCount, |
| cvSize(5,5), cvSize(-1,-1), |
| cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)); |
| break; |
| default: |
| assert(0); |
| result = false; |
| break; |
| } |
| |
| latestCounts[i] = found ? tempPointCount : -tempPointCount; |
| result = result && found; |
| } |
| } |
| |
| if( storage ) |
| cvClearMemStorage( storage ); |
| |
| return result; |
| } |
| |
| |
| bool CvCalibFilter::Push( const CvPoint2D32f** pts ) |
| { |
| bool result = true; |
| int i, newMaxPoints = etalonPointCount*(MAX(framesAccepted,framesTotal) + 1); |
| |
| isCalibrated = false; |
| |
| if( !pts ) |
| { |
| for( i = 0; i < cameraCount; i++ ) |
| if( latestCounts[i] <= 0 ) |
| return false; |
| pts = (const CvPoint2D32f**)latestPoints; |
| } |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( !pts[i] ) |
| { |
| assert(0); |
| break; |
| } |
| |
| if( maxPoints < newMaxPoints ) |
| { |
| CvPoint2D32f* prev = points[i]; |
| cvFree( points + i ); |
| points[i] = (CvPoint2D32f*)cvAlloc( newMaxPoints * sizeof(prev[0])); |
| memcpy( points[i], prev, maxPoints * sizeof(prev[0])); |
| } |
| |
| memcpy( points[i] + framesAccepted*etalonPointCount, pts[i], |
| etalonPointCount*sizeof(points[0][0])); |
| } |
| |
| if( maxPoints < newMaxPoints ) |
| maxPoints = newMaxPoints; |
| |
| result = i == cameraCount; |
| |
| if( ++framesAccepted >= framesTotal ) |
| Stop( true ); |
| return result; |
| } |
| |
| |
| bool CvCalibFilter::GetLatestPoints( int idx, CvPoint2D32f** pts, |
| int* count, bool* found ) |
| { |
| int n; |
| |
| if( (unsigned)idx >= (unsigned)cameraCount || |
| !pts || !count || !found ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| n = latestCounts[idx]; |
| |
| *found = n > 0; |
| *count = abs(n); |
| *pts = latestPoints[idx]; |
| |
| return true; |
| } |
| |
| |
| void CvCalibFilter::DrawPoints( IplImage** dst ) |
| { |
| DrawPoints( (CvMat**)dst ); |
| } |
| |
| |
| void CvCalibFilter::DrawPoints( CvMat** dstarr ) |
| { |
| int i, j; |
| |
| if( !dstarr ) |
| { |
| assert(0); |
| return; |
| } |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( dstarr[i] && latestCounts[i] ) |
| { |
| CvMat dst_stub, *dst; |
| int count = 0; |
| bool found = false; |
| CvPoint2D32f* pts = 0; |
| |
| GetLatestPoints( i, &pts, &count, &found ); |
| |
| dst = cvGetMat( dstarr[i], &dst_stub ); |
| |
| static const CvScalar line_colors[] = |
| { |
| {{0,0,255}}, |
| {{0,128,255}}, |
| {{0,200,200}}, |
| {{0,255,0}}, |
| {{200,200,0}}, |
| {{255,0,0}}, |
| {{255,0,255}} |
| }; |
| |
| const int colorCount = sizeof(line_colors)/sizeof(line_colors[0]); |
| const int r = 4; |
| CvScalar color = line_colors[0]; |
| CvPoint prev_pt = { 0, 0}; |
| |
| for( j = 0; j < count; j++ ) |
| { |
| CvPoint pt; |
| pt.x = cvRound(pts[j].x); |
| pt.y = cvRound(pts[j].y); |
| |
| if( found ) |
| { |
| if( etalonType == CV_CALIB_ETALON_CHESSBOARD ) |
| color = line_colors[(j/cvRound(etalonParams[0]))%colorCount]; |
| else |
| color = CV_RGB(0,255,0); |
| |
| if( j != 0 ) |
| cvLine( dst, prev_pt, pt, color, 1, CV_AA ); |
| } |
| |
| cvLine( dst, cvPoint( pt.x - r, pt.y - r ), |
| cvPoint( pt.x + r, pt.y + r ), color, 1, CV_AA ); |
| |
| cvLine( dst, cvPoint( pt.x - r, pt.y + r), |
| cvPoint( pt.x + r, pt.y - r), color, 1, CV_AA ); |
| |
| cvCircle( dst, pt, r+1, color, 1, CV_AA ); |
| |
| prev_pt = pt; |
| } |
| } |
| } |
| } |
| |
| |
| /* Get total number of frames and already accepted pair of frames */ |
| int CvCalibFilter::GetFrameCount( int* total ) const |
| { |
| if( total ) |
| *total = framesTotal; |
| |
| return framesAccepted; |
| } |
| |
| |
| /* Get camera parameters for specified camera. If camera is not calibrated |
| the function returns 0 */ |
| const CvCamera* CvCalibFilter::GetCameraParams( int idx ) const |
| { |
| if( (unsigned)idx >= (unsigned)cameraCount ) |
| { |
| assert(0); |
| return 0; |
| } |
| |
| return isCalibrated ? cameraParams + idx : 0; |
| } |
| |
| |
| /* Get camera parameters for specified camera. If camera is not calibrated |
| the function returns 0 */ |
| const CvStereoCamera* CvCalibFilter::GetStereoParams() const |
| { |
| if( !(isCalibrated && cameraCount == 2) ) |
| { |
| assert(0); |
| return 0; |
| } |
| |
| return &stereo; |
| } |
| |
| |
| /* Sets camera parameters for all cameras */ |
| bool CvCalibFilter::SetCameraParams( CvCamera* params ) |
| { |
| CvMat mat; |
| int arrSize; |
| |
| Stop(); |
| |
| if( !params ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| arrSize = cameraCount * sizeof(params[0]); |
| |
| cvInitMatHeader( &mat, 1, cameraCount * (arrSize/sizeof(float)), |
| CV_32FC1, params ); |
| cvCheckArr( &mat, CV_CHECK_RANGE, -10000, 10000 ); |
| |
| memcpy( cameraParams, params, arrSize ); |
| isCalibrated = true; |
| |
| return true; |
| } |
| |
| |
| bool CvCalibFilter::SaveCameraParams( const char* filename ) |
| { |
| if( isCalibrated ) |
| { |
| int i, j; |
| |
| FILE* f = fopen( filename, "w" ); |
| |
| if( !f ) return false; |
| |
| fprintf( f, "%d\n\n", cameraCount ); |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ ) |
| { |
| fprintf( f, "%15.10f ", ((float*)(cameraParams + i))[j] ); |
| } |
| fprintf( f, "\n\n" ); |
| } |
| |
| /* Save stereo params */ |
| |
| /* Save quad */ |
| for( i = 0; i < 2; i++ ) |
| { |
| for( j = 0; j < 4; j++ ) |
| { |
| fprintf(f, "%15.10f ", stereo.quad[i][j].x ); |
| fprintf(f, "%15.10f ", stereo.quad[i][j].y ); |
| } |
| fprintf(f, "\n"); |
| } |
| |
| /* Save coeffs */ |
| for( i = 0; i < 2; i++ ) |
| { |
| for( j = 0; j < 9; j++ ) |
| { |
| fprintf(f, "%15.10lf ", stereo.coeffs[i][j/3][j%3] ); |
| } |
| fprintf(f, "\n"); |
| } |
| |
| |
| fclose(f); |
| return true; |
| } |
| |
| return true; |
| } |
| |
| |
| bool CvCalibFilter::LoadCameraParams( const char* filename ) |
| { |
| int i, j; |
| int d = 0; |
| FILE* f = fopen( filename, "r" ); |
| |
| isCalibrated = false; |
| |
| if( !f ) return false; |
| |
| if( fscanf( f, "%d", &d ) != 1 || d <= 0 || d > 10 ) |
| return false; |
| |
| SetCameraCount( d ); |
| |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| for( j = 0; j < (int)(sizeof(cameraParams[i])/sizeof(float)); j++ ) |
| { |
| fscanf( f, "%f", &((float*)(cameraParams + i))[j] ); |
| } |
| } |
| |
| |
| /* Load stereo params */ |
| |
| /* load quad */ |
| for( i = 0; i < 2; i++ ) |
| { |
| for( j = 0; j < 4; j++ ) |
| { |
| fscanf(f, "%f ", &(stereo.quad[i][j].x) ); |
| fscanf(f, "%f ", &(stereo.quad[i][j].y) ); |
| } |
| } |
| |
| /* Load coeffs */ |
| for( i = 0; i < 2; i++ ) |
| { |
| for( j = 0; j < 9; j++ ) |
| { |
| fscanf(f, "%lf ", &(stereo.coeffs[i][j/3][j%3]) ); |
| } |
| } |
| |
| |
| |
| |
| fclose(f); |
| |
| stereo.warpSize = cvSize( cvRound(cameraParams[0].imgSize[0]), cvRound(cameraParams[0].imgSize[1])); |
| |
| isCalibrated = true; |
| |
| return true; |
| } |
| |
| |
| bool CvCalibFilter::Rectify( IplImage** srcarr, IplImage** dstarr ) |
| { |
| return Rectify( (CvMat**)srcarr, (CvMat**)dstarr ); |
| } |
| |
| bool CvCalibFilter::Rectify( CvMat** srcarr, CvMat** dstarr ) |
| { |
| int i; |
| |
| if( !srcarr || !dstarr ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| if( isCalibrated && cameraCount == 2 ) |
| { |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( srcarr[i] && dstarr[i] ) |
| { |
| IplImage src_stub, *src; |
| IplImage dst_stub, *dst; |
| |
| src = cvGetImage( srcarr[i], &src_stub ); |
| dst = cvGetImage( dstarr[i], &dst_stub ); |
| |
| if( src->imageData == dst->imageData ) |
| { |
| if( !undistImg || |
| undistImg->width != src->width || |
| undistImg->height != src->height || |
| CV_MAT_CN(undistImg->type) != src->nChannels ) |
| { |
| cvReleaseMat( &undistImg ); |
| undistImg = cvCreateMat( src->height, src->width, |
| CV_8U + (src->nChannels-1)*8 ); |
| } |
| cvCopy( src, undistImg ); |
| src = cvGetImage( undistImg, &src_stub ); |
| } |
| |
| cvZero( dst ); |
| |
| if( !rectMap[i][0] || rectMap[i][0]->width != src->width || |
| rectMap[i][0]->height != src->height ) |
| { |
| cvReleaseMat( &rectMap[i][0] ); |
| cvReleaseMat( &rectMap[i][1] ); |
| rectMap[i][0] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); |
| rectMap[i][1] = cvCreateMat(stereo.warpSize.height,stereo.warpSize.width,CV_32FC1); |
| cvComputePerspectiveMap(stereo.coeffs[i], rectMap[i][0], rectMap[i][1]); |
| } |
| cvRemap( src, dst, rectMap[i][0], rectMap[i][1] ); |
| } |
| } |
| } |
| else |
| { |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( srcarr[i] != dstarr[i] ) |
| cvCopy( srcarr[i], dstarr[i] ); |
| } |
| } |
| |
| return true; |
| } |
| |
| bool CvCalibFilter::Undistort( IplImage** srcarr, IplImage** dstarr ) |
| { |
| return Undistort( (CvMat**)srcarr, (CvMat**)dstarr ); |
| } |
| |
| |
| bool CvCalibFilter::Undistort( CvMat** srcarr, CvMat** dstarr ) |
| { |
| int i; |
| |
| if( !srcarr || !dstarr ) |
| { |
| assert(0); |
| return false; |
| } |
| |
| if( isCalibrated ) |
| { |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( srcarr[i] && dstarr[i] ) |
| { |
| CvMat src_stub, *src; |
| CvMat dst_stub, *dst; |
| |
| src = cvGetMat( srcarr[i], &src_stub ); |
| dst = cvGetMat( dstarr[i], &dst_stub ); |
| |
| if( src->data.ptr == dst->data.ptr ) |
| { |
| if( !undistImg || undistImg->width != src->width || |
| undistImg->height != src->height || |
| CV_ARE_TYPES_EQ( undistImg, src )) |
| { |
| cvReleaseMat( &undistImg ); |
| undistImg = cvCreateMat( src->height, src->width, src->type ); |
| } |
| |
| cvCopy( src, undistImg ); |
| src = undistImg; |
| } |
| |
| #if 1 |
| { |
| CvMat A = cvMat( 3, 3, CV_32FC1, cameraParams[i].matrix ); |
| CvMat k = cvMat( 1, 4, CV_32FC1, cameraParams[i].distortion ); |
| |
| if( !undistMap[i][0] || undistMap[i][0]->width != src->width || |
| undistMap[i][0]->height != src->height ) |
| { |
| cvReleaseMat( &undistMap[i][0] ); |
| cvReleaseMat( &undistMap[i][1] ); |
| undistMap[i][0] = cvCreateMat( src->height, src->width, CV_32FC1 ); |
| undistMap[i][1] = cvCreateMat( src->height, src->width, CV_32FC1 ); |
| cvInitUndistortMap( &A, &k, undistMap[i][0], undistMap[i][1] ); |
| } |
| |
| cvRemap( src, dst, undistMap[i][0], undistMap[i][1] ); |
| #else |
| cvUndistort2( src, dst, &A, &k ); |
| #endif |
| } |
| } |
| } |
| } |
| else |
| { |
| for( i = 0; i < cameraCount; i++ ) |
| { |
| if( srcarr[i] != dstarr[i] ) |
| cvCopy( srcarr[i], dstarr[i] ); |
| } |
| } |
| |
| |
| return true; |
| } |