diff --git a/modules/aruco/samples/calibrate_camera.cpp b/modules/aruco/samples/calibrate_camera.cpp index 727b2a99803..c8b5275885e 100644 --- a/modules/aruco/samples/calibrate_camera.cpp +++ b/modules/aruco/samples/calibrate_camera.cpp @@ -44,6 +44,7 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; @@ -64,6 +65,7 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{@outfile | | Output file with calibrated camera parameters }" "{v | | Input from video file, if ommited, input comes from camera }" "{ci | 0 | Camera id if input doesnt come from video (-v) }" @@ -74,80 +76,7 @@ const char* keys = "{pc | false | Fix the principal point at the center }"; } -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} - - - -/** - */ -static bool saveCameraParams(const string &filename, Size imageSize, float aspectRatio, int flags, - const Mat &cameraMatrix, const Mat &distCoeffs, double totalAvgErr) { - FileStorage fs(filename, FileStorage::WRITE); - if(!fs.isOpened()) - return false; - - time_t tt; - time(&tt); - struct tm *t2 = localtime(&tt); - char buf[1024]; - strftime(buf, sizeof(buf) - 1, "%c", t2); - - fs << "calibration_time" << buf; - - fs << "image_width" << imageSize.width; - fs << "image_height" << imageSize.height; - - if(flags & CALIB_FIX_ASPECT_RATIO) fs << "aspectRatio" << aspectRatio; - - if(flags != 0) { - sprintf(buf, "flags: %s%s%s%s", - flags & CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "", - flags & CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "", - flags & CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "", - flags & CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : ""); - } - - fs << "flags" << flags; - - fs << "camera_matrix" << cameraMatrix; - fs << "distortion_coefficients" << distCoeffs; - fs << "avg_reprojection_error" << totalAvgErr; - - return true; -} - - - -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -161,7 +90,6 @@ int main(int argc, char *argv[]) { int markersY = parser.get("h"); float markerLength = parser.get("l"); float markerSeparation = parser.get("s"); - int dictionaryId = parser.get("d"); string outputFile = parser.get(0); int calibrationFlags = 0; @@ -205,8 +133,22 @@ int main(int argc, char *argv[]) { waitTime = 10; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + cerr << "Invalid dictionary file" << endl; + return 0; + } + } + else { + cerr << "Dictionary not specified" << endl; + return 0; + } // create board object Ptr gridboard = diff --git a/modules/aruco/samples/calibrate_camera_charuco.cpp b/modules/aruco/samples/calibrate_camera_charuco.cpp index 42adeec8354..d08034be5d9 100644 --- a/modules/aruco/samples/calibrate_camera_charuco.cpp +++ b/modules/aruco/samples/calibrate_camera_charuco.cpp @@ -43,7 +43,7 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include -#include +#include "samples_utility.hpp" using namespace std; using namespace cv; @@ -63,6 +63,7 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{@outfile | | Output file with calibrated camera parameters }" "{v | | Input from video file, if ommited, input comes from camera }" "{ci | 0 | Camera id if input doesnt come from video (-v) }" @@ -74,80 +75,7 @@ const char* keys = "{sc | false | Show detected chessboard corners after calibration }"; } -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} - - - -/** - */ -static bool saveCameraParams(const string &filename, Size imageSize, float aspectRatio, int flags, - const Mat &cameraMatrix, const Mat &distCoeffs, double totalAvgErr) { - FileStorage fs(filename, FileStorage::WRITE); - if(!fs.isOpened()) - return false; - - time_t tt; - time(&tt); - struct tm *t2 = localtime(&tt); - char buf[1024]; - strftime(buf, sizeof(buf) - 1, "%c", t2); - - fs << "calibration_time" << buf; - - fs << "image_width" << imageSize.width; - fs << "image_height" << imageSize.height; - - if(flags & CALIB_FIX_ASPECT_RATIO) fs << "aspectRatio" << aspectRatio; - - if(flags != 0) { - sprintf(buf, "flags: %s%s%s%s", - flags & CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "", - flags & CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "", - flags & CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "", - flags & CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : ""); - } - - fs << "flags" << flags; - - fs << "camera_matrix" << cameraMatrix; - fs << "distortion_coefficients" << distCoeffs; - fs << "avg_reprojection_error" << totalAvgErr; - - return true; -} - - - -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -161,7 +89,6 @@ int main(int argc, char *argv[]) { int squaresY = parser.get("h"); float squareLength = parser.get("sl"); float markerLength = parser.get("ml"); - int dictionaryId = parser.get("d"); string outputFile = parser.get(0); bool showChessboardCorners = parser.get("sc"); @@ -207,8 +134,22 @@ int main(int argc, char *argv[]) { waitTime = 10; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + cerr << "Invalid dictionary file" << endl; + return 0; + } + } + else { + cerr << "Dictionary not specified" << endl; + return 0; + } // create charuco board object Ptr charucoboard = diff --git a/modules/aruco/samples/create_board.cpp b/modules/aruco/samples/create_board.cpp index 937fe5b5f74..3bb70fb9eb0 100644 --- a/modules/aruco/samples/create_board.cpp +++ b/modules/aruco/samples/create_board.cpp @@ -39,6 +39,8 @@ the use of this software, even if advised of the possibility of such damage. #include #include +#include +#include "samples_utility.hpp" using namespace cv; @@ -54,11 +56,13 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{m | | Margins size (in pixels). Default is marker separation (-s) }" "{bb | 1 | Number of bits in marker borders }" "{si | false | show generated image }"; } + int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -72,7 +76,6 @@ int main(int argc, char *argv[]) { int markersY = parser.get("h"); int markerLength = parser.get("l"); int markerSeparation = parser.get("s"); - int dictionaryId = parser.get("d"); int margins = markerSeparation; if(parser.has("m")) { margins = parser.get("m"); @@ -93,8 +96,23 @@ int main(int argc, char *argv[]) { imageSize.height = markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins; - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) + { + std::cerr << "Invalid dictionary file" << std::endl; + return 0; + } + } + else { + std::cerr << "Dictionary not specified" << std::endl; + return 0; + } Ptr board = aruco::GridBoard::create(markersX, markersY, float(markerLength), float(markerSeparation), dictionary); diff --git a/modules/aruco/samples/create_board_charuco.cpp b/modules/aruco/samples/create_board_charuco.cpp index 11313820137..4fc22b8bafd 100644 --- a/modules/aruco/samples/create_board_charuco.cpp +++ b/modules/aruco/samples/create_board_charuco.cpp @@ -39,11 +39,14 @@ the use of this software, even if advised of the possibility of such damage. #include #include +#include +#include "samples_utility.hpp" using namespace cv; namespace { const char* about = "Create a ChArUco board image"; +//! [charuco_detect_board_keys] const char* keys = "{@outfile | | Output image }" "{w | | Number of squares in X direction }" @@ -54,10 +57,13 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{m | | Margins size (in pixels). Default is (squareLength-markerLength) }" "{bb | 1 | Number of bits in marker borders }" "{si | false | show generated image }"; } +//! [charuco_detect_board_keys] + int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); @@ -72,7 +78,6 @@ int main(int argc, char *argv[]) { int squaresY = parser.get("h"); int squareLength = parser.get("sl"); int markerLength = parser.get("ml"); - int dictionaryId = parser.get("d"); int margins = squareLength - markerLength; if(parser.has("m")) { margins = parser.get("m"); @@ -88,8 +93,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + std::cerr << "Invalid dictionary file" << std::endl; + return 0; + } + } + else { + std::cerr << "Dictionary not specified" << std::endl; + return 0; + } Size imageSize; imageSize.width = squaresX * squareLength + 2 * margins; diff --git a/modules/aruco/samples/create_marker.cpp b/modules/aruco/samples/create_marker.cpp index 40537427446..f22815a376d 100644 --- a/modules/aruco/samples/create_marker.cpp +++ b/modules/aruco/samples/create_marker.cpp @@ -39,22 +39,28 @@ the use of this software, even if advised of the possibility of such damage. #include #include +#include +#include "samples_utility.hpp" using namespace cv; namespace { const char* about = "Create an ArUco marker image"; + +//! [aruco_create_markers_keys] const char* keys = "{@outfile | | Output image }" "{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2," "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{id | | Marker id in the dictionary }" "{ms | 200 | Marker size in pixels }" "{bb | 1 | Number of bits in marker borders }" "{si | false | show generated image }"; } +//! [aruco_create_markers_keys] int main(int argc, char *argv[]) { @@ -66,7 +72,6 @@ int main(int argc, char *argv[]) { return 0; } - int dictionaryId = parser.get("d"); int markerId = parser.get("id"); int borderBits = parser.get("bb"); int markerSize = parser.get("ms"); @@ -79,8 +84,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + std::cerr << "Invalid dictionary file" << std::endl; + return 0; + } + } + else { + std::cerr << "Dictionary not specified" << std::endl; + return 0; + } Mat markerImg; aruco::drawMarker(dictionary, markerId, markerSize, markerImg, borderBits); diff --git a/modules/aruco/samples/detect_board.cpp b/modules/aruco/samples/detect_board.cpp index f0cf583a49d..a7991f9137f 100644 --- a/modules/aruco/samples/detect_board.cpp +++ b/modules/aruco/samples/detect_board.cpp @@ -41,12 +41,15 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; namespace { const char* about = "Pose estimation using a ArUco Planar Grid board"; + +//! [aruco_detect_board_keys] const char* keys = "{w | | Number of squares in X direction }" "{h | | Number of squares in Y direction }" @@ -56,59 +59,17 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{c | | Output file with calibrated camera parameters }" - "{v | | Input from video file, if ommited, input comes from camera }" + "{v | | Input from video or image file, if omitted, input comes from camera }" "{ci | 0 | Camera id if input doesnt come from video (-v) }" "{dp | | File of marker detector parameters }" "{rs | | Apply refind strategy }" "{r | | show rejected candidates too }"; } - -/** - */ -static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeffs) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["camera_matrix"] >> camMatrix; - fs["distortion_coefficients"] >> distCoeffs; - return true; -} - - - -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} +//! [aruco_detect_board_keys] -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -122,7 +83,6 @@ int main(int argc, char *argv[]) { int markersY = parser.get("h"); float markerLength = parser.get("l"); float markerSeparation = parser.get("s"); - int dictionaryId = parser.get("d"); bool showRejected = parser.has("r"); bool refindStrategy = parser.has("rs"); int camId = parser.get("ci"); @@ -157,8 +117,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + cerr << "Invalid dictionary file" << endl; + return 0; + } + } + else { + cerr << "Dictionary not specified" << endl; + return 0; + } VideoCapture inputVideo; int waitTime; diff --git a/modules/aruco/samples/detect_board_charuco.cpp b/modules/aruco/samples/detect_board_charuco.cpp index fd106f366a3..482d89e689e 100644 --- a/modules/aruco/samples/detect_board_charuco.cpp +++ b/modules/aruco/samples/detect_board_charuco.cpp @@ -41,6 +41,7 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; @@ -57,58 +58,16 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{c | | Output file with calibrated camera parameters }" - "{v | | Input from video file, if ommited, input comes from camera }" + "{v | | Input from video or image file, if ommited, input comes from camera }" "{ci | 0 | Camera id if input doesnt come from video (-v) }" "{dp | | File of marker detector parameters }" "{rs | | Apply refind strategy }" "{r | | show rejected candidates too }"; } -/** - */ -static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeffs) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["camera_matrix"] >> camMatrix; - fs["distortion_coefficients"] >> distCoeffs; - return true; -} - - -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} - -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -122,7 +81,6 @@ int main(int argc, char *argv[]) { int squaresY = parser.get("h"); float squareLength = parser.get("sl"); float markerLength = parser.get("ml"); - int dictionaryId = parser.get("d"); bool showRejected = parser.has("r"); bool refindStrategy = parser.has("rs"); int camId = parser.get("ci"); @@ -155,8 +113,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + cerr << "Invalid dictionary file" << endl; + return 0; + } + } + else { + cerr << "Dictionary not specified" << endl; + return 0; + } VideoCapture inputVideo; int waitTime; diff --git a/modules/aruco/samples/detect_diamonds.cpp b/modules/aruco/samples/detect_diamonds.cpp index ae1e1b11762..a5e10a8b7bc 100644 --- a/modules/aruco/samples/detect_diamonds.cpp +++ b/modules/aruco/samples/detect_diamonds.cpp @@ -41,6 +41,7 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; @@ -55,6 +56,7 @@ const char* keys = "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16}" + "{cd | | Input file with custom dictionary }" "{c | | Output file with calibrated camera parameters }" "{as | | Automatic scale. The provided number is multiplied by the last" "diamond id becoming an indicator of the square length. In this case, the -sl and " @@ -63,53 +65,12 @@ const char* keys = "{ci | 0 | Camera id if input doesnt come from video (-v) }" "{dp | | File of marker detector parameters }" "{rs | | Apply refind strategy }" + "{refine | | Corner refinement: CORNER_REFINE_NONE=0, CORNER_REFINE_SUBPIX=1," + "CORNER_REFINE_CONTOUR=2, CORNER_REFINE_APRILTAG=3}" "{r | | show rejected candidates too }"; } -/** - */ -static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeffs) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["camera_matrix"] >> camMatrix; - fs["distortion_coefficients"] >> distCoeffs; - return true; -} - - -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} - -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -121,7 +82,6 @@ int main(int argc, char *argv[]) { float squareLength = parser.get("sl"); float markerLength = parser.get("ml"); - int dictionaryId = parser.get("d"); bool showRejected = parser.has("r"); bool estimatePose = parser.has("c"); bool autoScale = parser.has("as"); @@ -135,6 +95,11 @@ int main(int argc, char *argv[]) { return 0; } } + if (parser.has("refine")) { + //override cornerRefinementMethod read from config file + detectorParams->cornerRefinementMethod = parser.get("refine"); + } + std::cout << "Corner refinement method (0: None, 1: Subpixel, 2:contour, 3: AprilTag 2): " << detectorParams->cornerRefinementMethod << std::endl; int camId = parser.get("ci"); String video; @@ -148,8 +113,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + cerr << "Invalid dictionary file" << endl; + return 0; + } + } + else { + cerr << "Dictionary not specified" << endl; + return 0; + } Mat camMatrix, distCoeffs; if(estimatePose) { diff --git a/modules/aruco/samples/detect_markers.cpp b/modules/aruco/samples/detect_markers.cpp index dac27d1e0c2..ebfcc26ced8 100644 --- a/modules/aruco/samples/detect_markers.cpp +++ b/modules/aruco/samples/detect_markers.cpp @@ -40,19 +40,23 @@ the use of this software, even if advised of the possibility of such damage. #include #include #include +#include "samples_utility.hpp" using namespace std; using namespace cv; namespace { const char* about = "Basic marker detection"; + +//! [aruco_detect_markers_keys] const char* keys = "{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1, DICT_4X4_250=2," "DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6, DICT_5X5_1000=7, " "DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10, DICT_6X6_1000=11, DICT_7X7_50=12," "DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15, DICT_ARUCO_ORIGINAL = 16," "DICT_APRILTAG_16h5=17, DICT_APRILTAG_25h9=18, DICT_APRILTAG_36h10=19, DICT_APRILTAG_36h11=20}" - "{v | | Input from video file, if ommited, input comes from camera }" + "{cd | | Input file with custom dictionary }" + "{v | | Input from video or image file, if ommited, input comes from camera }" "{ci | 0 | Camera id if input doesnt come from video (-v) }" "{c | | Camera intrinsic parameters. Needed for camera pose }" "{l | 0.1 | Marker side length (in meters). Needed for correct scale in camera pose }" @@ -61,53 +65,8 @@ const char* keys = "{refine | | Corner refinement: CORNER_REFINE_NONE=0, CORNER_REFINE_SUBPIX=1," "CORNER_REFINE_CONTOUR=2, CORNER_REFINE_APRILTAG=3}"; } +//! [aruco_detect_markers_keys] -/** - */ -static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeffs) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["camera_matrix"] >> camMatrix; - fs["distortion_coefficients"] >> distCoeffs; - return true; -} - - - -/** - */ -static bool readDetectorParameters(string filename, Ptr ¶ms) { - FileStorage fs(filename, FileStorage::READ); - if(!fs.isOpened()) - return false; - fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; - fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; - fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; - fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; - fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; - fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; - fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; - fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; - fs["minDistanceToBorder"] >> params->minDistanceToBorder; - fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; - fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; - fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; - fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; - fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; - fs["markerBorderBits"] >> params->markerBorderBits; - fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; - fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; - fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; - fs["minOtsuStdDev"] >> params->minOtsuStdDev; - fs["errorCorrectionRate"] >> params->errorCorrectionRate; - return true; -} - - - -/** - */ int main(int argc, char *argv[]) { CommandLineParser parser(argc, argv, keys); parser.about(about); @@ -117,7 +76,6 @@ int main(int argc, char *argv[]) { return 0; } - int dictionaryId = parser.get("d"); bool showRejected = parser.has("r"); bool estimatePose = parser.has("c"); float markerLength = parser.get("l"); @@ -149,8 +107,22 @@ int main(int argc, char *argv[]) { return 0; } - Ptr dictionary = - aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + Ptr dictionary; + if (parser.has("d")) { + int dictionaryId = parser.get("d"); + dictionary = aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); + } + else if (parser.has("cd")) { + bool readOk = readDictionary(parser.get("cd"), dictionary); + if(!readOk) { + std::cerr << "Invalid dictionary file" << std::endl; + return 0; + } + } + else { + std::cerr << "Dictionary not specified" << std::endl; + return 0; + } Mat camMatrix, distCoeffs; if(estimatePose) { diff --git a/modules/aruco/samples/detector_params.yml b/modules/aruco/samples/detector_params.yml index ca3f74d9245..065f854c3c3 100644 --- a/modules/aruco/samples/detector_params.yml +++ b/modules/aruco/samples/detector_params.yml @@ -1,5 +1,4 @@ %YAML:1.0 -nmarkers: 1024 adaptiveThreshWinSizeMin: 3 adaptiveThreshWinSizeMax: 23 adaptiveThreshWinSizeStep: 10 diff --git a/modules/aruco/samples/samples_utility.hpp b/modules/aruco/samples/samples_utility.hpp new file mode 100644 index 00000000000..fccff061fef --- /dev/null +++ b/modules/aruco/samples/samples_utility.hpp @@ -0,0 +1,110 @@ +// This file is part of OpenCV project. +// It is subject to the license terms in the LICENSE file found in the top-level directory +// of this distribution and at http://opencv.org/license.html. + +#ifndef _SAMPLES_UTILITY_HPP_ +#define _SAMPLES_UTILITY_HPP_ + +#include +#include +#include +#include + +inline bool readCameraParameters(std::string filename, cv::Mat &camMatrix, cv::Mat &distCoeffs) { + cv::FileStorage fs(filename, cv::FileStorage::READ); + if(!fs.isOpened()) + return false; + fs["camera_matrix"] >> camMatrix; + fs["distortion_coefficients"] >> distCoeffs; + return true; +} + +inline bool saveCameraParams(const std::string &filename, cv::Size imageSize, float aspectRatio, int flags, + const cv::Mat &cameraMatrix, const cv::Mat &distCoeffs, double totalAvgErr) { + cv::FileStorage fs(filename, cv::FileStorage::WRITE); + if(!fs.isOpened()) + return false; + + time_t tt; + time(&tt); + struct tm *t2 = localtime(&tt); + char buf[1024]; + strftime(buf, sizeof(buf) - 1, "%c", t2); + + fs << "calibration_time" << buf; + + fs << "image_width" << imageSize.width; + fs << "image_height" << imageSize.height; + + if(flags & cv::CALIB_FIX_ASPECT_RATIO) fs << "aspectRatio" << aspectRatio; + + if(flags != 0) { + sprintf(buf, "flags: %s%s%s%s", + flags & cv::CALIB_USE_INTRINSIC_GUESS ? "+use_intrinsic_guess" : "", + flags & cv::CALIB_FIX_ASPECT_RATIO ? "+fix_aspectRatio" : "", + flags & cv::CALIB_FIX_PRINCIPAL_POINT ? "+fix_principal_point" : "", + flags & cv::CALIB_ZERO_TANGENT_DIST ? "+zero_tangent_dist" : ""); + } + + fs << "flags" << flags; + + fs << "camera_matrix" << cameraMatrix; + fs << "distortion_coefficients" << distCoeffs; + + fs << "avg_reprojection_error" << totalAvgErr; + + return true; +} + +inline bool readDetectorParameters(std::string filename, cv::Ptr ¶ms) { + cv::FileStorage fs(filename, cv::FileStorage::READ); + if(!fs.isOpened()) + return false; + fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin; + fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax; + fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep; + fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant; + fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate; + fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate; + fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate; + fs["minCornerDistanceRate"] >> params->minCornerDistanceRate; + fs["minDistanceToBorder"] >> params->minDistanceToBorder; + fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate; + fs["cornerRefinementMethod"] >> params->cornerRefinementMethod; + fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize; + fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations; + fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy; + fs["markerBorderBits"] >> params->markerBorderBits; + fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell; + fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell; + fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate; + fs["minOtsuStdDev"] >> params->minOtsuStdDev; + fs["errorCorrectionRate"] >> params->errorCorrectionRate; + return true; +} + +inline bool readDictionary(std::string filename, cv::Ptr &dictionary) +{ + cv::FileStorage fs(filename, cv::FileStorage::READ); + if (!fs.isOpened()) + return false; + int nMarkers = 0, markerSize = 0; + fs["nmarkers"] >> nMarkers; + fs["markersize"] >> markerSize; + + cv::Mat bytes(0, 0, CV_8UC1), marker(markerSize, markerSize, CV_8UC1); + std::string markerString; + for (int i = 0; i < nMarkers; i++) + { + std::ostringstream ostr; + ostr << i; + fs["marker_" + ostr.str()] >> markerString; + for (int j = 0; j < (int)markerString.size(); j++) + marker.at(j) = (markerString[j] == '0') ? 0 : 1; + bytes.push_back(cv::aruco::Dictionary::getByteListFromBits(marker)); + } + dictionary = cv::makePtr(bytes, markerSize); + return true; +} + +#endif diff --git a/modules/aruco/samples/tutorial_camera_charuco.yml b/modules/aruco/samples/tutorial_camera_charuco.yml new file mode 100644 index 00000000000..f1ded5993ad --- /dev/null +++ b/modules/aruco/samples/tutorial_camera_charuco.yml @@ -0,0 +1,21 @@ +%YAML:1.0 +--- +calibration_time: "Wed 08 Dec 2021 05:13:09 PM MSK" +image_width: 640 +image_height: 480 +flags: 0 +camera_matrix: !!opencv-matrix + rows: 3 + cols: 3 + dt: d + data: [ 4.5251072219637672e+02, 0., 3.1770297317353277e+02, 0., + 4.5676707935146891e+02, 2.7775155919135995e+02, 0., 0., 1. ] +distortion_coefficients: !!opencv-matrix + rows: 1 + cols: 5 + dt: d + data: [ 1.2136925618707872e-01, -1.0854664722560681e+00, + 1.1786843796668460e-04, -4.6240686046485508e-04, + 2.9542589406810080e+00 ] +avg_reprojection_error: 1.8234905535936044e-01 +info: "The camera calibration parameters were obtained by img_00.jpg-img_03.jpg from aruco/tutorials/aruco_calibration/images" diff --git a/modules/aruco/samples/tutorial_camera_params.yml b/modules/aruco/samples/tutorial_camera_params.yml new file mode 100644 index 00000000000..69d2d6d22ff --- /dev/null +++ b/modules/aruco/samples/tutorial_camera_params.yml @@ -0,0 +1,14 @@ +%YAML:1.0 +camera_matrix: !!opencv-matrix + rows: 3 + cols: 3 + dt: d + data: [ 628.158, 0., 324.099, + 0., 628.156, 260.908, + 0., 0., 1. ] +distortion_coefficients: !!opencv-matrix + rows: 5 + cols: 1 + dt: d + data: [ 0.0995485, -0.206384, + 0.00754589, 0.00336531, 0 ] diff --git a/modules/aruco/samples/tutorial_charuco_create_detect.cpp b/modules/aruco/samples/tutorial_charuco_create_detect.cpp index 5762a6307d4..d39c6063f4b 100644 --- a/modules/aruco/samples/tutorial_charuco_create_detect.cpp +++ b/modules/aruco/samples/tutorial_charuco_create_detect.cpp @@ -4,27 +4,14 @@ #include #include #include +#include "samples_utility.hpp" namespace { const char* about = "A tutorial code on charuco board creation and detection of charuco board with and without camera caliberation"; const char* keys = "{c | | Put value of c=1 to create charuco board;\nc=2 to detect charuco board without camera calibration;\nc=3 to detect charuco board with camera calibration and Pose Estimation}"; } -void createBoard(); -void detectCharucoBoardWithCalibrationPose(); -void detectCharucoBoardWithoutCalibration(); - -static bool readCameraParameters(std::string filename, cv::Mat& camMatrix, cv::Mat& distCoeffs) -{ - cv::FileStorage fs(filename, cv::FileStorage::READ); - if (!fs.isOpened()) - return false; - fs["camera_matrix"] >> camMatrix; - fs["distortion_coefficients"] >> distCoeffs; - return (camMatrix.size() == cv::Size(3,3)) ; -} - -void createBoard() +inline void createBoard() { cv::Ptr dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); //! [createBoard] @@ -36,7 +23,7 @@ void createBoard() } //! [detwcp] -void detectCharucoBoardWithCalibrationPose() +inline void detectCharucoBoardWithCalibrationPose() { cv::VideoCapture inputVideo; inputVideo.open(0); @@ -81,9 +68,8 @@ void detectCharucoBoardWithCalibrationPose() //! [detcor] cv::Vec3d rvec, tvec; //! [pose] - // cv::aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec); - //! [pose] bool valid = cv::aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, cameraMatrix, distCoeffs, rvec, tvec); + //! [pose] // if charuco pose is valid if (valid) cv::aruco::drawAxis(imageCopy, cameraMatrix, distCoeffs, rvec, tvec, 0.1f); @@ -99,7 +85,7 @@ void detectCharucoBoardWithCalibrationPose() //! [detwcp] //! [detwc] -void detectCharucoBoardWithoutCalibration() +inline void detectCharucoBoardWithoutCalibration() { cv::VideoCapture inputVideo; inputVideo.open(0); diff --git a/modules/aruco/samples/tutorial_dict.yml b/modules/aruco/samples/tutorial_dict.yml new file mode 100644 index 00000000000..752984302d3 --- /dev/null +++ b/modules/aruco/samples/tutorial_dict.yml @@ -0,0 +1,39 @@ +%YAML:1.0 +nmarkers: 35 +markersize: 6 +marker_0: "101011111011111001001001101100000000" +marker_1: "000000000010011001010011111010111000" +marker_2: "011001100000001010000101111101001101" +marker_3: "001000111111000111011001110000011111" +marker_4: "100110110100101111000000111101110011" +marker_5: "010101101110111000111010111100010111" +marker_6: "101001000110011110101001010100110100" +marker_7: "011010100100110000011101110110100010" +marker_8: "111110001000101000110001010010111101" +marker_9: "011101101100110111001100100001010100" +marker_10: "100001100001010001110001011000000111" +marker_11: "110010010010011100101111111000001111" +marker_12: "110101001001010110011111010110001101" +marker_13: "001111000001000100010001101001010001" +marker_14: "000000010010101010111110110011010011" +marker_15: "110001110111100101110011111100111010" +marker_16: "101011001110001010110011111011001110" +marker_17: "101110111101110100101101011001010111" +marker_18: "000100111000111101010011010101000101" +marker_19: "001110001110001101100101110100000011" +marker_20: "100101101100010110110110110001100011" +marker_21: "010110001001011010000100111000110110" +marker_22: "001000000000100100000000010100010010" +marker_23: "101001110010100110000111111010010000" +marker_24: "111001101010001100011010010001011100" +marker_25: "101000010001010000110100111101101001" +marker_26: "101010000001010011001010110110000001" +marker_27: "100101001000010101001000111101111110" +marker_28: "010010100110010011110001110101011100" +marker_29: "011001000101100001101111010001001111" +marker_30: "000111011100011110001101111011011001" +marker_31: "010100001011000100111101110001101010" +marker_32: "100101101001101010111111101101110100" +marker_33: "101101001010111000000100110111010101" +marker_34: "011111010000111011111110110101100101" +marker_35: "100010010000110011100011010001110110" diff --git a/modules/aruco/test/test_arucodetection.cpp b/modules/aruco/test/test_arucodetection.cpp index e56fdf81252..533fb730871 100644 --- a/modules/aruco/test/test_arucodetection.cpp +++ b/modules/aruco/test/test_arucodetection.cpp @@ -36,8 +36,9 @@ or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. */ - +#include #include "test_precomp.hpp" +#include "../samples/samples_utility.hpp" namespace opencv_test { namespace { @@ -554,4 +555,35 @@ TEST(CV_ArucoBitCorrection, algorithmic) { test.safe_run(); } +TEST(CV_ArucoTutorial, can_find_singlemarkersoriginal) +{ + string img_path = samples::findFile("../opencv_contrib/modules/aruco/tutorials/aruco_detection/images" + "/singlemarkersoriginal.jpg", true, true); + Mat image = imread(img_path); + Ptr dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); + vector< int > ids; + vector< vector< Point2f > > corners, rejected; + Ptr detectorParams = aruco::DetectorParameters::create(); + + aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected); + EXPECT_EQ(6, (int)ids.size()); +} + +TEST(CV_ArucoTutorial, can_find_gboriginal) +{ + string imgPath = samples::findFile("../opencv_contrib/modules/aruco/tutorials/aruco_board_detection" + "/images/gboriginal.png", true, true); + Mat image = imread(imgPath); + string dictPath = samples::findFile("../opencv_contrib/modules/aruco/samples" + "/tutorial_dict.yml", true, true); + cv::Ptr dictionary; + readDictionary(dictPath, dictionary); // set marker from tutorial_dict.yml + vector< int > ids; + vector< vector< Point2f > > corners, rejected; + Ptr detectorParams = aruco::DetectorParameters::create(); + + aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected); + EXPECT_EQ(35, (int)ids.size()); +} + }} // namespace diff --git a/modules/aruco/test/test_charucodetection.cpp b/modules/aruco/test/test_charucodetection.cpp index e803a031d92..d780a79d33e 100644 --- a/modules/aruco/test/test_charucodetection.cpp +++ b/modules/aruco/test/test_charucodetection.cpp @@ -38,6 +38,7 @@ the use of this software, even if advised of the possibility of such damage. #include "test_precomp.hpp" +#include "../samples/samples_utility.hpp" namespace opencv_test { namespace { @@ -677,4 +678,53 @@ TEST(Charuco, testCharucoCornersCollinear_false) EXPECT_FALSE(result); } +TEST(CV_ArucoTutorial, can_find_choriginal) +{ + string imgPath = samples::findFile("../opencv_contrib/modules/aruco/tutorials/charuco_detection" + "/images/choriginal.jpg", true, true); + Mat image = imread(imgPath); + cv::Ptr dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); + vector< int > ids; + vector< vector< Point2f > > corners, rejected; + Ptr detectorParams = aruco::DetectorParameters::create(); + + aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected); + EXPECT_EQ(17, (int)ids.size()); +} + +TEST(CV_ArucoTutorial, can_find_chocclusion) +{ + string imgPath = samples::findFile("../opencv_contrib/modules/aruco/tutorials/charuco_detection" + "/images/chocclusion_original.jpg", true, true); + Mat image = imread(imgPath); + cv::Ptr dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); + vector< int > ids; + vector< vector< Point2f > > corners, rejected; + Ptr detectorParams = aruco::DetectorParameters::create(); + + aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected); + EXPECT_EQ(13, (int)ids.size()); +} + +TEST(CV_ArucoTutorial, can_find_diamondmarkers) +{ + string imgPath = samples::findFile("../opencv_contrib/modules/aruco/tutorials/charuco_diamond_detection" + "/images/diamondmarkers.png", true, true); + Mat image = imread(imgPath); + string dictPath = samples::findFile("../opencv_contrib/modules/aruco/samples" + "/tutorial_dict.yml", true, true); + cv::Ptr dictionary; + readDictionary(dictPath, dictionary); // set marker from tutorial_dict.yml + vector< int > ids; + vector< vector< Point2f > > corners, rejected; + string detectorPath = samples::findFile("../opencv_contrib/modules/aruco/samples" + "/detector_params.yml", true, true); + Ptr detectorParams = aruco::DetectorParameters::create(); + readDetectorParameters(detectorPath, detectorParams); + detectorParams->cornerRefinementMethod = 3; + + aruco::detectMarkers(image, dictionary, corners, ids, detectorParams, rejected); + EXPECT_EQ(12, (int)ids.size()); +} + }} // namespace diff --git a/modules/aruco/tutorials/aruco_board_detection/aruco_board_detection.markdown b/modules/aruco/tutorials/aruco_board_detection/aruco_board_detection.markdown index fae0bd166ec..af3a0173a16 100644 --- a/modules/aruco/tutorials/aruco_board_detection/aruco_board_detection.markdown +++ b/modules/aruco/tutorials/aruco_board_detection/aruco_board_detection.markdown @@ -1,6 +1,9 @@ Detection of ArUco Boards {#tutorial_aruco_board_detection} ============================== +@prev_tutorial{tutorial_aruco_detection} +@next_tutorial{tutorial_charuco_detection} + An ArUco Board is a set of markers that acts like a single marker in the sense that it provides a single pose for the camera. @@ -55,7 +58,8 @@ The aruco module provides a specific function, ```estimatePoseBoard()```, to per cv::Mat inputImage; // camera parameters are read from somewhere cv::Mat cameraMatrix, distCoeffs; - readCameraParameters(cameraMatrix, distCoeffs); + // You can read camera parameters from tutorial_camera_params.yml + readCameraParameters(filename, cameraMatrix, distCoeffs); // This function is located in detect_board.cpp // assume we have a function to create the board object cv::Ptr board = cv::aruco::Board::create(); ... @@ -153,11 +157,11 @@ The output image will be something like this: ![](images/board.jpg) -A full working example of board creation is included in the ```create_board.cpp``` inside the module samples folder. +A full working example of board creation is included in the `create_board.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - "_output path_/aboard.png" -w=5 -h=7 -l=100 -s=10 -d=10 + "_output_path_/aboard.png" -w=5 -h=7 -l=100 -s=10 -d=10 @endcode Finally, a full example of board detection: @@ -167,10 +171,12 @@ Finally, a full example of board detection: inputVideo.open(0); cv::Mat cameraMatrix, distCoeffs; - // camera parameters are read from somewhere - readCameraParameters(cameraMatrix, distCoeffs); + // You can read camera parameters from tutorial_camera_params.yml + readCameraParameters(filename, cameraMatrix, distCoeffs); // This function is located in detect_board.cpp cv::Ptr dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); + // To use tutorial sample, you need read custome dictionaty from tutorial_dict.yml + readDictionary(filename, dictionary); // This function is located in detect_board.cpp cv::Ptr board = cv::aruco::GridBoard::create(5, 7, 0.04, 0.01, dictionary); while (inputVideo.grab()) { @@ -207,14 +213,20 @@ Sample video: @endhtmlonly -A full working example is included in the ```detect_board.cpp``` inside the module samples folder. +A full working example is included in the `detect_board.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - -c="_path_"/calib.txt" "_path_/aboard.png" -w=5 -h=7 -l=100 -s=10 -d=10 + -w=5 -h=7 -l=100 -s=10 + -v=/path_to_aruco_tutorials/aruco_board_detection/images/gboriginal.png + -c=/path_to_aruco_samples/tutorial_camera_params.yml + -cd=/path_to_aruco_samples/tutorial_dict.yml @endcode - - +Parameters for `detect_board.cpp`: +@snippet samples/detect_board.cpp aruco_detect_board_keys +@note To work with examples from the tutorial, you can use camera parameters from `tutorial_camera_params.yml` and +you need use custom dictionary from `tutorial_dict.yml`. +An example of usage in `detect_board.cpp`. Refine marker detection ----- diff --git a/modules/aruco/tutorials/aruco_calibration/aruco_calibration.markdown b/modules/aruco/tutorials/aruco_calibration/aruco_calibration.markdown index dbbdb026f9c..936658765c8 100644 --- a/modules/aruco/tutorials/aruco_calibration/aruco_calibration.markdown +++ b/modules/aruco/tutorials/aruco_calibration/aruco_calibration.markdown @@ -1,6 +1,9 @@ Calibration with ArUco and ChArUco {#tutorial_aruco_calibration} ============================== +@prev_tutorial{tutorial_charuco_diamond_detection} +@next_tutorial{tutorial_aruco_faq} + The ArUco module can also be used to calibrate a camera. Camera calibration consists in obtaining the camera intrinsic parameters and distortion coefficients. This parameters remain fixed unless the camera optic is modified, thus camera calibration only need to be done once. @@ -59,14 +62,16 @@ in each of the viewpoints. Finally, the ```calibrationFlags``` parameter determines some of the options for the calibration. Its format is equivalent to the flags parameter in the OpenCV ```calibrateCamera()``` function. -A full working example is included in the ```calibrate_camera_charuco.cpp``` inside the module samples folder. +A full working example is included in the `calibrate_camera_charuco.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - _output path_" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 + "output_path/camera_calib.txt" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 + -v="path_aruco/tutorials/aruco_calibration/images/img_%02d.jpg + -c=path_aruco/samples/tutorial_camera_params.yml @endcode - +The camera calibration parameters from `samples/tutorial_camera_charuco.yml` were obtained by `aruco_calibration/images/img_00.jpg-img_03.jpg`. Calibration with ArUco Boards ------ @@ -104,7 +109,7 @@ In this case, and contrary to the ```calibrateCameraCharuco()``` function, the d The rest of parameters are the same than in ```calibrateCameraCharuco()```, except the board layout object which does not need to be a ```CharucoBoard``` object, it can be any ```Board``` object. -A full working example is included in the ```calibrate_camera.cpp``` inside the module samples folder. +A full working example is included in the `calibrate_camera.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} diff --git a/modules/aruco/tutorials/aruco_calibration/images/img_00.jpg b/modules/aruco/tutorials/aruco_calibration/images/img_00.jpg new file mode 100644 index 00000000000..9609bbb54c8 Binary files /dev/null and b/modules/aruco/tutorials/aruco_calibration/images/img_00.jpg differ diff --git a/modules/aruco/tutorials/aruco_calibration/images/img_01.jpg b/modules/aruco/tutorials/aruco_calibration/images/img_01.jpg new file mode 100644 index 00000000000..3ca7c3149ff Binary files /dev/null and b/modules/aruco/tutorials/aruco_calibration/images/img_01.jpg differ diff --git a/modules/aruco/tutorials/aruco_calibration/images/img_02.jpg b/modules/aruco/tutorials/aruco_calibration/images/img_02.jpg new file mode 100644 index 00000000000..ef14eab4482 Binary files /dev/null and b/modules/aruco/tutorials/aruco_calibration/images/img_02.jpg differ diff --git a/modules/aruco/tutorials/aruco_calibration/images/img_03.jpg b/modules/aruco/tutorials/aruco_calibration/images/img_03.jpg new file mode 100644 index 00000000000..df311eb2321 Binary files /dev/null and b/modules/aruco/tutorials/aruco_calibration/images/img_03.jpg differ diff --git a/modules/aruco/tutorials/aruco_detection/aruco_detection.markdown b/modules/aruco/tutorials/aruco_detection/aruco_detection.markdown index 741ee3c77aa..be9bb690f51 100644 --- a/modules/aruco/tutorials/aruco_detection/aruco_detection.markdown +++ b/modules/aruco/tutorials/aruco_detection/aruco_detection.markdown @@ -1,6 +1,8 @@ Detection of ArUco Markers {#tutorial_aruco_detection} ============================== +@next_tutorial{tutorial_aruco_board_detection} + Pose estimation is of great importance in many computer vision applications: robot navigation, augmented reality, and many more. This process is based on finding correspondences between points in the real environment and their 2d image projection. This is usually a difficult step, and thus it is @@ -102,12 +104,14 @@ The generated image is: ![Generated marker](images/marker23.png) -A full working example is included in the `create_marker.cpp` inside the module samples folder. +A full working example is included in the `create_marker.cpp` inside the `modules/aruco/samples/`. -Note: The samples now take input from the command line using cv::CommandLineParser. For this file the example parameters will look like +Note: The samples now take input from the command line using cv::CommandLineParser. For this file the example parameters will look like: @code{.cpp} "marker23.png" -d=10 -id=23 @endcode +Parameters for `create_marker.cpp`: +@snippet samples/create_marker.cpp aruco_create_markers_keys Marker Detection ------ @@ -231,13 +235,14 @@ while (inputVideo.grab()) { Note that some of the optional parameters have been omitted, like the detection parameter object and the output vector of rejected candidates. -A full working example is included in the `detect_markers.cpp` inside the module samples folder. +A full working example is included in the `detect_markers.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input from the command line using cv::CommandLineParser. For this file the example parameters will look like @code{.cpp} --c="_path_/calib.txt" -d=10 +-v=/path_to_aruco_tutorials/aruco_detection/images/singlemarkersoriginal.jpg -d=10 @endcode - +Parameters for `detect_markers.cpp`: +@snippet samples/detect_markers.cpp aruco_detect_markers_keys Pose Estimation @@ -267,7 +272,9 @@ The aruco module provides a function to estimate the poses of all the detected m @code{.cpp} cv::Mat cameraMatrix, distCoeffs; -... +// You can read camera parameters from tutorial_camera_params.yml +readCameraParameters(filename, cameraMatrix, distCoeffs); // This function is located in detect_markers.cpp + std::vector rvecs, tvecs; cv::aruco::estimatePoseSingleMarkers(markerCorners, 0.05, cameraMatrix, distCoeffs, rvecs, tvecs); @endcode @@ -308,8 +315,8 @@ cv::VideoCapture inputVideo; inputVideo.open(0); cv::Mat cameraMatrix, distCoeffs; -// camera parameters are read from somewhere -readCameraParameters(cameraMatrix, distCoeffs); +// You can read camera parameters from tutorial_camera_params.yml +readCameraParameters(filename, cameraMatrix, distCoeffs); // This function is located in detect_markers.cpp cv::Ptr dictionary = cv::aruco::getPredefinedDictionary(cv::aruco::DICT_6X6_250); @@ -346,12 +353,17 @@ Sample video: @endhtmlonly -A full working example is included in the `detect_markers.cpp` inside the module samples folder. +A full working example is included in the `detect_markers.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input from the command line using cv::CommandLineParser. For this file the example parameters will look like @code{.cpp} - -c="_path_/calib.txt" -d=10 +-v=/path_to_aruco_tutorials/aruco_detection/images/singlemarkersoriginal.jpg -d=10 +-c=/path_to_aruco_samples/tutorial_camera_params.yml @endcode +Parameters for `detect_markers.cpp`: +@snippet samples/detect_markers.cpp aruco_detect_markers_keys +@note To work with examples from the tutorial, you can use camera parameters from `tutorial_camera_params.yml`. +An example of use in `detect.cpp`. @@ -766,4 +778,4 @@ too low, it can produce a poor subpixel refinement. Default values: - `int cornerRefinementMaxIterations = 30` -- `double cornerRefinementMinAccuracy = 0.1` +- `double cornerRefinementMinAccuracy = 0.1` \ No newline at end of file diff --git a/modules/aruco/tutorials/aruco_faq/aruco_faq.markdown b/modules/aruco/tutorials/aruco_faq/aruco_faq.markdown index d6fa418ae08..492b321de34 100644 --- a/modules/aruco/tutorials/aruco_faq/aruco_faq.markdown +++ b/modules/aruco/tutorials/aruco_faq/aruco_faq.markdown @@ -1,6 +1,8 @@ Aruco module FAQ {#tutorial_aruco_faq} ============================== +@prev_tutorial{tutorial_aruco_calibration} + This is a compilation of questions that can be useful for those that want to use the aruco module. - I only want to label some objects, what should I use? diff --git a/modules/aruco/tutorials/charuco_detection/charuco_detection.markdown b/modules/aruco/tutorials/charuco_detection/charuco_detection.markdown index 5e31b9f84d1..b26809cdaaa 100644 --- a/modules/aruco/tutorials/charuco_detection/charuco_detection.markdown +++ b/modules/aruco/tutorials/charuco_detection/charuco_detection.markdown @@ -1,6 +1,9 @@ -Detection of ChArUco Corners {#tutorial_charuco_detection} +Detection of ChArUco Boards {#tutorial_charuco_detection} ============================== +@prev_tutorial{tutorial_aruco_board_detection} +@next_tutorial{tutorial_charuco_diamond_detection} + ArUco markers and boards are very useful due to their fast detection and their versatility. However, one of the problems of ArUco markers is that the accuracy of their corner positions is not too high, even after applying subpixel refinement. @@ -87,11 +90,11 @@ The output image will be something like this: ![](images/charucoboard.jpg) -A full working example is included in the ```create_board_charuco.cpp``` inside the modules/aruco/samples/create_board_charuco.cpp. +A full working example is included in the `create_board_charuco.cpp` inside the `modules/aruco/samples/`. Note: The create_board_charuco.cpp now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - "_ output path_/chboard.png" -w=5 -h=7 -sl=200 -ml=120 -d=10 + "_output_path_/chboard.png" -w=5 -h=7 -sl=200 -ml=120 -d=10 @endcode @@ -180,15 +183,15 @@ This can be easily done using the ```drawDetectedCornersCharuco()``` function: For this image: -![Image with Charuco board](images/choriginal.png) +![Image with Charuco board](images/choriginal.jpg) The result will be: -![Charuco board detected](images/chcorners.png) +![Charuco board detected](images/chcorners.jpg) In the presence of occlusion. like in the following image, although some corners are clearly visible, not all their surrounding markers have been detected due occlusion and, thus, they are not interpolated: -![Charuco detection with occlusion](images/chocclusion.png) +![Charuco detection with occlusion](images/chocclusion.jpg) Finally, this is a full example of ChArUco detection (without using calibration parameters): @@ -200,15 +203,14 @@ Sample video: @endhtmlonly -A full working example is included in the ```detect_board_charuco.cpp``` inside the modules/aruco/samples/detect_board_charuco.cpp. +A full working example is included in the `detect_board_charuco.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - -c="_path_/calib.txt" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 + -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 + -v=/path_to_aruco_tutorials/charuco_detection/images/choriginal.jpg @endcode -Here the calib.txt is the output file generated by the calibrate_camera_charuco.cpp. - ChArUco Pose Estimation ------ @@ -231,15 +233,17 @@ not enough corners for pose estimation or they are in the same line. The axis can be drawn using ```drawAxis()``` to check the pose is correctly estimated. The result would be: (X:red, Y:green, Z:blue) -![Charuco Board Axis](images/chaxis.png) +![Charuco Board Axis](images/chaxis.jpg) A full example of ChArUco detection with pose estimation: @snippet samples/tutorial_charuco_create_detect.cpp detwcp -A full working example is included in the ```detect_board_charuco.cpp``` inside the modules/aruco/samples/detect_board_charuco.cpp. +A full working example is included in the `detect_board_charuco.cpp` inside the `modules/aruco/samples/detect_board_charuco.cpp`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - "_path_/calib.txt" -dp="_path_/detector_params.yml" -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 + -w=5 -h=7 -sl=0.04 -ml=0.02 -d=10 -dp="_path_/detector_params.yml" + -v=/path_to_aruco_tutorials/charuco_detection/images/choriginal.jpg + -c=/path_to_aruco_samples/tutorial_camera_charuco.yml @endcode diff --git a/modules/aruco/tutorials/charuco_detection/images/chaxis.jpg b/modules/aruco/tutorials/charuco_detection/images/chaxis.jpg new file mode 100644 index 00000000000..dbe96437426 Binary files /dev/null and b/modules/aruco/tutorials/charuco_detection/images/chaxis.jpg differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chaxis.png b/modules/aruco/tutorials/charuco_detection/images/chaxis.png deleted file mode 100644 index 8eed13ef519..00000000000 Binary files a/modules/aruco/tutorials/charuco_detection/images/chaxis.png and /dev/null differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chcorners.jpg b/modules/aruco/tutorials/charuco_detection/images/chcorners.jpg new file mode 100644 index 00000000000..20729461096 Binary files /dev/null and b/modules/aruco/tutorials/charuco_detection/images/chcorners.jpg differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chcorners.png b/modules/aruco/tutorials/charuco_detection/images/chcorners.png deleted file mode 100644 index 88506fecb0a..00000000000 Binary files a/modules/aruco/tutorials/charuco_detection/images/chcorners.png and /dev/null differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chocclusion.jpg b/modules/aruco/tutorials/charuco_detection/images/chocclusion.jpg new file mode 100644 index 00000000000..c3d08363bac Binary files /dev/null and b/modules/aruco/tutorials/charuco_detection/images/chocclusion.jpg differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chocclusion.png b/modules/aruco/tutorials/charuco_detection/images/chocclusion.png deleted file mode 100644 index b406263dbba..00000000000 Binary files a/modules/aruco/tutorials/charuco_detection/images/chocclusion.png and /dev/null differ diff --git a/modules/aruco/tutorials/charuco_detection/images/chocclusion_original.jpg b/modules/aruco/tutorials/charuco_detection/images/chocclusion_original.jpg new file mode 100644 index 00000000000..037a8eb1284 Binary files /dev/null and b/modules/aruco/tutorials/charuco_detection/images/chocclusion_original.jpg differ diff --git a/modules/aruco/tutorials/charuco_detection/images/choriginal.jpg b/modules/aruco/tutorials/charuco_detection/images/choriginal.jpg new file mode 100644 index 00000000000..3ca7c3149ff Binary files /dev/null and b/modules/aruco/tutorials/charuco_detection/images/choriginal.jpg differ diff --git a/modules/aruco/tutorials/charuco_detection/images/choriginal.png b/modules/aruco/tutorials/charuco_detection/images/choriginal.png deleted file mode 100644 index b211458c9dc..00000000000 Binary files a/modules/aruco/tutorials/charuco_detection/images/choriginal.png and /dev/null differ diff --git a/modules/aruco/tutorials/charuco_diamond_detection/charuco_diamond_detection.markdown b/modules/aruco/tutorials/charuco_diamond_detection/charuco_diamond_detection.markdown index c1a84df12ff..c26e645e212 100644 --- a/modules/aruco/tutorials/charuco_diamond_detection/charuco_diamond_detection.markdown +++ b/modules/aruco/tutorials/charuco_diamond_detection/charuco_diamond_detection.markdown @@ -1,6 +1,9 @@ Detection of Diamond Markers {#tutorial_charuco_diamond_detection} ============================== +@prev_tutorial{tutorial_charuco_detection} +@next_tutorial{tutorial_aruco_calibration} + A ChArUco diamond marker (or simply diamond marker) is a chessboard composed by 3x3 squares and 4 ArUco markers inside the white squares. It is similar to a ChArUco board in appearance, however they are conceptually different. @@ -58,7 +61,7 @@ The image produced will be: ![Diamond marker](images/diamondmarker.png) -A full working example is included in the ```create_diamond.cpp``` inside the module samples folder. +A full working example is included in the `create_diamond.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} @@ -118,11 +121,13 @@ The result is the same that the one produced by ```drawDetectedMarkers()```, but ![Detected diamond markers](images/detecteddiamonds.png) -A full working example is included in the ```detect_diamonds.cpp``` inside the module samples folder. +A full working example is included in the `detect_diamonds.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - -c="_path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10 + -dp="path_aruco/samples/detector_params.yml" -sl=0.04 -ml=0.012 -refine=3 + -v="path_aruco/tutorials/charuco_diamond_detection/images/diamondmarkers.png" + -cd="path_aruco/samples/tutorial_dict.yml @endcode ChArUco Diamond Pose Estimation @@ -166,9 +171,12 @@ Sample video: @endhtmlonly -A full working example is included in the ```detect_diamonds.cpp``` inside the module samples folder. +A full working example is included in the `detect_diamonds.cpp` inside the `modules/aruco/samples/`. Note: The samples now take input via commandline via the [OpenCV Commandline Parser](http://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#gsc.tab=0). For this file the example parameters will look like @code{.cpp} - -c="_output path_/calib.txt" -dp="_path_/detector_params.yml" -sl=0.04 -ml=0.02 -d=10 + -dp="path_aruco/samples/detector_params.yml" -sl=0.04 -ml=0.012 -refine=3 + -v="path_aruco/tutorials/charuco_diamond_detection/images/diamondmarkers.png" + -cd="path_aruco/samples/tutorial_dict.yml + -c="path_aruco/samples/tutorial_camera_params.yml" @endcode