$search
00001 00011 #ifndef CV_GEOMETRY_H 00012 #define CV_GEOMETRY_H 00013 00014 #include <stdio.h> 00015 #include <opencv/cv.h> 00016 00017 00025 inline void cvDistort (const double *pIntrinsicDistort, const double *pDistortion, const double *pSrc, double *pDes ) { 00026 //std::cout << "k1: " << pDistortion[0] << ", k2: " << pDistortion[1] << ",p1: " << pDistortion[2] << ", p2: " << pDistortion[3] << std::endl; 00027 double dx = ( pSrc[0] - pIntrinsicDistort[2] ) / pIntrinsicDistort[0]; 00028 // relative y position in distorted image to the center 00029 double dy = ( pSrc[1] - pIntrinsicDistort[5] ) / pIntrinsicDistort[4]; 00030 // relative distance of the distorted point to the center 00031 double dxdy = dx*dy; 00032 double dx2 = dx*dx; 00033 double dy2 = dy*dy; 00034 double r = sqrt ( dx2 + dy2 ); 00035 double r2 = r*r; 00036 double r4 = r2*r2; 00037 00038 //x = dx*(1 + k1r^2 + k2r^4) + 2*p1*dx*dy + p2(r^2+2*dx^2) 00039 double Tx1 = dx * ( 1.0 + pDistortion[0] * r2 + pDistortion[1] * r4 ); 00040 double Tx2 = 2 * pDistortion[2] * dxdy; 00041 double Tx3 = pDistortion[3] * ( r2 + 2 * dx2 ); 00042 00043 //y = dy*(1 + k1r^2 + k2r^4) + p1(r^2+2*dy^2) + 2*p2*dx*dy 00044 double Ty1 = dy * ( 1.0 + pDistortion[0] * r2 + pDistortion[1] * r4 ); 00045 double Ty2 = pDistortion[2] * ( r2 + 2 * dy2 ); 00046 double Ty3 = 2 * pDistortion[3] * dxdy; 00047 00048 pDes[0] = ( Tx1 + Tx2 + Tx3 ) * pIntrinsicDistort[0] + pIntrinsicDistort[2]; 00049 pDes[1] = ( Ty1 + Ty2 + Ty3 ) * pIntrinsicDistort[4] + pIntrinsicDistort[5]; 00050 00051 } 00052 00053 00061 inline void cvDistort (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, const CvPoint2D64f *pSrc, CvPoint2D64f *pDes ) { 00062 cvDistort (pIntrinsicDistort->data.db, pDistortion->data.db, (const double *) pSrc, (double *) pDes ); 00063 } 00064 00072 inline void cvDistort (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, const CvPoint *pSrc, CvPoint *pDes ) { 00073 double src[] = {static_cast<double>(pSrc->x), static_cast<double>(pSrc->y)}, des[2]; 00074 cvDistort (pIntrinsicDistort->data.db, pDistortion->data.db, (const double *) &src, (double *) &des ); 00075 pDes->x = cvRound(des[0]), pDes->y = cvRound(des[1]); 00076 } 00077 00087 inline void cvInitUndistortMapExact (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, CvMat *pMapX, CvMat *pMapY) { 00088 CvPoint2D64f undistort, distort; 00089 if((cvGetElemType(pMapX) == CV_32FC1) && (cvGetElemType(pMapY) == CV_32FC1)){ 00090 float *pX = pMapX->data.fl, *pY = pMapY->data.fl; 00091 for ( undistort.y = 0; undistort.y < pMapX->height; undistort.y++) { 00092 for ( undistort.x = 0; undistort.x < pMapX->width; undistort.x++) { 00093 cvDistort(pIntrinsicDistort, pDistortion, &undistort, &distort); 00094 *pX++ = (float) distort.x, *pY++ = (float) distort.y; 00095 } 00096 } 00097 } else if((cvGetElemType(pMapX) == CV_64FC1) && (cvGetElemType(pMapY) == CV_64FC1)){ 00098 double *pX = pMapX->data.db, *pY = pMapY->data.db; 00099 for ( undistort.y = 0; undistort.y < pMapX->height; undistort.y++) { 00100 for ( undistort.x = 0; undistort.x < pMapX->width; undistort.x++) { 00101 cvDistort(pIntrinsicDistort, pDistortion, &undistort, &distort); 00102 *pX++ = distort.x, *pY++ = distort.y; 00103 } 00104 } 00105 } 00106 } 00107 00117 inline void cvUndistortExact (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, const IplImage *pSrc, IplImage *pDes) { 00118 00119 CvMat *pMapX = cvCreateMat ( pSrc->height, pSrc->width, CV_32FC1 ); 00120 CvMat *pMapY = cvCreateMat ( pSrc->height, pSrc->width, CV_32FC1 ); 00121 cvInitUndistortMapExact (pIntrinsicDistort, pDistortion, pMapX, pMapY); 00122 cvRemap ( pSrc, pDes, pMapX, pMapY ); 00123 cvReleaseMat ( &pMapX ), cvReleaseMat ( &pMapY ); 00124 } 00125 00133 inline bool cvUndistort (const double *pIntrinsicDistort, const double *pDistortion, const double *pSrc, double *pDes, double maxError = 1) { 00134 const int iMaxInterations = 100; 00135 double fError = (pIntrinsicDistort[2]+pIntrinsicDistort[5])*4; 00136 double cradient[] = {0, 0}; 00137 pDes[0] = pSrc[0], pDes[1] = pSrc[1]; 00138 double current[2]; 00139 int i; 00140 for ( i = 0; ( ( i < iMaxInterations ) && ( fError > maxError ) ); i++ ) { 00141 pDes[0] += cradient[0]; 00142 pDes[1] += cradient[1]; 00143 cvDistort (pIntrinsicDistort, pDistortion, pDes, (double *) ¤t ); 00144 cradient[0] = pSrc[0] - current[0]; 00145 cradient[1] = pSrc[1] - current[1]; 00146 fError = cradient[0] * cradient[0] + cradient[1] * cradient[1]; 00147 } 00148 if ( i < iMaxInterations ) return true; 00149 else return false; 00150 } 00151 00159 inline bool cvUndistort (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, const CvPoint2D64f *pSrc, CvPoint2D64f *pDes, double maxError = 1) { 00160 return cvUndistort (pIntrinsicDistort->data.db, pDistortion->data.db, (const double *) pSrc, (double *) pDes, maxError ); 00161 } 00162 00170 inline bool Undistort (const CvMat *pIntrinsicDistort, const CvMat *pDistortion, const CvPoint *pSrc, CvPoint *pDes, double maxError = 1) { 00171 double src[] = {static_cast<double>(pSrc->x), static_cast<double>(pSrc->y)}, des[2]; 00172 bool result = cvUndistort (pIntrinsicDistort->data.db, pDistortion->data.db, (const double *) src, (double *) &des, maxError ); 00173 pDes->x = round(des[0]); 00174 pDes->y = round(des[1]); 00175 return result; 00176 } 00183 inline void cvProjectPoint(const double *pMintMext, const double *pSrc, double *pDes) { 00184 pDes[0] = pMintMext[0] * pSrc[0] + pMintMext[1] * pSrc[1] + pMintMext[2] * pSrc[2] + pMintMext[3]; 00185 pDes[1] = pMintMext[4] * pSrc[0] + pMintMext[5] * pSrc[1] + pMintMext[6] * pSrc[2] + pMintMext[7]; 00186 double n = pMintMext[8] * pSrc[0] + pMintMext[9] * pSrc[1] + pMintMext[10] * pSrc[2] + pMintMext[11]; 00187 pDes[0] /= n; 00188 pDes[1] /= n; 00189 } 00190 00197 inline void cvProjectPoint(const CvMat *pMintMext, const CvPoint2D64f *pSrc, CvPoint2D64f *pDes) { 00198 cvProjectPoint(pMintMext->data.db, (const double *) pSrc, (double *) pDes); 00199 } 00200 00207 template <typename A, typename B> inline void cvProjectPoint(const CvMat *pMintMext, const A *pSrc, B *pDes) { 00208 double src[] = {pSrc->x, pSrc->y}, des[2]; 00209 cvProjectPoint(pMintMext->data.db, (const double *) src, (double *) des); 00210 pDes->x = cvRound(des[0]), pDes->y = cvRound(des[1]); 00211 } 00212 00213 #endif //CV_GEOMETIRY_H