PageRenderTime 80ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/slam6d/trunk-external/src/pmd/calibrate/calibrate.cc

https://github.com/AsherBond/MondocosmOS
C++ | 139 lines | 86 code | 33 blank | 20 comment | 10 complexity | fa9dbdf0e6044d93e9d0e71af94dd5dd MD5 | raw file
  1. #include <stdio.h>
  2. #include <cv.h>
  3. #include <highgui.h>
  4. void usage(char *progName) {
  5. printf("%s <board-size-x> <board-size-y> <square-size> <images-list>\n", progName);
  6. printf("\twhere board-size-x and y is count of *inner* corners of the booard");
  7. printf("i.e.: %s 6 4 0.04 image*\n", progName);
  8. printf("Use more then ten images.\nPress space bar to proceed.\n");
  9. }
  10. void calibrate( CvMat *intrinsic, CvMat *distortion, CvSize imgSz, CvSize boardSz
  11. , double boardSide, CvPoint2D32f **corners, int boardsCnt) {
  12. int totalPoints = boardSz.width * boardSz.height;
  13. // object points (model)
  14. CvMat *objPts = cvCreateMat(totalPoints * boardsCnt, 3, CV_32FC1);
  15. // found points
  16. CvMat *imgPts = cvCreateMat(totalPoints * boardsCnt, 2, CV_32FC1);
  17. // points count
  18. CvMat *ptsCnt = cvCreateMat(boardsCnt, 1, CV_32SC1);
  19. // copy corners to matrix and fill model matrix
  20. for(int i = 0; i < boardsCnt; i++) {
  21. for(int j = 0; j < totalPoints; j++) {
  22. int s = i * totalPoints;
  23. CV_MAT_ELEM(*imgPts, float, s+j, 0) = corners[i][j].x;
  24. CV_MAT_ELEM(*imgPts, float, s+j, 1) = corners[i][j].y;
  25. CV_MAT_ELEM(*objPts, float, s+j, 0) = boardSide * (j / boardSz.width);
  26. CV_MAT_ELEM(*objPts, float, s+j, 1) = boardSide * (j % boardSz.width);
  27. CV_MAT_ELEM(*objPts, float, s+j, 2) = 0.0f;
  28. }
  29. CV_MAT_ELEM(*ptsCnt, int, i, 0) = totalPoints;
  30. }
  31. // initial guess
  32. CV_MAT_ELEM(*intrinsic, float, 0, 0) = 1.0f;
  33. CV_MAT_ELEM(*intrinsic, float, 1, 1) = 1.0f;
  34. cvCalibrateCamera2( objPts, imgPts, ptsCnt, imgSz
  35. , intrinsic, distortion
  36. , NULL, NULL, 0 );
  37. return;
  38. }
  39. int main(int argc, char **argv)
  40. {
  41. if(argc < 5) {
  42. usage(argv[0]);
  43. exit(1);
  44. }
  45. int patx = atoi(argv[1]);
  46. int paty = atoi(argv[2]);
  47. CvSize boardSz = cvSize(patx, paty);
  48. int loadImageCnt = argc - 4;
  49. int cornersTotal = boardSz.width * boardSz.height;
  50. float boardSide = atof(argv[3]);;
  51. char **images = &argv[4];
  52. // intrinsic matrices and ditortion params
  53. CvMat *intrinsic = cvCreateMat(3, 3, CV_32F);
  54. CvMat *distortion = cvCreateMat(1, 4, CV_32F);
  55. IplImage *img = cvLoadImage(images[0], CV_LOAD_IMAGE_GRAYSCALE);
  56. IplImage *imgColor = cvCreateImage(cvGetSize(img), 8, 3);
  57. int subpixel;
  58. if(cvGetSize(img).width < 300) {
  59. subpixel = 4;
  60. }
  61. else {
  62. subpixel = 11;
  63. }
  64. int imagesWithBoard = 0;
  65. CvPoint2D32f **corners = (CvPoint2D32f**)calloc(100, sizeof(CvPoint2D32f*));
  66. corners[0] = (CvPoint2D32f*) malloc(cornersTotal * sizeof(CvPoint2D32f));
  67. cvNamedWindow("Cam", 0);
  68. for(int imagesLoaded = 0; imagesLoaded < loadImageCnt; imagesLoaded++) {
  69. img = cvLoadImage(images[imagesLoaded], CV_LOAD_IMAGE_GRAYSCALE);
  70. cvCvtColor(img, imgColor, CV_GRAY2BGR);
  71. int cornersCount;
  72. int found = cvFindChessboardCorners(img, boardSz, corners[imagesWithBoard],
  73. &cornersCount, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);
  74. if(found) cvFindCornerSubPix(img, corners[imagesWithBoard], cornersCount, cvSize(subpixel, subpixel), cvSize(-1,-1),
  75. cvTermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
  76. if(found && (cornersCount == cornersTotal)) {
  77. cvDrawChessboardCorners(imgColor, boardSz, corners[imagesWithBoard], cornersCount, found);
  78. imagesWithBoard++;
  79. corners[imagesWithBoard] = (CvPoint2D32f*) malloc(cornersTotal * sizeof(CvPoint2D32f));
  80. }
  81. cvShowImage("Cam", imgColor);
  82. cvWaitKey(0);
  83. }
  84. cvDestroyAllWindows();
  85. printf("calibrating...\n");
  86. fflush(stdout);
  87. //TODO: can be started in parallel to watch calibration on image undistortion :)
  88. calibrate(intrinsic, distortion, cvGetSize(img), boardSz, boardSide, corners, imagesWithBoard);
  89. // save to xml files
  90. cvSave("./intrinsic.xml", intrinsic);
  91. cvSave("./distortion.xml", distortion);
  92. printf("matrices saved to xml files.\n");
  93. // let OS clean all images and matrices
  94. return 0;
  95. }
  96. /*void usage(char *progName) {
  97. printf( "usage:\n \
  98. %s <x> <y> <camera-id> [-s]\n \
  99. \tcamera-id is v4l id or -1 for pmd cam \
  100. \tpress space or 'a' to grab image\n \
  101. \tpress 'n' to skip grabbed frame\n \
  102. \tpress 'c' to finish frame grabbing start calibration\n \
  103. or:\n \
  104. %s <x> <y> <image1cam.jpg, image1pmd.jpg, image2cam.png...>\n", progName, progName);
  105. fflush(stdout);
  106. }*/