Skip to content

Commit c07438c

Browse files
authored
Merge pull request #3410 from stopmosk:fix-aruco-charuco-calib-tutorials-and-faq
Update aruco and charuco calibration tutorials and faq
2 parents ec406fa + 21c9dd0 commit c07438c

File tree

4 files changed

+228
-268
lines changed

4 files changed

+228
-268
lines changed

modules/aruco/samples/calibrate_camera.cpp

Lines changed: 77 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,14 @@
1-
/*
2-
By downloading, copying, installing or using the software you agree to this
3-
license. If you do not agree to this license, do not download, install,
4-
copy or use the software.
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html
54

6-
License Agreement
7-
For Open Source Computer Vision Library
8-
(3-clause BSD License)
9-
10-
Copyright (C) 2013, OpenCV Foundation, all rights reserved.
11-
Third party copyrights are property of their respective owners.
12-
13-
Redistribution and use in source and binary forms, with or without modification,
14-
are permitted provided that the following conditions are met:
15-
16-
* Redistributions of source code must retain the above copyright notice,
17-
this list of conditions and the following disclaimer.
18-
19-
* Redistributions in binary form must reproduce the above copyright notice,
20-
this list of conditions and the following disclaimer in the documentation
21-
and/or other materials provided with the distribution.
22-
23-
* Neither the names of the copyright holders nor the names of the contributors
24-
may be used to endorse or promote products derived from this software
25-
without specific prior written permission.
26-
27-
This software is provided by the copyright holders and contributors "as is" and
28-
any express or implied warranties, including, but not limited to, the implied
29-
warranties of merchantability and fitness for a particular purpose are
30-
disclaimed. In no event shall copyright holders or contributors be liable for
31-
any direct, indirect, incidental, special, exemplary, or consequential damages
32-
(including, but not limited to, procurement of substitute goods or services;
33-
loss of use, data, or profits; or business interruption) however caused
34-
and on any theory of liability, whether in contract, strict liability,
35-
or tort (including negligence or otherwise) arising in any way out of
36-
the use of this software, even if advised of the possibility of such damage.
37-
*/
38-
39-
40-
#include <opencv2/highgui.hpp>
5+
#include <ctime>
6+
#include <iostream>
7+
#include <vector>
418
#include <opencv2/calib3d.hpp>
42-
#include <opencv2/objdetect/aruco_detector.hpp>
43-
#include <opencv2/aruco/aruco_calib.hpp>
9+
#include <opencv2/highgui.hpp>
4410
#include <opencv2/imgproc.hpp>
45-
#include <vector>
46-
#include <iostream>
47-
#include <ctime>
11+
#include <opencv2/objdetect.hpp>
4812
#include "aruco_samples_utility.hpp"
4913

