Skip to content

Commit 175c508

Browse files
author
AleksandrPanov
committed
fix ArUco, ChArUco and calibrate, add tests, add samples_utility.hpp
1 parent 5cc328d commit 175c508

36 files changed

+461
-411
lines changed

modules/aruco/samples/calibrate_camera.cpp

Lines changed: 18 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ the use of this software, even if advised of the possibility of such damage.
4444
#include <vector>
4545
#include <iostream>
4646
#include <ctime>
47+
#include "samples_utility.hpp"
4748

4849
using namespace std;
4950
using namespace cv;
@@ -64,6 +65,7 @@ const char* keys =
6465
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
6566
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
6667
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
68+
"{cd | | Input file with custom dictionary }"
6769
"{@outfile |<none> | Output file with calibrated camera parameters }"
6870
"{v | | Input from video file, if ommited, input comes from camera }"
6971
"{ci | 0 | Camera id if input doesnt come from video (-v) }"
@@ -74,80 +76,7 @@ const char* keys =
7476
"{pc | false | Fix the principal point at the center }";
7577
}
7678

77-
/**
78-
*/
79-
static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
80-
FileStorage fs(filename, FileStorage::READ);
81-
if(!fs.isOpened())
82-
return false;
83-
fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
84-
fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
85-
fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
86-
fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
87-
fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
88-
fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
89-
fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
90-
fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
91-
fs["minDistanceToBorder"] >> params->minDistanceToBorder;
92-
fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
93-
fs["cornerRefinementMethod"] >> params->cornerRefinementMethod;
94-
fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
95-
fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
96-
fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
97-
fs["markerBorderBits"] >> params->markerBorderBits;
98-
fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
99-
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
100-
fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
101-
fs["minOtsuStdDev"] >> params->minOtsuStdDev;
102-
fs["errorCorrectionRate"] >> params->errorCorrectionRate;
103-
return true;
104-
}
105-
106-
107-
108-
/**
109-
*/
110-
static bool saveCameraParams(const string &filename, Size imageSize, float aspectRatio, int flags,
111-
const Mat &cameraMatrix, const Mat &distCoeffs, double totalAvgErr) {
112-
FileStorage fs(filename, FileStorage::WRITE);
113-
if(!fs.isOpened())
114-
return false;
115-
116-
time_t tt;
117-
time(&tt);
118-
struct tm *t2 = localtime(&tt);
119-
char buf[1024];
120-
strftime(buf, sizeof(buf) - 1, "%c", t2);
121-
122-
fs << "calibration_time" << buf;
123-
124-
fs << "image_width" << imageSize.width;
125-
fs << "image_height" << imageSize.height;
126-
127-
if(flags & CALIB_FIX_ASPECT_RATIO) fs << "aspectRatio" << aspectRatio;
128-
129-
if(flags != 0) {
130-
sprintf(buf, "flags: %s%s%s%s",
131-
flags & CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "",
132-
flags & CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "",
133-
flags & CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "",
134-
flags & CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : "");
135-
}
136-
137-
fs << "flags" << flags;
138-
139-
fs << "camera_matrix" << cameraMatrix;
140-
fs << "distortion_coefficients" << distCoeffs;
14179

142-
fs << "avg_reprojection_error" << totalAvgErr;
143-
144-
return true;
145-
}
146-
147-
148-
149-
/**
150-
*/
15180
int main(int argc, char *argv[]) {
15281
CommandLineParser parser(argc, argv, keys);
15382
parser.about(about);
@@ -161,7 +90,6 @@ int main(int argc, char *argv[]) {
16190
int markersY = parser.get<int>("h");
16291
float markerLength = parser.get<float>("l");
16392
float markerSeparation = parser.get<float>("s");
164-
int dictionaryId = parser.get<int>("d");
16593
string outputFile = parser.get<String>(0);
16694

16795
int calibrationFlags = 0;
@@ -205,8 +133,22 @@ int main(int argc, char *argv[]) {
205133
waitTime = 10;
206134
}
207135

208-
Ptr<aruco::Dictionary> dictionary =
209-
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
136+
Ptr<aruco::Dictionary> dictionary;
137+
if (parser.has("d")) {
138+
int dictionaryId = parser.get<int>("d");
139+
dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
140+
}
141+
else if (parser.has("cd")) {
142+
bool readOk = readDictionary(parser.get<string>("cd"), dictionary);
143+
if(!readOk) {
144+
cerr << "Invalid dictionary file" << endl;
145+
return 0;
146+
}
147+
}
148+
else {
149+
cerr << "Dictionary not specified" << endl;
150+
return 0;
151+
}
210152

211153
// create board object
212154
Ptr<aruco::GridBoard> gridboard =

modules/aruco/samples/calibrate_camera_charuco.cpp

Lines changed: 18 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ the use of this software, even if advised of the possibility of such damage.
4343
#include <opencv2/imgproc.hpp>
4444
#include <vector>
4545
#include <iostream>
46-
#include <ctime>
46+
#include "samples_utility.hpp"
4747

4848
using namespace std;
4949
using namespace cv;
@@ -63,6 +63,7 @@ const char* keys =
6363
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
6464
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
6565
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
66+
"{cd | | Input file with custom dictionary }"
6667
"{@outfile |<none> | Output file with calibrated camera parameters }"
6768
"{v | | Input from video file, if ommited, input comes from camera }"
6869
"{ci | 0 | Camera id if input doesnt come from video (-v) }"
@@ -74,80 +75,7 @@ const char* keys =
7475
"{sc | false | Show detected chessboard corners after calibration }";
7576
}
7677

77-
/**
78-
*/
79-
static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
80-
FileStorage fs(filename, FileStorage::READ);
81-
if(!fs.isOpened())
82-
return false;
83-
fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
84-
fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
85-
fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
86-
fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
87-
fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
88-
fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
89-
fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
90-
fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
91-
fs["minDistanceToBorder"] >> params->minDistanceToBorder;
92-
fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
93-
fs["cornerRefinementMethod"] >> params->cornerRefinementMethod;
94-
fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
95-
fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
96-
fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
97-
fs["markerBorderBits"] >> params->markerBorderBits;
98-
fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
99-
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
100-
fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
101-
fs["minOtsuStdDev"] >> params->minOtsuStdDev;
102-
fs["errorCorrectionRate"] >> params->errorCorrectionRate;
103-
return true;
104-
}
105-
106-
107-
108-
/**
109-
*/
110-
static bool saveCameraParams(const string &filename, Size imageSize, float aspectRatio, int flags,
111-
const Mat &cameraMatrix, const Mat &distCoeffs, double totalAvgErr) {
112-
FileStorage fs(filename, FileStorage::WRITE);
113-
if(!fs.isOpened())
114-
return false;
115-
116-
time_t tt;
117-
time(&tt);
118-
struct tm *t2 = localtime(&tt);
119-
char buf[1024];
120-
strftime(buf, sizeof(buf) - 1, "%c", t2);
121-
122-
fs << "calibration_time" << buf;
123-
124-
fs << "image_width" << imageSize.width;
125-
fs << "image_height" << imageSize.height;
126-
127-
if(flags & CALIB_FIX_ASPECT_RATIO) fs << "aspectRatio" << aspectRatio;
128-
129-
if(flags != 0) {
130-
sprintf(buf, "flags: %s%s%s%s",
131-
flags & CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "",
132-
flags & CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "",
133-
flags & CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "",
134-
flags & CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : "");
135-
}
136-
137-
fs << "flags" << flags;
138-
139-
fs << "camera_matrix" << cameraMatrix;
140-
fs << "distortion_coefficients" << distCoeffs;
14178

142-
fs << "avg_reprojection_error" << totalAvgErr;
143-
144-
return true;
145-
}
146-
147-
148-
149-
/**
150-
*/
15179
int main(int argc, char *argv[]) {
15280
CommandLineParser parser(argc, argv, keys);
15381
parser.about(about);
@@ -161,7 +89,6 @@ int main(int argc, char *argv[]) {
16189
int squaresY = parser.get<int>("h");
16290
float squareLength = parser.get<float>("sl");
16391
float markerLength = parser.get<float>("ml");
164-
int dictionaryId = parser.get<int>("d");
16592
string outputFile = parser.get<string>(0);
16693

16794
bool showChessboardCorners = parser.get<bool>("sc");
@@ -207,8 +134,22 @@ int main(int argc, char *argv[]) {
207134
waitTime = 10;
208135
}
209136

210-
Ptr<aruco::Dictionary> dictionary =
211-
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
137+
Ptr<aruco::Dictionary> dictionary;
138+
if (parser.has("d")) {
139+
int dictionaryId = parser.get<int>("d");
140+
dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
141+
}
142+
else if (parser.has("cd")) {
143+
bool readOk = readDictionary(parser.get<string>("cd"), dictionary);
144+
if(!readOk) {
145+
cerr << "Invalid dictionary file" << endl;
146+
return 0;
147+
}
148+
}
149+
else {
150+
cerr << "Dictionary not specified" << endl;
151+
return 0;
152+
}
212153

213154
// create charuco board object
214155
Ptr<aruco::CharucoBoard> charucoboard =

modules/aruco/samples/create_board.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ the use of this software, even if advised of the possibility of such damage.
3939

4040
#include <opencv2/highgui.hpp>
4141
#include <opencv2/aruco.hpp>
42+
#include <iostream>
43+
#include "samples_utility.hpp"
4244

4345
using namespace cv;
4446

@@ -54,11 +56,13 @@ const char* keys =
5456
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
5557
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
5658
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
59+
"{cd | | Input file with custom dictionary }"
5760
"{m | | Margins size (in pixels). Default is marker separation (-s) }"
5861
"{bb | 1 | Number of bits in marker borders }"
5962
"{si | false | show generated image }";
6063
}
6164

65+
6266
int main(int argc, char *argv[]) {
6367
CommandLineParser parser(argc, argv, keys);
6468
parser.about(about);
@@ -72,7 +76,6 @@ int main(int argc, char *argv[]) {
7276
int markersY = parser.get<int>("h");
7377
int markerLength = parser.get<int>("l");
7478
int markerSeparation = parser.get<int>("s");
75-
int dictionaryId = parser.get<int>("d");
7679
int margins = markerSeparation;
7780
if(parser.has("m")) {
7881
margins = parser.get<int>("m");
@@ -93,8 +96,23 @@ int main(int argc, char *argv[]) {
9396
imageSize.height =
9497
markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins;
9598

96-
Ptr<aruco::Dictionary> dictionary =
97-
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
99+
Ptr<aruco::Dictionary> dictionary;
100+
if (parser.has("d")) {
101+
int dictionaryId = parser.get<int>("d");
102+
dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
103+
}
104+
else if (parser.has("cd")) {
105+
bool readOk = readDictionary(parser.get<std::string>("cd"), dictionary);
106+
if(!readOk)
107+
{
108+
std::cerr << "Invalid dictionary file" << std::endl;
109+
return 0;
110+
}
111+
}
112+
else {
113+
std::cerr << "Dictionary not specified" << std::endl;
114+
return 0;
115+
}
98116

99117
Ptr<aruco::GridBoard> board = aruco::GridBoard::create(markersX, markersY, float(markerLength),
100118
float(markerSeparation), dictionary);

modules/aruco/samples/create_board_charuco.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,14 @@ the use of this software, even if advised of the possibility of such damage.
3939

4040
#include <opencv2/highgui.hpp>
4141
#include <opencv2/aruco/charuco.hpp>
42+
#include <iostream>
43+
#include "samples_utility.hpp"
4244

4345
using namespace cv;
4446

4547
namespace {
4648
const char* about = "Create a ChArUco board image";
49+
//! [charuco_detect_board_keys]
4750
const char* keys =
4851
"{@outfile |<none> | Output image }"
4952
"{w | | Number of squares in X direction }"
@@ -54,10 +57,13 @@ const char* keys =
5457
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, "
5558
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12,"
5659
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}"
60+
"{cd | | Input file with custom dictionary }"
5761
"{m | | Margins size (in pixels). Default is (squareLength-markerLength) }"
5862
"{bb | 1 | Number of bits in marker borders }"
5963
"{si | false | show generated image }";
6064
}
65+
//! [charuco_detect_board_keys]
66+
6167

6268
int main(int argc, char *argv[]) {
6369
CommandLineParser parser(argc, argv, keys);
@@ -72,7 +78,6 @@ int main(int argc, char *argv[]) {
7278
int squaresY = parser.get<int>("h");
7379
int squareLength = parser.get<int>("sl");
7480
int markerLength = parser.get<int>("ml");
75-
int dictionaryId = parser.get<int>("d");
7681
int margins = squareLength - markerLength;
7782
if(parser.has("m")) {
7883
margins = parser.get<int>("m");
@@ -88,8 +93,22 @@ int main(int argc, char *argv[]) {
8893
return 0;
8994
}
9095

91-
Ptr<aruco::Dictionary> dictionary =
92-
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
96+
Ptr<aruco::Dictionary> dictionary;
97+
if (parser.has("d")) {
98+
int dictionaryId = parser.get<int>("d");
99+
dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
100+
}
101+
else if (parser.has("cd")) {
102+
bool readOk = readDictionary(parser.get<std::string>("cd"), dictionary);
103+
if(!readOk) {
104+
std::cerr << "Invalid dictionary file" << std::endl;
105+
return 0;
106+
}
107+
}
108+
else {
109+
std::cerr << "Dictionary not specified" << std::endl;
110+
return 0;
111+
}
93112

94113
Size imageSize;
95114
imageSize.width = squaresX * squareLength + 2 * margins;

0 commit comments

Comments
 (0)