1
+ // ! [charucohdr]
2
+ #include < opencv2/aruco/charuco.hpp>
3
+ // ! [charucohdr]
4
+ #include < opencv2/highgui.hpp>
5
+ #include < iostream>
6
+ #include < string>
7
+
8
+ namespace {
9
+ const char * about = " A tutorial code on charuco board creation and detection of charuco board with and without camera caliberation" ;
10
+ const char * keys = " {c | | Put value of c=1 to create charuco board;\n c=2 to detect charuco board without camera calibration;\n c=3 to detect charuco board with camera calibration and Pose Estimation}" ;
11
+ }
12
+
13
+ void createBoard ();
14
+ void detectCharucoBoardWithCalibrationPose ();
15
+ void detectCharucoBoardWithoutCalibration ();
16
+
17
+ static bool readCameraParameters (std::string filename, cv::Mat& camMatrix, cv::Mat& distCoeffs)
18
+ {
19
+ cv::FileStorage fs (filename, cv::FileStorage::READ);
20
+ if (!fs.isOpened ())
21
+ return false ;
22
+ fs[" camera_matrix" ] >> camMatrix;
23
+ fs[" distortion_coefficients" ] >> distCoeffs;
24
+ return true ;
25
+ }
26
+
27
+ void createBoard ()
28
+ {
29
+ cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary (cv::aruco::DICT_6X6_250);
30
+ // ! [createBoard]
31
+ cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create (5 , 7 , 0 .04f , 0 .02f , dictionary);
32
+ cv::Mat boardImage;
33
+ board->draw (cv::Size (600 , 500 ), boardImage, 10 , 1 );
34
+ // ! [createBoard]
35
+ cv::imwrite (" BoardImage.jpg" , boardImage);
36
+ }
37
+
38
+ // ! [detwcp]
39
+ void detectCharucoBoardWithCalibrationPose ()
40
+ {
41
+ cv::VideoCapture inputVideo;
42
+ inputVideo.open (0 );
43
+ // ! [matdiscoff]
44
+ cv::Mat cameraMatrix, distCoeffs;
45
+ std::string filename = " calib.txt" ;
46
+ bool readOk = readCameraParameters (filename, cameraMatrix, distCoeffs);
47
+ // ! [matdiscoff]
48
+ if (!readOk) {
49
+ std::cerr << " Invalid camera file" << std::endl;
50
+ } else {
51
+ // ! [dictboard]
52
+ cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary (cv::aruco::DICT_6X6_250);
53
+ cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create (5 , 7 , 0 .04f , 0 .02f , dictionary);
54
+ cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create ();
55
+ // ! [dictboard]
56
+ while (inputVideo.grab ()) {
57
+ // ! [inputImg]
58
+ cv::Mat image;
59
+ // ! [inputImg]
60
+ cv::Mat imageCopy;
61
+ inputVideo.retrieve (image);
62
+ image.copyTo (imageCopy);
63
+ // ! [midcornerdet]
64
+ std::vector<int > markerIds;
65
+ std::vector<std::vector<cv::Point2f> > markerCorners;
66
+ cv::aruco::detectMarkers (image, board->dictionary , markerCorners, markerIds, params);
67
+ // ! [midcornerdet]
68
+ // if at least one marker detected
69
+ if (markerIds.size () > 0 ) {
70
+ cv::aruco::drawDetectedMarkers (imageCopy, markerCorners, markerIds);
71
+ // ! [charidcor]
72
+ std::vector<cv::Point2f> charucoCorners;
73
+ std::vector<int > charucoIds;
74
+ cv::aruco::interpolateCornersCharuco (markerCorners, markerIds, image, board, charucoCorners, charucoIds, cameraMatrix, distCoeffs);
75
+ // ! [charidcor]
76
+ // if at least one charuco corner detected
77
+ if (charucoIds.size () > 0 ) {
78
+ cv::Scalar color = cv::Scalar (255 , 0 , 0 );
79
+ // ! [detcor]
80
+ cv::aruco::drawDetectedCornersCharuco (imageCopy, charucoCorners, charucoIds, color);
81
+ // ! [detcor]
82
+ cv::Vec3d rvec, tvec;
83
+ // ! [pose]
84
+ // cv::aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec);
85
+ // ! [pose]
86
+ bool valid = cv::aruco::estimatePoseCharucoBoard (charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec);
87
+ // if charuco pose is valid
88
+ if (valid)
89
+ cv::aruco::drawAxis (imageCopy, cameraMatrix, distCoeffs, rvec, tvec, 0 .1f );
90
+ }
91
+ }
92
+ cv::imshow (" out" , imageCopy);
93
+ char key = (char )cv::waitKey (30 );
94
+ if (key == 27 )
95
+ break ;
96
+ }
97
+ }
98
+ }
99
+ // ! [detwcp]
100
+
101
+ // ! [detwc]
102
+ void detectCharucoBoardWithoutCalibration ()
103
+ {
104
+ cv::VideoCapture inputVideo;
105
+ inputVideo.open (0 );
106
+ cv::Ptr<cv::aruco::Dictionary> dictionary = cv::aruco::getPredefinedDictionary (cv::aruco::DICT_6X6_250);
107
+ cv::Ptr<cv::aruco::CharucoBoard> board = cv::aruco::CharucoBoard::create (5 , 7 , 0 .04f , 0 .02f , dictionary);
108
+
109
+ cv::Ptr<cv::aruco::DetectorParameters> params = cv::aruco::DetectorParameters::create ();
110
+ params->cornerRefinementMethod = cv::aruco::CORNER_REFINE_NONE;
111
+ while (inputVideo.grab ()) {
112
+ cv::Mat image, imageCopy;
113
+ inputVideo.retrieve (image);
114
+ image.copyTo (imageCopy);
115
+ std::vector<int > markerIds;
116
+ std::vector<std::vector<cv::Point2f> > markerCorners;
117
+ cv::aruco::detectMarkers (image, board->dictionary , markerCorners, markerIds, params);
118
+ // or
119
+ // cv::aruco::detectMarkers(image, dictionary, markerCorners, markerIds, params);
120
+ // if at least one marker detected
121
+ if (markerIds.size () > 0 ) {
122
+ cv::aruco::drawDetectedMarkers (imageCopy, markerCorners, markerIds);
123
+ // ! [charidcorwc]
124
+ std::vector<cv::Point2f> charucoCorners;
125
+ std::vector<int > charucoIds;
126
+ cv::aruco::interpolateCornersCharuco (markerCorners, markerIds, image, board, charucoCorners, charucoIds);
127
+ // ! [charidcorwc]
128
+ // if at least one charuco corner detected
129
+ if (charucoIds.size () > 0 )
130
+ cv::aruco::drawDetectedCornersCharuco (imageCopy, charucoCorners, charucoIds, cv::Scalar (255 , 0 , 0 ));
131
+ }
132
+ cv::imshow (" out" , imageCopy);
133
+ char key = (char )cv::waitKey (30 );
134
+ if (key == 27 )
135
+ break ;
136
+ }
137
+ }
138
+ // ! [detwc]
139
+
140
+ int main (int argc, char * argv[])
141
+ {
142
+ cv::CommandLineParser parser (argc, argv, keys);
143
+ parser.about (about);
144
+ if (argc < 2 ) {
145
+ parser.printMessage ();
146
+ return 0 ;
147
+ }
148
+ int choose = parser.get <int >(" c" );
149
+ switch (choose) {
150
+ case 1 :
151
+ createBoard ();
152
+ std::cout << " An image named BoardImg.jpg is generated in folder containing this file" << std::endl;
153
+ break ;
154
+ case 2 :
155
+ detectCharucoBoardWithoutCalibration ();
156
+ break ;
157
+ case 3 :
158
+ detectCharucoBoardWithCalibrationPose ();
159
+ break ;
160
+ default :
161
+ break ;
162
+ }
163
+ return 0 ;
164
+ }
0 commit comments