5014
using namespace std;
@@ -138,7 +102,9 @@ int main(int argc, char *argv[]) {
138102
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(0);
139103
if (parser.has("d")) {
140104
int dictionaryId = parser.get<int>("d");
141-
dictionary = aruco::getPredefinedDictionary(aruco::PredefinedDictionaryType(dictionaryId));
105+
dictionary = aruco::getPredefinedDictionary(
106+
aruco::PredefinedDictionaryType(dictionaryId)
107+
);
142108
}
143109
else if (parser.has("cd")) {
144110
FileStorage fs(parser.get<std::string>("cd"), FileStorage::READ);
@@ -153,80 +119,104 @@ int main(int argc, char *argv[]) {
153119
return 0;
154120
}
155121

156-
// create board object
157-
Ptr<aruco::GridBoard> gridboard = new aruco::GridBoard(Size(markersX, markersY), markerLength, markerSeparation, dictionary);
158-
Ptr<aruco::Board> board = gridboard.staticCast<aruco::Board>();
122+
// Create board object
123+
aruco::GridBoard gridboard(Size(markersX, markersY), markerLength, markerSeparation, dictionary);
159124

160-
// collected frames for calibration
161-
vector< vector< vector< Point2f > > > allCorners;
162-
vector< vector< int > > allIds;
163-
Size imgSize;
125+
// Collected frames for calibration
126+
vector<vector<vector<Point2f>>> allMarkerCorners;
127+
vector<vector<int>> allMarkerIds;
128+
Size imageSize;
164129

165130
aruco::ArucoDetector detector(dictionary, detectorParams);
166131

167132
while(inputVideo.grab()) {
168133
Mat image, imageCopy;
169134
inputVideo.retrieve(image);
170135

171-
vector< int > ids;
172-
vector< vector< Point2f > > corners, rejected;
136+
vector<int> markerIds;
137+
vector<vector<Point2f>> markerCorners, rejectedMarkers;
173138

174-
// detect markers
175-
detector.detectMarkers(image, corners, ids, rejected);
139+
// Detect markers
140+
detector.detectMarkers(image, markerCorners, markerIds, rejectedMarkers);
176141

177-
// refind strategy to detect more markers
178-
if(refindStrategy) detector.refineDetectedMarkers(image, *board, corners, ids, rejected);
142+
// Refind strategy to detect more markers
143+
if(refindStrategy) {
144+
detector.refineDetectedMarkers(
145+
image, gridboard, markerCorners, markerIds, rejectedMarkers
146+
);
147+
}
179148

180-
// draw results
149+
// Draw results
181150
image.copyTo(imageCopy);
182-
if(ids.size() > 0) aruco::drawDetectedMarkers(imageCopy, corners, ids);
183-
putText(imageCopy, "Press 'c' to add current frame. 'ESC' to finish and calibrate",
184-
Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 0, 0), 2);
185151

152+
if(!markerIds.empty()) {
153+
aruco::drawDetectedMarkers(imageCopy, markerCorners, markerIds);
154+
}
155+
156+
putText(
157+
imageCopy, "Press 'c' to add current frame. 'ESC' to finish and calibrate",
158+
Point(10, 20), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(255, 0, 0), 2
159+
);
186160
imshow("out", imageCopy);
161+
162+
// Wait for key pressed
187163
char key = (char)waitKey(waitTime);
188-
if(key == 27) break;
189-
if(key == 'c' && ids.size() > 0) {
164+
165+
if(key == 27) {
166+
break;
167+
}
168+
169+
if(key == 'c' && !markerIds.empty()) {
190170
cout << "Frame captured" << endl;
191-
allCorners.push_back(corners);
192-
allIds.push_back(ids);
193-
imgSize = image.size();
171+
allMarkerCorners.push_back(markerCorners);
172+
allMarkerIds.push_back(markerIds);
173+
imageSize = image.size();
194174
}
195175
}
196176

197-
if(allIds.size() < 1) {
177+
if(allMarkerIds.empty()) {
198178
cerr << "Not enough captures for calibration" << endl;
199179
return 0;
200180
}
201181

202182
Mat cameraMatrix, distCoeffs;
203-
vector< Mat > rvecs, tvecs;
204-
double repError;
205183

206184
if(calibrationFlags & CALIB_FIX_ASPECT_RATIO) {
207185
cameraMatrix = Mat::eye(3, 3, CV_64F);
208-
cameraMatrix.at< double >(0, 0) = aspectRatio;
186+
cameraMatrix.at<double>(0, 0) = aspectRatio;
209187
}
210188

211-
// prepare data for calibration
212-
vector< vector< Point2f > > allCornersConcatenated;
213-
vector< int > allIdsConcatenated;
214-
vector< int > markerCounterPerFrame;
215-
markerCounterPerFrame.reserve(allCorners.size());
216-
for(unsigned int i = 0; i < allCorners.size(); i++) {
217-
markerCounterPerFrame.push_back((int)allCorners[i].size());
218-
for(unsigned int j = 0; j < allCorners[i].size(); j++) {
219-
allCornersConcatenated.push_back(allCorners[i][j]);
220-
allIdsConcatenated.push_back(allIds[i][j]);
189+
// Prepare data for calibration
190+
vector<Point3f> objectPoints;
191+
vector<Point2f> imagePoints;
192+
vector<Mat> processedObjectPoints, processedImagePoints;
193+
size_t nFrames = allMarkerCorners.size();
194+
195+
for(size_t frame = 0; frame < nFrames; frame++) {
196+
Mat currentImgPoints, currentObjPoints;
197+
198+
gridboard.matchImagePoints(
199+
allMarkerCorners[frame], allMarkerIds[frame],
200+
currentObjPoints, currentImgPoints
201+
);
202+
203+
if(currentImgPoints.total() > 0 && currentObjPoints.total() > 0) {
204+
processedImagePoints.push_back(currentImgPoints);
205+
processedObjectPoints.push_back(currentObjPoints);
221206
}
222207
}
223-
// calibrate camera
224-
repError = aruco::calibrateCameraAruco(allCornersConcatenated, allIdsConcatenated,
225-
markerCounterPerFrame, board, imgSize, cameraMatrix,
226-
distCoeffs, rvecs, tvecs, calibrationFlags);
227208

228-
bool saveOk = saveCameraParams(outputFile, imgSize, aspectRatio, calibrationFlags, cameraMatrix,
229-
distCoeffs, repError);
209+
// Calibrate camera
210+
double repError = calibrateCamera(
211+
processedObjectPoints, processedImagePoints, imageSize,
212+
cameraMatrix, distCoeffs, noArray(), noArray(), noArray(),
213+
noArray(), noArray(), calibrationFlags
214+
);
215+
216+
bool saveOk = saveCameraParams(
217+
outputFile, imageSize, aspectRatio, calibrationFlags, cameraMatrix,
218+
distCoeffs, repError
219+
);
230220

231221
if(!saveOk) {
232222
cerr << "Cannot save output file" << endl;

0 commit comments

Comments
 (0)