detect_board.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include <iostream>
  2. #include <vector>
  3. #include <opencv2/highgui.hpp>
  4. #include <opencv2/objdetect/aruco_detector.hpp>
  5. #include "aruco_samples_utility.hpp"
  6. using namespace std;
  7. using namespace cv;
  8. namespace {
  9. const char* about = "Pose estimation using a ArUco Planar Grid board";
  10. //! [aruco_detect_board_keys]
  11. const char* keys =
  12. "{w | | Number of squares in X direction }"
  13. "{h | | Number of squares in Y direction }"
  14. "{l | | Marker side length (in pixels) }"
  15. "{s | | Separation between two consecutive markers in the grid (in pixels)}"
  16. "{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2,"
  17. "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
  18. "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
  19. "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
  20. "{cd | | Input file with custom dictionary }"
  21. "{c | | Output file with calibrated camera parameters }"
  22. "{v | | Input from video or image file, if omitted, input comes from camera }"
  23. "{ci | 0 | Camera id if input doesnt come from video (-v) }"
  24. "{dp | | File of marker detector parameters }"
  25. "{rs | | Apply refind strategy }"
  26. "{r | | show rejected candidates too }";
  27. }
  28. //! [aruco_detect_board_keys]
  29. int main(int argc, char *argv[]) {
  30. CommandLineParser parser(argc, argv, keys);
  31. parser.about(about);
  32. if(argc < 7) {
  33. parser.printMessage();
  34. return 0;
  35. }
  36. //! [aruco_detect_board_full_sample]
  37. int markersX = parser.get<int>("w");
  38. int markersY = parser.get<int>("h");
  39. float markerLength = parser.get<float>("l");
  40. float markerSeparation = parser.get<float>("s");
  41. bool showRejected = parser.has("r");
  42. bool refindStrategy = parser.has("rs");
  43. int camId = parser.get<int>("ci");
  44. Mat camMatrix, distCoeffs;
  45. readCameraParamsFromCommandLine(parser, camMatrix, distCoeffs);
  46. aruco::Dictionary dictionary = readDictionatyFromCommandLine(parser);
  47. aruco::DetectorParameters detectorParams = readDetectorParamsFromCommandLine(parser);
  48. String video;
  49. if(parser.has("v")) {
  50. video = parser.get<String>("v");
  51. }
  52. if(!parser.check()) {
  53. parser.printErrors();
  54. return 0;
  55. }
  56. aruco::ArucoDetector detector(dictionary, detectorParams);
  57. VideoCapture inputVideo;
  58. int waitTime;
  59. if(!video.empty()) {
  60. inputVideo.open(video);
  61. waitTime = 0;
  62. } else {
  63. inputVideo.open(camId);
  64. waitTime = 10;
  65. }
  66. float axisLength = 0.5f * ((float)min(markersX, markersY) * (markerLength + markerSeparation) +
  67. markerSeparation);
  68. // Create GridBoard object
  69. //! [aruco_create_board]
  70. aruco::GridBoard board(Size(markersX, markersY), markerLength, markerSeparation, dictionary);
  71. //! [aruco_create_board]
  72. // Also you could create Board object
  73. //vector<vector<Point3f> > objPoints; // array of object points of all the marker corners in the board
  74. //vector<int> ids; // vector of the identifiers of the markers in the board
  75. //aruco::Board board(objPoints, dictionary, ids);
  76. double totalTime = 0;
  77. int totalIterations = 0;
  78. while(inputVideo.grab()) {
  79. Mat image, imageCopy;
  80. inputVideo.retrieve(image);
  81. double tick = (double)getTickCount();
  82. vector<int> ids;
  83. vector<vector<Point2f>> corners, rejected;
  84. Vec3d rvec, tvec;
  85. //! [aruco_detect_and_refine]
  86. // Detect markers
  87. detector.detectMarkers(image, corners, ids, rejected);
  88. // Refind strategy to detect more markers
  89. if(refindStrategy)
  90. detector.refineDetectedMarkers(image, board, corners, ids, rejected, camMatrix,
  91. distCoeffs);
  92. //! [aruco_detect_and_refine]
  93. // Estimate board pose
  94. int markersOfBoardDetected = 0;
  95. if(!ids.empty()) {
  96. // Get object and image points for the solvePnP function
  97. cv::Mat objPoints, imgPoints;
  98. board.matchImagePoints(corners, ids, objPoints, imgPoints);
  99. // Find pose
  100. cv::solvePnP(objPoints, imgPoints, camMatrix, distCoeffs, rvec, tvec);
  101. markersOfBoardDetected = (int)objPoints.total() / 4;
  102. }
  103. double currentTime = ((double)getTickCount() - tick) / getTickFrequency();
  104. totalTime += currentTime;
  105. totalIterations++;
  106. if(totalIterations % 30 == 0) {
  107. cout << "Detection Time = " << currentTime * 1000 << " ms "
  108. << "(Mean = " << 1000 * totalTime / double(totalIterations) << " ms)" << endl;
  109. }
  110. // Draw results
  111. image.copyTo(imageCopy);
  112. if(!ids.empty())
  113. aruco::drawDetectedMarkers(imageCopy, corners, ids);
  114. if(showRejected && !rejected.empty())
  115. aruco::drawDetectedMarkers(imageCopy, rejected, noArray(), Scalar(100, 0, 255));
  116. if(markersOfBoardDetected > 0)
  117. cv::drawFrameAxes(imageCopy, camMatrix, distCoeffs, rvec, tvec, axisLength);
  118. imshow("out", imageCopy);
  119. char key = (char)waitKey(waitTime);
  120. if(key == 27) break;
  121. //! [aruco_detect_board_full_sample]
  122. }
  123. return 0;
  124. }