26 #include <bias_config.h>
27 #ifndef BIAS_HAVE_OPENCV
28 # error You need to enable OPENCV to compile this file. Please reconfigure MIP with USE_OPENCV (jw)
31 #include <Base/Common/W32Compat.hh>
37 #ifndef CV_CALIB_ZERO_TANGENT_DIST
38 # error Your OpenCV version is probably too old because CV_CALIB_ZERO_TANGENT_DIST seems to be unsupported. Try again with OpenCV version >=beta5a
41 #define DRAW_IDEAL_OVERLAY
42 #define DRAW_POINT_LABEL
59 # include "Utils/ThreeDOut.hh"
63 #include <Base/Debug/Error.hh>
64 #include <Base/Common/FileHandling.hh>
65 #include <Base/Math/Vector3.hh>
66 #include <Base/Image/ImageIO.hh>
67 #include <Base/Image/ImageConvert.hh>
68 #include <Geometry/RMatrix.hh>
69 #include <Geometry/PMatrix.hh>
70 #include <Geometry/Pose.hh>
71 #include <Utils/Param.hh>
118 CvPoint2D32f * ConvertWorldToPixel(CvPoint3D32f *pts3d,
119 int numImages,
int *numPts,
120 CvMatr32f cam, CvVect32f t, CvMatr32f r,
121 int xCorners,
int yCorners)
124 CvPoint2D32f *pts2d =
new CvPoint2D32f[numImages * xCorners * yCorners];
126 CvMat *C = cvCreateMat(3, 3, CV_32FC1);
127 CvMat *point3D = cvCreateMat(3, 1, CV_32FC1);
128 CvMat *R = cvCreateMat(3, 3, CV_32FC1);
129 CvMat *T = cvCreateMat(3, 1, CV_32FC1);
131 CvPoint3D32f *pts3dCur = pts3d;
132 CvPoint2D32f *pts2dCur = pts2d;
134 for (i = 0; i < 3; i++) {
135 for (j = 0; j < 3; j++) {
136 CV_MAT_ELEM(*C,
float, i, j) = cam[3 * i + j];
140 for (k = 0; k < numImages; k++) {
141 for (j = 0; j < 9; j++) {
142 if (j < 3) CV_MAT_ELEM(*T,
float, j, 0) = t[k*3 + j];
143 CV_MAT_ELEM(*R,
float, j / 3, j%3) = r[k*9 + j];
145 for (i = 0; i < numPts[k]; i++) {
146 CV_MAT_ELEM(*point3D,
float, 0, 0) = pts3dCur[i].x;
147 CV_MAT_ELEM(*point3D,
float, 1, 0) = pts3dCur[i].y;
148 CV_MAT_ELEM(*point3D,
float, 2, 0) = pts3dCur[i].z;
150 cvMatMulAdd(R, point3D, T, point3D);
151 cvMatMul(C, point3D, point3D);
153 pts2dCur[i].x = CV_MAT_ELEM(*point3D,
float, 0, 0) /
154 CV_MAT_ELEM(*point3D,
float, 2, 0);
155 pts2dCur[i].y = CV_MAT_ELEM(*point3D,
float, 1, 0) /
156 CV_MAT_ELEM(*point3D,
float, 2, 0);
158 pts3dCur += numPts[k];
159 pts2dCur += numPts[k];
162 cvReleaseMat(&point3D);
175 void DrawPoints(CvArr *img, CvPoint2D32f *ptArray,
int numPts,
176 const int xCorners,
const int yCorners)
180 #ifdef DRAW_POINT_LABEL
182 cvInitFont(&font, CV_FONT_HERSHEY_PLAIN, 1.0f, 1.0f);
183 #endif //DRAW_POINT_LABEL
187 ptOld.x = (int)ptArray[0].x;
188 ptOld.y = (int)ptArray[0].y;
190 for (
int i = 0; i < numPts; i++) {
191 int clr = (int)((
float)i / numPts * 255.0);
192 pt.x = (int)ptArray[i].x;
193 pt.y = (int)ptArray[i].y;
194 cvCircle(img, pt, 3, CV_RGB(255-clr,0,clr), CV_FILLED);
196 #ifdef DRAW_POINT_LABEL
200 cvPutText(img, ssID.str().c_str(), pt, &font, CV_RGB(0,0,255));
201 #endif //DRAW_POINT_LABEL
206 #ifdef DRAW_IDEAL_OVERLAY
209 for (
int xx = 0; xx < xCorners*yCorners; xx+=xCorners) {
210 cvLine(img, cvPointFrom32f(ptArray[xx]),
211 cvPointFrom32f(ptArray[xx+xCorners-1]),
212 CV_RGB(0,0,255), 1, CV_AA);
215 for (
int yy = 0; yy < xCorners; yy+=1) {
216 cvLine(img, cvPointFrom32f(ptArray[yy]),
217 cvPointFrom32f(ptArray[yy+xCorners*(yCorners-1)]),
218 CV_RGB(0,0,255), 1, CV_AA);
224 cvInitFont(&fontBig, CV_FONT_HERSHEY_PLAIN, 5.0f, 5.0f, 0, 2, CV_AA);
225 cvPutText(img,
"0", cvPointFrom32f(ptArray[0]), &fontBig, CV_RGB(0,0,255));
226 cvLine(img, cvPointFrom32f(ptArray[0]), cvPointFrom32f(ptArray[xCorners-1]),
227 CV_RGB(255,0,0), 1, CV_AA);
228 cvPutText(img,
"X", cvPointFrom32f(ptArray[xCorners-1]),
229 &fontBig, CV_RGB(255,0,0));
230 cvLine(img, cvPointFrom32f(ptArray[0]),
231 cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
232 CV_RGB(0,255,0), 1, CV_AA);
233 cvPutText(img,
"Y", cvPointFrom32f(ptArray[xCorners*(yCorners-1)]),
234 &fontBig, CV_RGB(0,255,0));
243 void InitCorners3d(CvPoint3D32f *corners3d,
int xCorners,
244 int yCorners,
int numImages)
247 int nStride = xCorners * yCorners;
248 for (n = 0; n < numImages; n++) {
249 for (x = 0; x < xCorners; x++) {
250 for (y = 0; y < yCorners; y++) {
251 corners3d[n*nStride + x +xCorners*y].x = (float)x;
252 corners3d[n*nStride + x +xCorners*y].y = (float)y;
253 corners3d[n*nStride + x +xCorners*y].z = 0.0f;
264 void InitCorners3dMatrix(CvMat *corners3dMat,
265 int xCorners,
int yCorners,
int numImages)
268 int offset=xCorners * yCorners;
269 for (n = 0; n < numImages; n++) {
270 for (x = 0; x < xCorners; x++) {
271 for (y = 0; y < yCorners; y++) {
272 CV_MAT_ELEM(*corners3dMat,
float,n*offset+x+ y*xCorners, 0) = (float)x;
273 CV_MAT_ELEM(*corners3dMat,
float,n*offset+x+ y*xCorners, 1) = (float)y;
274 CV_MAT_ELEM(*corners3dMat,
float,n*offset+x+ y*xCorners, 2) = 0.0f;
281 void InitCorners2dPointMatrix(CvMat *points2dMat,CvPoint2D32f *cornersArray,
282 CvMat *pointCounts,
int* cornersFound,
286 for (n = 0; n < numImages; n++) {
287 int corners=cornersFound[n];
288 CV_MAT_ELEM(*pointCounts,
int,n,0)=corners;
289 for (x = 0; x < corners; x++) {
290 CV_MAT_ELEM(*points2dMat,
float,row+x,0) = cornersArray[row+x].x;
291 CV_MAT_ELEM(*points2dMat,
float,row+x,1) = cornersArray[row+x].y;
299 const float * translation_vectors,
300 const unsigned int numImages)
302 BIASASSERT(translation_vectors!=NULL);
303 BIASASSERT(camIndex<numImages);
305 for (
unsigned int k=0; k<3; k++)
306 C.
GetData()[k] = translation_vectors[camIndex*3 +k];
312 const float * rotation_matrices,
313 const unsigned int numImages)
315 BIASASSERT(rotation_matrices!=NULL);
316 BIASASSERT(camIndex<numImages);
318 for (
unsigned int k=0; k<9; k++)
319 R.
GetData()[k] = rotation_matrices[camIndex*9 +k];
326 BIASASSERT(camera_matrix!=NULL);
328 for (
unsigned int i=0; i<9; i++)
329 K.
GetData()[i] = camera_matrix[i];
335 const float * rotation_matrices,
336 const float * translation_vectors,
337 const unsigned int numImages)
341 BIASASSERT(rotation_matrices!=NULL);
342 BIASASSERT(translation_vectors!=NULL);
343 BIASASSERT(camIndex<numImages);
348 void PrintIntrinsics(CvVect32f distortion,
349 CvMatr32f camera_matrix,
352 BIASASSERT(distortion!=NULL);
353 os <<
"Distortion coefficients:" << endl
355 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[0]<<endl
357 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[1]<<endl
359 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[2]<<endl
361 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[3]<<endl;
363 BIASASSERT(camera_matrix != NULL);
364 os <<
"Camera matrix K:" << endl;
366 os <<
" " << GetKfromArr(camera_matrix) << endl;
370 void PrintDistortionVec4(CvVect32f distortion,
373 BIASASSERT(distortion!=NULL);
375 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[0]<<endl
376 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[1]<<endl
377 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[2]<<endl
378 << setw(DIGW)<<setprecision(DIGPREC)<<distortion[3]<<endl;
397 void PrintExtrinsics(
const float * translation_vectors,
398 const float * rotation_matrices,
399 const unsigned int numImages,
402 BIASASSERT(translation_vectors != NULL);
403 BIASASSERT(rotation_matrices != NULL);
407 for (
unsigned int i = 0; i < numImages; i++) {
408 tmpRcv = GetRfromArr(i, rotation_matrices, numImages);
409 tmpCcv = GetCfromArr(i, translation_vectors, numImages);
410 Rbias = R_cv2bias(tmpRcv);
411 Cbias = C_cv2bias(tmpCcv, tmpRcv);
412 os <<
"[" << i <<
"] R = " << Rbias <<
"\tC = " << Cbias << endl;
417 void usage(
int argc,
char** argv)
419 cout<<
"Usage: calibrateCamera <inner_chessboard_corners_X> "
420 <<
"<inner_chessboard_cornersY> [all-image-filenames]"<<endl
421 <<
" with at least 2 inner chessboard corners and "
422 <<
"*non-symmetric* chessboard pattern. "<<endl
423 <<
" In particular 8x8 is *NOT* OK while 8x7 is good."<<endl
425 <<
"Sample usage:"<<endl
426 <<
" calibrateCamera 7 4 a.jpg b.jpg c.jpg d.jpg e.jpg "<<endl
427 <<
"or special dart test modus:"<<endl
428 <<
" calibrateCamera --darttest [0|1] a.jpg b.jpg c.jpg d.jpg e.jpg ..."<<endl
430 <<
"(c) MIP University of Kiel"<<endl
431 <<
"Jan Woetzel (www.mip.informatik.uni-kiel.de/~jw)"<<endl
432 <<
"feel free to ask me fo details."<<endl;
438 int main(
int argc,
char** argv)
441 cout<<
"Started "<<argv[0]<<
"\n(c) MIP University of Kiel, Jan Woetzel"<<endl;
443 IplImage *image = NULL;
444 IplImage *undistort = NULL;
445 IplImage *gray = NULL;
446 CvPoint2D32f *cornersArray = NULL;
448 CvPoint3D32f *corners3d = NULL;
449 CvVect32f translation_vectors = NULL;
450 CvMatr32f rotation_matrices = NULL;
456 params.
AddParamBool(
"fixedAspect",
"focal length is euqal in both directions",
459 "principal point is fixed in image center",
461 params.
AddParamBool(
"fixedAll",
"only calibrate extrinsic parameters, "
462 "KMatrix must be given, distortion is optional",
464 params.
AddParamString(
"kmatrix",
"file name of K-matrix with inital values,"
465 " which are unchanged if fixedAll",
"",
'K');
466 params.
AddParamString(
"distortion",
"file name of vector with distortion "
467 " values (radial k1, k2, tangential p1,p2)",
473 BIASASSERT(nextParam >= 0);
476 if ((argc-nextParam<3) && (params.
GetParamString(
"darttest")->size()==0)) {
486 flags |= CV_CALIB_ZERO_TANGENT_DIST;
491 cerr <<
"Error opening KMatrix file "
496 flags |= CV_CALIB_USE_INTRINSIC_GUESS;
499 flags |= CV_CALIB_FIX_ASPECT_RATIO;
501 flags |= CV_CALIB_FIX_PRINCIPAL_POINT;
507 cerr <<
"Error opening distortion file "
511 in >> biasDistortion;
512 cout <<
"User given distortion values:" << biasDistortion << endl;
522 bool darttest =
false;
524 if (strcmp(argv[1],
"--darttest") == 0) {
525 std::cout <<
"Started dart test for " << argv[0] << std::endl;
529 if (argv[2][0] ==
'1') {
537 xCorners = atoi(argv[nextParam]);
540 cout<<
"[ERROR] xCorners = "<<xCorners<<
" is invalid!"<<endl;
541 yCorners = atoi(argv[nextParam]);
544 cout<<
"[ERROR] yCorners = "<<yCorners<<
" is invalid!"<<endl;
549 if ((xCorners<=2) || (yCorners<=2)) {
555 numImages = argc - nextParam;
558 cornersArray =
new CvPoint2D32f[xCorners*yCorners*numImages];
559 corners3d =
new CvPoint3D32f[xCorners*yCorners*numImages];
560 int *cornersFound =
new int[numImages];
561 translation_vectors =
new float[3*numImages];
562 rotation_matrices =
new float[9*numImages];
563 InitCorners3d(corners3d, xCorners, yCorners, numImages);
566 CvMat *corners3dMat = cvCreateMat(xCorners*yCorners*numImages,3, CV_32FC1);
567 InitCorners3dMatrix(corners3dMat, xCorners, yCorners, numImages);
570 cvNamedWindow(
"Image", CV_WINDOW_AUTOSIZE);
571 cvMoveWindow(
"Image", 0,0);
573 CvPoint2D32f *nextCornersArray = cornersArray;
576 string outFilenameVRML(
"out_allP.wrl");
584 for (iImg = 0; iImg < numImages; iImg++) {
585 BIASASSERT((iImg+nextParam)<argc);
586 imgFilename = argv[iImg+nextParam];
588 cout <<
"Loading " << imgFilename << endl;
590 BIASERR(
"BIAS::ImageIO failed to load image " << imgFilename
591 <<
". Now trying OpenCV routines...");
592 image = cvLoadImage(imgFilename.c_str());
594 BIASERR(
"OpenCV failed to load " << imgFilename <<
" either. Aborting!");
599 #ifdef BIAS_HAVE_OPENCV
603 BIASERR(
"case not implemented.");
606 BIASASSERT(image!=NULL);
607 width = image->width;
608 height = image->height;
610 if (image->depth != IPL_DEPTH_8U) {
611 cerr <<
"[ERROR] Depth is not IPL_DEPTH_8U for image "
612 << imgFilename <<
"!" << endl;
617 if (image->nChannels == 1 && image->depth == IPL_DEPTH_8U) {
618 gray = cvCloneImage(image);
620 gray = cvCreateImage(cvSize(image->width, image->height),
622 BIASASSERT(gray!=NULL);
623 cvConvertImage(image, gray);
628 cvShowImage(
"Image", image);
631 cornersFound[iImg] = xCorners * yCorners;
648 int res = cvFindChessboardCorners(gray, cvSize(xCorners, yCorners),
651 CV_CALIB_CB_ADAPTIVE_THRESH);
655 cvFindCornerSubPix(gray, nextCornersArray,
656 cornersFound[iImg], cvSize(5,5), cvSize(-1,-1),
657 cvTermCriteria(CV_TERMCRIT_ITER, 100, 0.1));
660 DrawPoints(image, nextCornersArray, cornersFound[iImg], xCorners, yCorners);
662 cvShowImage(
"Image", image);
668 cvSaveImage(outFilename.c_str(), image);
671 cerr<<
"[ERROR] Could not find all "<<xCorners<<
"x"<<yCorners
672 <<
" inner corners of checkerboard in image "<<imgFilename << endl
673 <<
" but actually checkerboard has to be detectable"
674 <<
" in *all* images!"<<endl<<
" Please remove image "
675 <<imgFilename<<
" and try again!"<<endl;
676 cerr<<
"Press any key in GUI window."<<endl;
681 nextCornersArray += cornersFound[iImg];
686 cvReleaseImage(&image);
687 cvReleaseImage(&gray);
689 if (usegui) cvDestroyWindow(
"Image");
691 cout<<
"Solving calibration... "<<flush;
708 for (
int i = 0;i < numImages; i++) {
709 totalpoints += cornersFound[i];
711 CvMat *points2dMat = cvCreateMat(totalpoints, 2, CV_32FC1);
712 CvMat *pointCountMat = cvCreateMat(numImages, 1, CV_32SC1);
713 InitCorners2dPointMatrix(points2dMat, cornersArray, pointCountMat,
714 cornersFound, numImages);
715 CvMat *camMatrix = cvCreateMat(3,3,CV_32FC1);
717 cvInitMatHeader(camMatrix,3,3,CV_32FC1, camera_matrix.
GetData());
719 cvmSetZero(camMatrix);
720 CV_MAT_ELEM(*camMatrix,
float,0,0) = 600.;
721 CV_MAT_ELEM(*camMatrix,
float,1,1) = 600.;
722 CV_MAT_ELEM(*camMatrix,
float,0,2) = float(width/2.);
723 CV_MAT_ELEM(*camMatrix,
float,1,2) = float(height/2.);
724 CV_MAT_ELEM(*camMatrix,
float,2,2) = 1.;
727 CvMat *distortMatrix = cvCreateMat(4,1,CV_32FC1);
729 cvInitMatHeader(distortMatrix,4,1,CV_32FC1, biasDistortion.GetData());
731 cvmSetZero(distortMatrix);
734 CvMat *rotVectors = cvCreateMat(numImages,3,CV_32FC1);
735 CvMat *transVectors = cvCreateMat(numImages,3,CV_32FC1);
738 CvMat *rotVector = cvCreateMat(1,3,CV_32FC1);
739 CvMat *transVector = cvCreateMat(1,3,CV_32FC1);
741 for (
int n=0; n<numImages; n++) {
743 int nrPoints = CV_MAT_ELEM(*pointCountMat,
int,n,0);
744 CvMat *points3DSingleView = cvCreateMat(nrPoints,3,CV_32FC1);
745 CvMat *points2DSingleView = cvCreateMat(nrPoints,2,CV_32FC1);
746 for (
int p=0; p < nrPoints; p++) {
748 for (r=0; r < 2; r++) {
749 CV_MAT_ELEM(*points2DSingleView,
float,p,r) =
750 CV_MAT_ELEM(*points2dMat,
float,nextPoint+p,r);
752 for (r=0; r < 3; r++) {
753 CV_MAT_ELEM(*points3DSingleView,
float,p,r) =
754 CV_MAT_ELEM(*corners3dMat,
float,nextPoint+p,r);
758 cvFindExtrinsicCameraParams2(
759 points3DSingleView, points2DSingleView,
760 camMatrix, distortMatrix,
761 rotVector, transVector);
762 for (
int r=0; r < 3; r++) {
763 CV_MAT_ELEM(*rotVectors,
float,n,r) =
764 CV_MAT_ELEM(*rotVector,
float,0,r);
765 CV_MAT_ELEM(*transVectors,
float,n,r) =
766 CV_MAT_ELEM(*transVector,
float,0,r);
770 cvCalibrateCamera2(corners3dMat, points2dMat,
771 pointCountMat, cvSize(width, height),
772 camMatrix, distortMatrix,
773 rotVectors, transVectors, flags);
776 for (
unsigned int i=0;i<3;i++) {
777 for (
unsigned int j=0;j<3;j++) {
778 camera_matrix[i][j]= CV_MAT_ELEM(*camMatrix,
float,i,j);
781 memcpy(distortion.
GetData(),distortMatrix->data.fl,
sizeof(float)*4);
782 CvMat *dummyRot= cvCreateMat(1,3,CV_32FC1);
783 CvMat *dummyRes= cvCreateMat(3,3,CV_32FC1);
784 for (
int i=0; i<numImages; i++) {
785 dummyRot->data.fl= &(rotVectors->data.fl[i*3]);
786 cvRodrigues2( dummyRot, dummyRes);
787 memcpy(&rotation_matrices[i*9],dummyRes->data.fl,
sizeof(
float)*9);
788 translation_vectors= transVectors->data.fl;
790 cout<<
" done."<<endl;
793 PrintExtrinsics(translation_vectors, rotation_matrices, numImages,std::cout);
795 ofstream ofs(
"out_extrinsics.txt");
796 PrintExtrinsics(translation_vectors, rotation_matrices, numImages, ofs);
797 cout<<
"Wrote result to file out_extrinsics.txt"<<endl;
800 PrintIntrinsics(distortion.
GetData(),
804 ofstream ofs(
"out_intrinsics.txt");
805 PrintIntrinsics(distortion.
GetData(),
808 cout<<
"Wrote result to file out_intrinsics.txt"<<endl;
813 ofstream ofs(
"out_distortion.txt");
814 PrintDistortionVec4(distortion.
GetData(), ofs);
815 cout<<
"Wrote result to file out_intrinsics.txt"<<endl;
822 Kbi = GetKfromArr(camera_matrix.
GetData());
823 Kbi.
Save(
"out_Kmat.K");
831 for (iImg = 0; iImg < numImages; iImg++) {
832 Rbi = R_cv2bias(GetRfromArr(iImg,rotation_matrices, numImages));
833 Cbi = C_cv2bias(GetCfromArr(iImg, translation_vectors, numImages),
834 GetRfromArr(iImg,rotation_matrices, numImages));
839 ofs.open(imgFilename.c_str());
846 ofs.open(imgFilename.c_str());
853 ofs.open(imgFilename.c_str());
861 CameraVRML.AddPMatrix(Pbi, width, height,
RGBAuc(0,0,255,0));
863 CameraVRML.AddLine(lastC, Cbi,
RGBAuc(255,255,0,0));
866 CameraVRML.AddPMatrix(Pbi, width, height,
RGBAuc(0,255,0,0));
867 CameraVRML.AddLine(lastC, Cbi,
RGBAuc(255,0,0,0));
874 cout<<
"Wrote results to out_*.Rmat, out_*.Cmat and out_*.P"<<endl;
877 const double scale=1.0;
887 CameraVRML.VRMLOut(outFilenameVRML);
888 cout<<
"wrote vrml \""<<outFilenameVRML<<
"\""<<endl;
891 CvPoint2D32f *backprojPts2d =
892 ConvertWorldToPixel(corners3d, numImages, cornersFound,
893 camera_matrix.
GetData(), translation_vectors,
894 rotation_matrices, xCorners, yCorners);
897 cvNamedWindow(
"Undistorted", CV_WINDOW_AUTOSIZE);
898 cvMoveWindow(
"Undistorted", 0,0);
899 cout<<
"Opened GUI"<<endl;
902 for (iImg = 0; iImg < numImages; iImg++) {
904 imgFilename = argv[iImg+nextParam];
906 #ifdef BIAS_HAVE_OPENCV
909 BIASERR(
"No support to convert image loaded by BIAS into OpenCV format!");
912 BIASERR(
"Failed to load image with BIAS! Trying OpenCV routines, now...");
913 image = cvLoadImage(imgFilename.c_str());
915 BIASERR(
"Failed to load image " << imgFilename
916 <<
"with OpenCV either! Aborting.");
921 cout <<
"Loaded and converted image " << imgFilename.c_str() <<
"." << endl;
924 undistort = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U,
926 cvUndistort2(image, undistort, camMatrix, distortMatrix);
928 DrawPoints(image, &backprojPts2d[iImg*cornersFound[iImg]],
929 cornersFound[iImg], xCorners,yCorners);
931 cvShowImage(
"Image", image);
934 DrawPoints(undistort, &backprojPts2d[iImg*cornersFound[iImg]],
935 cornersFound[iImg], xCorners,yCorners);
937 cvShowImage(
"Undistorted", undistort);
940 cout <<
"Drawed checkerboard corners into image" << endl;
942 cvSaveImage(outFilename.c_str(), image);
945 cvSaveImage(outFilename.c_str(), undistort);
947 cout <<
"Wrote images to files" << endl;
948 cvReleaseImage(&image);
949 cvReleaseImage(&undistort);
951 cout <<
"Wrote backprojected images to files" << endl;
956 <<
"<DartMeasurementFile name=\"chess7x4_003_"
957 <<
"findChessBoardCornerGuesses.jpg\" type=\"image/jpeg\">"
958 <<
"chess7x4_003_findChessBoardCornerGuesses.jpg"
959 <<
"</DartMeasurementFile>"<<endl
960 <<
"<DartMeasurementFile name=\"chess7x4_003_backproject_"
961 <<
"undistorted.jpg\" type=\"image/jpeg\">chess7x4_003_backproject_"
962 <<
"undistorted.jpg</DartMeasurementFile>"<<endl;
966 ofstream outXML(
"out_cameraParam.xml");
967 outXML<<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>"<<endl;
968 outXML<<
"<!-- File created from MIP/calibrateIntrinsics with K-Matrix"<<endl;
969 for (
unsigned int i=0;i<3; i++) {
970 for (
unsigned int j=0;j<3; j++) {
971 outXML<<setw(DIGW)<<setprecision(DIGPREC)<<Kbi[i][j]<<
" ";
976 outXML<<
" <camera version=\"2.0\">"<<endl;
977 outXML<<
"<!--\"Model\" is an arbitrary camera name. "<<endl;
978 outXML<<
" \"SerialID\" is i.e. the camera firewire-bus ID."<<endl;
979 outXML<<
" \"ImageWidth\" and \"ImageHeight\" are in pixel."<<endl;
980 outXML<<
" \"CellSizeX\" is the size of one CCD-cell in meter."<<endl;
981 outXML<<
" \"AspectRatio\" is CellsizeX/CellSizeY "
982 <<
"(same as FocalLengthY/FocalLengthX).-->"<<endl;
983 outXML<<
" <Sensor AspectRatio=\""
984 <<setprecision(10)<<Kbi[1][1]/Kbi[0][0]<<
"\""<<endl;
987 outXML<<
" ImageHeight=\""<<height<<
"\" ImageWidth=\""<<width<<
"\""<<endl;
988 outXML<<
" SerialID=\"666\" />"<<endl;
989 outXML<<
" <!--\"Model\" is an arbitrary name. \"Type\" can be either "
990 <<
"\"Spherical\" or \"Perspective\"--> "<<endl;
991 outXML<<
" <Lens Model=\"not specified\" Type=\"Perspective\" > "<<endl;
992 outXML<<
" <PerspectiveCalib>"<<endl;
993 outXML<<
" <!--\"FocalLength\" is FocalLengthX in meters, "
994 <<
"if you want to give it in pixel set \"CellSizeX\"=1."<<endl;
995 outXML<<
" k1 and k2 are radial distortion; p1, p2 are "
996 <<
" tangential distortion. -->"<<endl;
997 outXML<<
" <Default p1=\"0\" p2=\"0\" k1=\""
998 <<setprecision(10)<<distortion[0]<<
"\" k2=\""<< setprecision(10)
999 <<distortion[1]<<
"\" FocalLength=\""<<Kbi[0][0]<<
"\" />"<<endl;
1000 outXML<<
" </PerspectiveCalib>"<<endl;
1001 outXML<<
" <VignetteCalib>"<<endl;
1002 outXML<<
" <!--The measurements for vignette calibration relate the "
1003 <<
"distance of a pixel from the image principal point to an absorbtion "
1004 <<
"factor for the corresponding image pixels.--> "<<endl;
1005 outXML<<
" </VignetteCalib>"<<endl;
1006 outXML<<
" </Lens>"<<endl;
1007 outXML<<
" <!--The \"PrincipalPoint\" is given as a fraction of "
1008 <<
"\"ImageWidth\"/\"ImageHeight\" with (0.5,0.5) is the image center.-->"
1010 outXML<<
" <PrincipalPoint X=\""
1011 <<setprecision(10)<<Kbi[0][2]/(double)(width-1)<<
"\" "<<endl;
1013 <<setprecision(10)<<Kbi[1][2]/(double)(height-1)<<
"\" />"<<endl;
1014 outXML<<
" </camera>"<<endl;
1017 cout<<
"MIP camera parameter file written to out_cameraParam.xml" << endl;
1023 Rbi.GetQuaternion(quat);
1025 std::vector<double> distortionDouble(4,0.0);
1026 distortionDouble[0] = distortion[0];
1027 distortionDouble[1] = distortion[1];
1028 distortionDouble[2] = distortion[2];
1029 distortionDouble[3] = distortion[3];
1034 #ifdef BIAS_HAVE_XML2
1036 xmlNodePtr root = tree.
create(
"Projection");
1043 if (tree.
write(
"out_projParam.xml") == 0){
1044 cout <<
"MIP projection parameter file written to out_projParam.xml" << endl;
1048 cout <<
"Failed to write MIP projection parameter file to "
1049 <<
"out_projParam.xml!" << endl;
1053 if (usegui) cvDestroyAllWindows();
1054 delete cornersArray;
1056 delete cornersFound;
void addAttribute(const xmlNodePtr Node, const std::string &AttributeName, bool AttributeValue)
Add an attribute to a node.
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn't change the ...
int write(const std::string &Filename, bool AutoAddCompressionSuffix=true) const
Write the whole tree that was constructed in memory to disk.
int Set(const PoseParametrization &pose)
Set pose from pose parametrization.
void SetZero()
set all values to 0
Unified output of 3D entities via OpenGL or VRML.
void DisableDestructorWarning()
Uses this just before end of your program to avoid error from destructor.
xmlNodePtr create(const std::string &RootNodeName)
Create the base of a new XML-Tree in memory, already with a one and only root node.
void SetZero()
set all values to 0
bool * AddParamBool(const std::string &name, const std::string &help, bool deflt=false, char cmdshort=0, int Group=GRP_NOSHOW)
configuration struct for drawing styles of various 3d objects
int ParseCommandLine(int &argc, char *argv[])
scan command line arguments for valid parameters
bool * GetParamBool(const std::string &name) const
bool Save(const std::string &fname) const
void Usage(std::ostream &os=std::cout)
print Help-Information to stdout
Represents 3d pose transformations, parametrized as Euclidean translation and unit quaternion orienta...
Wrapper class for reading and writing XML files based on the XML library libxml2. ...
static std::string Basename(const std::string &fullname)
Get file base name without path from given path and filename.
This class hides the underlying projection model, like projection matrix, spherical camera...
std::string * GetParamString(const std::string &name) const
void SetIdentity()
set the elements of this matrix to the matrix 1 0 0 0 0 1 0 0 0 0 1 0 which is no strict identity (!)...
BIAS::Vector4< unsigned char > RGBAuc
class BIASGeometry_EXPORT PMatrix
is a 'fixed size' quadratic matrix of dim.
virtual int XMLOut(const xmlNodePtr Node, XMLIO &XMLObject) const
specialization of XML write function for BIAS::Projection.
This class Param provides generic support for parameters.
Matrix3x3< T > Transpose() const
returns transposed matrix tested 12.06.2002
const T * GetData() const
get the data pointer the member function itself is const (before {..}) because it doesn't change the...
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
BIAS_ProjParaPersp_DISTORTION_TYPE
static int BIAS2ipl(const Image< StorageType > &source, IplImage *&dest)
Returns a new, separate IplImage for use with OpenCV created rom the source BIAS Image.
K describes the mapping from world coordinates (wcs) to pixel coordinates (pcs).
void CreatePerspective(const BIAS::Pose &pose, const BIAS::KMatrix &K, int width, int height, BIAS_ProjParaPersp_DISTORTION_TYPE radDistType=DISTYPE_DEF, const std::vector< double > &UndistortionCoefficients=std::vector< double >(4, 0.0))
Create a perspective camera and add to projection.
int SetEnhancedFlag(const std::string &name, bool enhanced)
if a parametr is marked as enhanced, it is hidden from the naive user
describes a projective 3D -> 2D mapping in homogenous coordinates
std::string * AddParamString(const std::string &name, const std::string &help, std::string deflt="", char cmdshort=0, int Group=GRP_NOSHOW)
void SetIdentity()
set the elements of this matrix to the identity matrix (possibly overriding the inherited method) ...