Commit 063c191d authored by folz's avatar folz

aruco: Use shared Ptrs to support exporting

parent 9b06bb28
...@@ -121,30 +121,32 @@ namespace aruco { ...@@ -121,30 +121,32 @@ namespace aruco {
* - errorCorrectionRate error correction rate respect to the maximun error correction capability * - errorCorrectionRate error correction rate respect to the maximun error correction capability
* for each dictionary. (default 0.6). * for each dictionary. (default 0.6).
*/ */
struct CV_EXPORTS DetectorParameters { struct CV_EXPORTS_W DetectorParameters {
DetectorParameters(); DetectorParameters();
int adaptiveThreshWinSizeMin; CV_WRAP static Ptr<DetectorParameters> create();
int adaptiveThreshWinSizeMax;
int adaptiveThreshWinSizeStep; CV_PROP_RW int adaptiveThreshWinSizeMin;
double adaptiveThreshConstant; CV_PROP_RW int adaptiveThreshWinSizeMax;
double minMarkerPerimeterRate; CV_PROP_RW int adaptiveThreshWinSizeStep;
double maxMarkerPerimeterRate; CV_PROP_RW double adaptiveThreshConstant;
double polygonalApproxAccuracyRate; CV_PROP_RW double minMarkerPerimeterRate;
double minCornerDistanceRate; CV_PROP_RW double maxMarkerPerimeterRate;
int minDistanceToBorder; CV_PROP_RW double polygonalApproxAccuracyRate;
double minMarkerDistanceRate; CV_PROP_RW double minCornerDistanceRate;
bool doCornerRefinement; CV_PROP_RW int minDistanceToBorder;
int cornerRefinementWinSize; CV_PROP_RW double minMarkerDistanceRate;
int cornerRefinementMaxIterations; CV_PROP_RW bool doCornerRefinement;
double cornerRefinementMinAccuracy; CV_PROP_RW int cornerRefinementWinSize;
int markerBorderBits; CV_PROP_RW int cornerRefinementMaxIterations;
int perspectiveRemovePixelPerCell; CV_PROP_RW double cornerRefinementMinAccuracy;
double perspectiveRemoveIgnoredMarginPerCell; CV_PROP_RW int markerBorderBits;
double maxErroneousBitsInBorderRate; CV_PROP_RW int perspectiveRemovePixelPerCell;
double minOtsuStdDev; CV_PROP_RW double perspectiveRemoveIgnoredMarginPerCell;
double errorCorrectionRate; CV_PROP_RW double maxErroneousBitsInBorderRate;
CV_PROP_RW double minOtsuStdDev;
CV_PROP_RW double errorCorrectionRate;
}; };
...@@ -171,9 +173,9 @@ struct CV_EXPORTS DetectorParameters { ...@@ -171,9 +173,9 @@ struct CV_EXPORTS DetectorParameters {
* @sa estimatePoseSingleMarkers, estimatePoseBoard * @sa estimatePoseSingleMarkers, estimatePoseBoard
* *
*/ */
CV_EXPORTS void detectMarkers(InputArray image, Dictionary dictionary, OutputArrayOfArrays corners, CV_EXPORTS_W void detectMarkers(InputArray image, Ptr<Dictionary> &dictionary, OutputArrayOfArrays corners,
OutputArray ids, DetectorParameters parameters = DetectorParameters(), OutputArray ids, const Ptr<DetectorParameters> &parameters = DetectorParameters::create(),
OutputArrayOfArrays rejectedImgPoints = noArray()); OutputArrayOfArrays rejectedImgPoints = noArray());
...@@ -205,9 +207,9 @@ CV_EXPORTS void detectMarkers(InputArray image, Dictionary dictionary, OutputArr ...@@ -205,9 +207,9 @@ CV_EXPORTS void detectMarkers(InputArray image, Dictionary dictionary, OutputArr
* (-markerLength/2, markerLength/2, 0), (markerLength/2, markerLength/2, 0), * (-markerLength/2, markerLength/2, 0), (markerLength/2, markerLength/2, 0),
* (markerLength/2, -markerLength/2, 0), (-markerLength/2, -markerLength/2, 0) * (markerLength/2, -markerLength/2, 0), (-markerLength/2, -markerLength/2, 0)
*/ */
CV_EXPORTS void estimatePoseSingleMarkers(InputArrayOfArrays corners, float markerLength, CV_EXPORTS_W void estimatePoseSingleMarkers(InputArrayOfArrays corners, float markerLength,
InputArray cameraMatrix, InputArray distCoeffs, InputArray cameraMatrix, InputArray distCoeffs,
OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs); OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs);
...@@ -221,7 +223,7 @@ CV_EXPORTS void estimatePoseSingleMarkers(InputArrayOfArrays corners, float mark ...@@ -221,7 +223,7 @@ CV_EXPORTS void estimatePoseSingleMarkers(InputArrayOfArrays corners, float mark
* - The dictionary which indicates the type of markers of the board * - The dictionary which indicates the type of markers of the board
* - The identifier of all the markers in the board. * - The identifier of all the markers in the board.
*/ */
class CV_EXPORTS Board { class CV_EXPORTS_W Board {
public: public:
// array of object points of all the marker corners in the board // array of object points of all the marker corners in the board
...@@ -229,7 +231,7 @@ class CV_EXPORTS Board { ...@@ -229,7 +231,7 @@ class CV_EXPORTS Board {
std::vector< std::vector< Point3f > > objPoints; std::vector< std::vector< Point3f > > objPoints;
// the dictionary of markers employed for this board // the dictionary of markers employed for this board
Dictionary dictionary; Ptr<Dictionary> dictionary;
// vector of the identifiers of the markers in the board (same size than objPoints) // vector of the identifiers of the markers in the board (same size than objPoints)
// The identifiers refers to the board dictionary // The identifiers refers to the board dictionary
...@@ -243,7 +245,7 @@ class CV_EXPORTS Board { ...@@ -243,7 +245,7 @@ class CV_EXPORTS Board {
* More common type of board. All markers are placed in the same plane in a grid arrangment. * More common type of board. All markers are placed in the same plane in a grid arrangment.
* The board can be drawn using drawPlanarBoard() function (@sa drawPlanarBoard) * The board can be drawn using drawPlanarBoard() function (@sa drawPlanarBoard)
*/ */
class CV_EXPORTS GridBoard : public Board { class CV_EXPORTS_W GridBoard : public Board {
public: public:
/** /**
...@@ -274,8 +276,8 @@ class CV_EXPORTS GridBoard : public Board { ...@@ -274,8 +276,8 @@ class CV_EXPORTS GridBoard : public Board {
* This functions creates a GridBoard object given the number of markers in each direction and * This functions creates a GridBoard object given the number of markers in each direction and
* the marker size and marker separation. * the marker size and marker separation.
*/ */
static GridBoard create(int markersX, int markersY, float markerLength, float markerSeparation, CV_WRAP static Ptr<GridBoard> create(int markersX, int markersY, float markerLength,
Dictionary dictionary); float markerSeparation, Ptr<Dictionary> &dictionary);
/** /**
* *
...@@ -332,9 +334,9 @@ class CV_EXPORTS GridBoard : public Board { ...@@ -332,9 +334,9 @@ class CV_EXPORTS GridBoard : public Board {
* The function returns the number of markers from the input employed for the board pose estimation. * The function returns the number of markers from the input employed for the board pose estimation.
* Note that returning a 0 means the pose has not been estimated. * Note that returning a 0 means the pose has not been estimated.
*/ */
CV_EXPORTS int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, const Board &board, CV_EXPORTS_W int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, Ptr<Board> &board,
InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec, InputArray cameraMatrix, InputArray distCoeffs, OutputArray rvec,
OutputArray tvec); OutputArray tvec);
...@@ -370,12 +372,12 @@ CV_EXPORTS int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, con ...@@ -370,12 +372,12 @@ CV_EXPORTS int estimatePoseBoard(InputArrayOfArrays corners, InputArray ids, con
* using projectPoint function. If not, missing marker projections are interpolated using global * using projectPoint function. If not, missing marker projections are interpolated using global
* homography, and all the marker corners in the board must have the same Z coordinate. * homography, and all the marker corners in the board must have the same Z coordinate.
*/ */
CV_EXPORTS void refineDetectedMarkers( CV_EXPORTS_W void refineDetectedMarkers(
InputArray image, const Board &board, InputOutputArrayOfArrays detectedCorners, InputArray image, Ptr<Board> &board, InputOutputArrayOfArrays detectedCorners,
InputOutputArray detectedIds, InputOutputArray rejectedCorners, InputOutputArray detectedIds, InputOutputArray rejectedCorners,
InputArray cameraMatrix = noArray(), InputArray distCoeffs = noArray(), InputArray cameraMatrix = noArray(), InputArray distCoeffs = noArray(),
float minRepDistance = 10.f, float errorCorrectionRate = 3.f, bool checkAllOrders = true, float minRepDistance = 10.f, float errorCorrectionRate = 3.f, bool checkAllOrders = true,
OutputArray recoveredIdxs = noArray(), DetectorParameters parameters = DetectorParameters()); OutputArray recoveredIdxs = noArray(), const Ptr<DetectorParameters> &parameters = DetectorParameters::create());
...@@ -396,9 +398,9 @@ CV_EXPORTS void refineDetectedMarkers( ...@@ -396,9 +398,9 @@ CV_EXPORTS void refineDetectedMarkers(
* the markers in the image. The marker borders are painted and the markers identifiers if provided. * the markers in the image. The marker borders are painted and the markers identifiers if provided.
* Useful for debugging purposes. * Useful for debugging purposes.
*/ */
CV_EXPORTS void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays corners, CV_EXPORTS_W void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays corners,
InputArray ids = noArray(), InputArray ids = noArray(),
Scalar borderColor = Scalar(0, 255, 0)); Scalar borderColor = Scalar(0, 255, 0));
...@@ -418,8 +420,8 @@ CV_EXPORTS void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays c ...@@ -418,8 +420,8 @@ CV_EXPORTS void drawDetectedMarkers(InputOutputArray image, InputArrayOfArrays c
* Given the pose estimation of a marker or board, this function draws the axis of the world * Given the pose estimation of a marker or board, this function draws the axis of the world
* coordinate system, i.e. the system centered on the marker/board. Useful for debugging purposes. * coordinate system, i.e. the system centered on the marker/board. Useful for debugging purposes.
*/ */
CV_EXPORTS void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs, CV_EXPORTS_W void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputArray distCoeffs,
InputArray rvec, InputArray tvec, float length); InputArray rvec, InputArray tvec, float length);
...@@ -435,13 +437,14 @@ CV_EXPORTS void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputA ...@@ -435,13 +437,14 @@ CV_EXPORTS void drawAxis(InputOutputArray image, InputArray cameraMatrix, InputA
* *
* This function returns a marker image in its canonical form (i.e. ready to be printed) * This function returns a marker image in its canonical form (i.e. ready to be printed)
*/ */
CV_EXPORTS void drawMarker(Dictionary dictionary, int id, int sidePixels, OutputArray img, CV_EXPORTS_W void drawMarker(Ptr<Dictionary> &dictionary, int id, int sidePixels, OutputArray img,
int borderBits = 1); int borderBits = 1);
/** /**
* @brief Draw a planar board * @brief Draw a planar board
* @sa _drawPlanarBoardImpl
* *
* @param board layout of the board that will be drawn. The board should be planar, * @param board layout of the board that will be drawn. The board should be planar,
* z coordinate is ignored * z coordinate is ignored
...@@ -454,8 +457,16 @@ CV_EXPORTS void drawMarker(Dictionary dictionary, int id, int sidePixels, Output ...@@ -454,8 +457,16 @@ CV_EXPORTS void drawMarker(Dictionary dictionary, int id, int sidePixels, Output
* This function return the image of a planar board, ready to be printed. It assumes * This function return the image of a planar board, ready to be printed. It assumes
* the Board layout specified is planar by ignoring the z coordinates of the object points. * the Board layout specified is planar by ignoring the z coordinates of the object points.
*/ */
CV_EXPORTS void drawPlanarBoard(const Board &board, Size outSize, OutputArray img, CV_EXPORTS_W void drawPlanarBoard(Ptr<Board> &board, Size outSize, OutputArray img,
int marginSize = 0, int borderBits = 1); int marginSize = 0, int borderBits = 1);
/**
* @brief Implementation of drawPlanarBoard that accepts a raw Board pointer.
*/
void _drawPlanarBoardImpl(Board *board, Size outSize, OutputArray img,
int marginSize = 0, int borderBits = 1);
...@@ -487,8 +498,8 @@ CV_EXPORTS void drawPlanarBoard(const Board &board, Size outSize, OutputArray im ...@@ -487,8 +498,8 @@ CV_EXPORTS void drawPlanarBoard(const Board &board, Size outSize, OutputArray im
* detected markers from several views of the Board. The process is similar to the chessboard * detected markers from several views of the Board. The process is similar to the chessboard
* calibration in calibrateCamera(). The function returns the final re-projection error. * calibration in calibrateCamera(). The function returns the final re-projection error.
*/ */
CV_EXPORTS double calibrateCameraAruco( CV_EXPORTS_W double calibrateCameraAruco(
InputArrayOfArrays corners, InputArray ids, InputArray counter, const Board &board, InputArrayOfArrays corners, InputArray ids, InputArray counter, Ptr<Board> &board,
Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0, OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)); TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON));
......
...@@ -59,7 +59,7 @@ namespace aruco { ...@@ -59,7 +59,7 @@ namespace aruco {
* calibration and pose estimation. * calibration and pose estimation.
* This class also allows the easy creation and drawing of ChArUco boards. * This class also allows the easy creation and drawing of ChArUco boards.
*/ */
class CV_EXPORTS CharucoBoard : public Board { class CV_EXPORTS_W CharucoBoard : public Board {
public: public:
// vector of chessboard 3D corners precalculated // vector of chessboard 3D corners precalculated
...@@ -97,8 +97,8 @@ class CV_EXPORTS CharucoBoard : public Board { ...@@ -97,8 +97,8 @@ class CV_EXPORTS CharucoBoard : public Board {
* This functions creates a CharucoBoard object given the number of squares in each direction * This functions creates a CharucoBoard object given the number of squares in each direction
* and the size of the markers and chessboard squares. * and the size of the markers and chessboard squares.
*/ */
static CharucoBoard create(int squaresX, int squaresY, float squareLength, float markerLength, CV_WRAP static Ptr<CharucoBoard> create(int squaresX, int squaresY, float squareLength,
Dictionary dictionary); float markerLength, Ptr<Dictionary> &dictionary);
/** /**
* *
...@@ -154,11 +154,11 @@ class CV_EXPORTS CharucoBoard : public Board { ...@@ -154,11 +154,11 @@ class CV_EXPORTS CharucoBoard : public Board {
* also returned in charucoIds. * also returned in charucoIds.
* The function returns the number of interpolated corners. * The function returns the number of interpolated corners.
*/ */
CV_EXPORTS int interpolateCornersCharuco(InputArrayOfArrays markerCorners, InputArray markerIds, CV_EXPORTS_W int interpolateCornersCharuco(InputArrayOfArrays markerCorners, InputArray markerIds,
InputArray image, const CharucoBoard &board, InputArray image, Ptr<CharucoBoard> &board,
OutputArray charucoCorners, OutputArray charucoIds, OutputArray charucoCorners, OutputArray charucoIds,
InputArray cameraMatrix = noArray(), InputArray cameraMatrix = noArray(),
InputArray distCoeffs = noArray()); InputArray distCoeffs = noArray());
...@@ -180,9 +180,9 @@ CV_EXPORTS int interpolateCornersCharuco(InputArrayOfArrays markerCorners, Input ...@@ -180,9 +180,9 @@ CV_EXPORTS int interpolateCornersCharuco(InputArrayOfArrays markerCorners, Input
* The function checks if the input corners are enough and valid to perform pose estimation. * The function checks if the input corners are enough and valid to perform pose estimation.
* If pose estimation is valid, returns true, else returns false. * If pose estimation is valid, returns true, else returns false.
*/ */
CV_EXPORTS bool estimatePoseCharucoBoard(InputArray charucoCorners, InputArray charucoIds, CV_EXPORTS_W bool estimatePoseCharucoBoard(InputArray charucoCorners, InputArray charucoIds,
CharucoBoard &board, InputArray cameraMatrix, Ptr<CharucoBoard> &board, InputArray cameraMatrix,
InputArray distCoeffs, OutputArray rvec, OutputArray tvec); InputArray distCoeffs, OutputArray rvec, OutputArray tvec);
...@@ -198,9 +198,9 @@ CV_EXPORTS bool estimatePoseCharucoBoard(InputArray charucoCorners, InputArray c ...@@ -198,9 +198,9 @@ CV_EXPORTS bool estimatePoseCharucoBoard(InputArray charucoCorners, InputArray c
* This function draws a set of detected Charuco corners. If identifiers vector is provided, it also * This function draws a set of detected Charuco corners. If identifiers vector is provided, it also
* draws the id of each corner. * draws the id of each corner.
*/ */
CV_EXPORTS void drawDetectedCornersCharuco(InputOutputArray image, InputArray charucoCorners, CV_EXPORTS_W void drawDetectedCornersCharuco(InputOutputArray image, InputArray charucoCorners,
InputArray charucoIds = noArray(), InputArray charucoIds = noArray(),
Scalar cornerColor = Scalar(255, 0, 0)); Scalar cornerColor = Scalar(255, 0, 0));
...@@ -230,8 +230,8 @@ CV_EXPORTS void drawDetectedCornersCharuco(InputOutputArray image, InputArray ch ...@@ -230,8 +230,8 @@ CV_EXPORTS void drawDetectedCornersCharuco(InputOutputArray image, InputArray ch
* receives a list of detected corners and its identifiers from several views of the Board. * receives a list of detected corners and its identifiers from several views of the Board.
* The function returns the final re-projection error. * The function returns the final re-projection error.
*/ */
CV_EXPORTS double calibrateCameraCharuco( CV_EXPORTS_W double calibrateCameraCharuco(
InputArrayOfArrays charucoCorners, InputArrayOfArrays charucoIds, const CharucoBoard &board, InputArrayOfArrays charucoCorners, InputArrayOfArrays charucoIds, Ptr<CharucoBoard> &board,
Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs,
OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0, OutputArrayOfArrays rvecs = noArray(), OutputArrayOfArrays tvecs = noArray(), int flags = 0,
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON)); TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 30, DBL_EPSILON));
...@@ -261,11 +261,11 @@ CV_EXPORTS double calibrateCameraCharuco( ...@@ -261,11 +261,11 @@ CV_EXPORTS double calibrateCameraCharuco(
* are provided, the diamond search is based on reprojection. If not, diamond search is based on * are provided, the diamond search is based on reprojection. If not, diamond search is based on
* homography. Homography is faster than reprojection but can slightly reduce the detection rate. * homography. Homography is faster than reprojection but can slightly reduce the detection rate.
*/ */
CV_EXPORTS void detectCharucoDiamond(InputArray image, InputArrayOfArrays markerCorners, CV_EXPORTS_W void detectCharucoDiamond(InputArray image, InputArrayOfArrays markerCorners,
InputArray markerIds, float squareMarkerLengthRate, InputArray markerIds, float squareMarkerLengthRate,
OutputArrayOfArrays diamondCorners, OutputArray diamondIds, OutputArrayOfArrays diamondCorners, OutputArray diamondIds,
InputArray cameraMatrix = noArray(), InputArray cameraMatrix = noArray(),
InputArray distCoeffs = noArray()); InputArray distCoeffs = noArray());
...@@ -287,9 +287,9 @@ CV_EXPORTS void detectCharucoDiamond(InputArray image, InputArrayOfArrays marker ...@@ -287,9 +287,9 @@ CV_EXPORTS void detectCharucoDiamond(InputArray image, InputArrayOfArrays marker
* are painted and the markers identifiers if provided. * are painted and the markers identifiers if provided.
* Useful for debugging purposes. * Useful for debugging purposes.
*/ */
CV_EXPORTS void drawDetectedDiamonds(InputOutputArray image, InputArrayOfArrays diamondCorners, CV_EXPORTS_W void drawDetectedDiamonds(InputOutputArray image, InputArrayOfArrays diamondCorners,
InputArray diamondIds = noArray(), InputArray diamondIds = noArray(),
Scalar borderColor = Scalar(0, 0, 255)); Scalar borderColor = Scalar(0, 0, 255));
...@@ -308,7 +308,8 @@ CV_EXPORTS void drawDetectedDiamonds(InputOutputArray image, InputArrayOfArrays ...@@ -308,7 +308,8 @@ CV_EXPORTS void drawDetectedDiamonds(InputOutputArray image, InputArrayOfArrays
* *
* This function return the image of a ChArUco marker, ready to be printed. * This function return the image of a ChArUco marker, ready to be printed.
*/ */
CV_EXPORTS void drawCharucoDiamond(Dictionary dictionary, Vec4i ids, int squareLength, // TODO cannot be exported yet; conversion from/to Vec4i is not wrapped in core
CV_EXPORTS void drawCharucoDiamond(Ptr<Dictionary> &dictionary, Vec4i ids, int squareLength,
int markerLength, OutputArray img, int marginSize = 0, int markerLength, OutputArray img, int marginSize = 0,
int borderBits = 1); int borderBits = 1);
......
...@@ -58,12 +58,12 @@ namespace aruco { ...@@ -58,12 +58,12 @@ namespace aruco {
* *
* `bytesList.ptr(i)[k*nbytes + j]` is then the j-th byte of i-th marker, in its k-th rotation. * `bytesList.ptr(i)[k*nbytes + j]` is then the j-th byte of i-th marker, in its k-th rotation.
*/ */
class CV_EXPORTS Dictionary { class CV_EXPORTS_W Dictionary {
public: public:
Mat bytesList; // marker code information CV_PROP_RW Mat bytesList; // marker code information
int markerSize; // number of bits per dimension CV_PROP_RW int markerSize; // number of bits per dimension
int maxCorrectionBits; // maximum number of bits that can be corrected CV_PROP_RW int maxCorrectionBits; // maximum number of bits that can be corrected
/** /**
...@@ -71,6 +71,32 @@ class CV_EXPORTS Dictionary { ...@@ -71,6 +71,32 @@ class CV_EXPORTS Dictionary {
Dictionary(const Mat &_bytesList = Mat(), int _markerSize = 0, int _maxcorr = 0); Dictionary(const Mat &_bytesList = Mat(), int _markerSize = 0, int _maxcorr = 0);
/**
Dictionary(const Dictionary &_dictionary);
*/
/**
*/
Dictionary(const Ptr<Dictionary> &_dictionary);
/**
* @see generateCustomDictionary
*/
CV_WRAP_AS(create) static Ptr<Dictionary> create(int nMarkers, int markerSize);
/**
* @see generateCustomDictionary
*/
CV_WRAP_AS(create_from) static Ptr<Dictionary> create(int nMarkers, int markerSize,
Ptr<Dictionary> &baseDictionary);
/**
* @see getPredefinedDictionary
*/
CV_WRAP static Ptr<Dictionary> get(int dict);
/** /**
* @brief Given a matrix of bits. Returns whether if marker is identified or not. * @brief Given a matrix of bits. Returns whether if marker is identified or not.
...@@ -109,9 +135,10 @@ class CV_EXPORTS Dictionary { ...@@ -109,9 +135,10 @@ class CV_EXPORTS Dictionary {
/** /**
* @brief Predefined markers dictionaries/sets * @brief Predefined markers dictionaries/sets
* Each dictionary indicates the number of bits and the number of markers contained * Each dictionary indicates the number of bits and the number of markers contained
* - DICT_ARUCO: standard ArUco Library Markers. 1024 markers, 5x5 bits, 0 minimum distance * - DICT_ARUCO_ORIGINAL: standard ArUco Library Markers. 1024 markers, 5x5 bits, 0 minimum
distance
*/ */
enum PREDEFINED_DICTIONARY_NAME { enum CV_EXPORTS_W_SIMPLE PREDEFINED_DICTIONARY_NAME {
DICT_4X4_50 = 0, DICT_4X4_50 = 0,
DICT_4X4_100, DICT_4X4_100,
DICT_4X4_250, DICT_4X4_250,
...@@ -135,7 +162,21 @@ enum PREDEFINED_DICTIONARY_NAME { ...@@ -135,7 +162,21 @@ enum PREDEFINED_DICTIONARY_NAME {
/** /**
* @brief Returns one of the predefined dictionaries defined in PREDEFINED_DICTIONARY_NAME * @brief Returns one of the predefined dictionaries defined in PREDEFINED_DICTIONARY_NAME
*/ */
CV_EXPORTS const Dictionary &getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name); CV_EXPORTS Ptr<Dictionary> getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name);
/**
* @brief Returns one of the predefined dictionaries referenced by DICT_*.
*/
CV_EXPORTS_W Ptr<Dictionary> getPredefinedDictionary(int dict);
/**
* @see generateCustomDictionary
*/
CV_EXPORTS_AS(custom_dictionary) Ptr<Dictionary> generateCustomDictionary(
int nMarkers,
int markerSize);
/** /**
...@@ -150,8 +191,10 @@ CV_EXPORTS const Dictionary &getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME ...@@ -150,8 +191,10 @@ CV_EXPORTS const Dictionary &getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME
* included and the rest are generated based on them. If the size of baseDictionary is higher * included and the rest are generated based on them. If the size of baseDictionary is higher
* than nMarkers, only the first nMarkers in baseDictionary are taken and no new marker is added. * than nMarkers, only the first nMarkers in baseDictionary are taken and no new marker is added.
*/ */
CV_EXPORTS Dictionary generateCustomDictionary(int nMarkers, int markerSize, CV_EXPORTS_AS(custom_dictionary_from) Ptr<Dictionary> generateCustomDictionary(
const Dictionary &baseDictionary = Dictionary()); int nMarkers,
int markerSize,
Ptr<Dictionary> &baseDictionary);
......
...@@ -76,30 +76,30 @@ const char* keys = ...@@ -76,30 +76,30 @@ const char* keys =
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -173,7 +173,7 @@ int main(int argc, char *argv[]) { ...@@ -173,7 +173,7 @@ int main(int argc, char *argv[]) {
if(parser.get<bool>("zt")) calibrationFlags |= CALIB_ZERO_TANGENT_DIST; if(parser.get<bool>("zt")) calibrationFlags |= CALIB_ZERO_TANGENT_DIST;
if(parser.get<bool>("pc")) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT; if(parser.get<bool>("pc")) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT;
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -205,12 +205,13 @@ int main(int argc, char *argv[]) { ...@@ -205,12 +205,13 @@ int main(int argc, char *argv[]) {
waitTime = 10; waitTime = 10;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
// create board object // create board object
aruco::GridBoard board = Ptr<aruco::GridBoard> gridboard =
aruco::GridBoard::create(markersX, markersY, markerLength, markerSeparation, dictionary); aruco::GridBoard::create(markersX, markersY, markerLength, markerSeparation, dictionary);
Ptr<aruco::Board> board = gridboard.staticCast<aruco::Board>();
// collected frames for calibration // collected frames for calibration
vector< vector< vector< Point2f > > > allCorners; vector< vector< vector< Point2f > > > allCorners;
......
...@@ -76,30 +76,30 @@ const char* keys = ...@@ -76,30 +76,30 @@ const char* keys =
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) { ...@@ -175,7 +175,7 @@ int main(int argc, char *argv[]) {
if(parser.get<bool>("zt")) calibrationFlags |= CALIB_ZERO_TANGENT_DIST; if(parser.get<bool>("zt")) calibrationFlags |= CALIB_ZERO_TANGENT_DIST;
if(parser.get<bool>("pc")) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT; if(parser.get<bool>("pc")) calibrationFlags |= CALIB_FIX_PRINCIPAL_POINT;
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -207,12 +207,13 @@ int main(int argc, char *argv[]) { ...@@ -207,12 +207,13 @@ int main(int argc, char *argv[]) {
waitTime = 10; waitTime = 10;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
// create charuco board object // create charuco board object
aruco::CharucoBoard board = Ptr<aruco::CharucoBoard> charucoboard =
aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary); aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary);
Ptr<aruco::Board> board = charucoboard.staticCast<aruco::Board>();
// collect data from each frame // collect data from each frame
vector< vector< vector< Point2f > > > allCorners; vector< vector< vector< Point2f > > > allCorners;
...@@ -236,7 +237,7 @@ int main(int argc, char *argv[]) { ...@@ -236,7 +237,7 @@ int main(int argc, char *argv[]) {
// interpolate charuco corners // interpolate charuco corners
Mat currentCharucoCorners, currentCharucoIds; Mat currentCharucoCorners, currentCharucoIds;
if(ids.size() > 0) if(ids.size() > 0)
aruco::interpolateCornersCharuco(corners, ids, image, board, currentCharucoCorners, aruco::interpolateCornersCharuco(corners, ids, image, charucoboard, currentCharucoCorners,
currentCharucoIds); currentCharucoIds);
// draw results // draw results
...@@ -305,7 +306,7 @@ int main(int argc, char *argv[]) { ...@@ -305,7 +306,7 @@ int main(int argc, char *argv[]) {
for(int i = 0; i < nFrames; i++) { for(int i = 0; i < nFrames; i++) {
// interpolate using camera parameters // interpolate using camera parameters
Mat currentCharucoCorners, currentCharucoIds; Mat currentCharucoCorners, currentCharucoIds;
aruco::interpolateCornersCharuco(allCorners[i], allIds[i], allImgs[i], board, aruco::interpolateCornersCharuco(allCorners[i], allIds[i], allImgs[i], charucoboard,
currentCharucoCorners, currentCharucoIds, cameraMatrix, currentCharucoCorners, currentCharucoIds, cameraMatrix,
distCoeffs); distCoeffs);
...@@ -321,7 +322,7 @@ int main(int argc, char *argv[]) { ...@@ -321,7 +322,7 @@ int main(int argc, char *argv[]) {
// calibrate camera using charuco // calibrate camera using charuco
repError = repError =
aruco::calibrateCameraCharuco(allCharucoCorners, allCharucoIds, board, imgSize, aruco::calibrateCameraCharuco(allCharucoCorners, allCharucoIds, charucoboard, imgSize,
cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags); cameraMatrix, distCoeffs, rvecs, tvecs, calibrationFlags);
bool saveOk = saveCameraParams(outputFile, imgSize, aspectRatio, calibrationFlags, bool saveOk = saveCameraParams(outputFile, imgSize, aspectRatio, calibrationFlags,
......
...@@ -93,15 +93,15 @@ int main(int argc, char *argv[]) { ...@@ -93,15 +93,15 @@ int main(int argc, char *argv[]) {
imageSize.height = imageSize.height =
markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins; markersY * (markerLength + markerSeparation) - markerSeparation + 2 * margins;
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
aruco::GridBoard board = aruco::GridBoard::create(markersX, markersY, float(markerLength), Ptr<aruco::GridBoard> board = aruco::GridBoard::create(markersX, markersY, float(markerLength),
float(markerSeparation), dictionary); float(markerSeparation), dictionary);
// show created board // show created board
Mat boardImage; Mat boardImage;
board.draw(imageSize, boardImage, margins, borderBits); board->draw(imageSize, boardImage, margins, borderBits);
if(showImage) { if(showImage) {
imshow("board", boardImage); imshow("board", boardImage);
......
...@@ -88,19 +88,19 @@ int main(int argc, char *argv[]) { ...@@ -88,19 +88,19 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
Size imageSize; Size imageSize;
imageSize.width = squaresX * squareLength + 2 * margins; imageSize.width = squaresX * squareLength + 2 * margins;
imageSize.height = squaresY * squareLength + 2 * margins; imageSize.height = squaresY * squareLength + 2 * margins;
aruco::CharucoBoard board = aruco::CharucoBoard::create(squaresX, squaresY, (float)squareLength, Ptr<aruco::CharucoBoard> board = aruco::CharucoBoard::create(squaresX, squaresY, (float)squareLength,
(float)markerLength, dictionary); (float)markerLength, dictionary);
// show created board // show created board
Mat boardImage; Mat boardImage;
board.draw(imageSize, boardImage, margins, borderBits); board->draw(imageSize, boardImage, margins, borderBits);
if(showImage) { if(showImage) {
imshow("board", boardImage); imshow("board", boardImage);
......
...@@ -86,7 +86,7 @@ int main(int argc, char *argv[]) { ...@@ -86,7 +86,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
istringstream ss(idsString); istringstream ss(idsString);
......
...@@ -79,7 +79,7 @@ int main(int argc, char *argv[]) { ...@@ -79,7 +79,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
Mat markerImg; Mat markerImg;
......
...@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff ...@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -137,7 +137,7 @@ int main(int argc, char *argv[]) { ...@@ -137,7 +137,7 @@ int main(int argc, char *argv[]) {
} }
} }
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -145,7 +145,7 @@ int main(int argc, char *argv[]) { ...@@ -145,7 +145,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
} }
detectorParams.doCornerRefinement = true; // do corner refinement in markers detectorParams->doCornerRefinement = true; // do corner refinement in markers
String video; String video;
if(parser.has("v")) { if(parser.has("v")) {
...@@ -157,7 +157,7 @@ int main(int argc, char *argv[]) { ...@@ -157,7 +157,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
VideoCapture inputVideo; VideoCapture inputVideo;
...@@ -174,8 +174,9 @@ int main(int argc, char *argv[]) { ...@@ -174,8 +174,9 @@ int main(int argc, char *argv[]) {
markerSeparation); markerSeparation);
// create board object // create board object
aruco::GridBoard board = Ptr<aruco::GridBoard> gridboard =
aruco::GridBoard::create(markersX, markersY, markerLength, markerSeparation, dictionary); aruco::GridBoard::create(markersX, markersY, markerLength, markerSeparation, dictionary);
Ptr<aruco::Board> board = gridboard.staticCast<aruco::Board>();
double totalTime = 0; double totalTime = 0;
int totalIterations = 0; int totalIterations = 0;
......
...@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff ...@@ -79,30 +79,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { ...@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
} }
} }
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) { ...@@ -155,7 +155,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
VideoCapture inputVideo; VideoCapture inputVideo;
...@@ -171,8 +171,9 @@ int main(int argc, char *argv[]) { ...@@ -171,8 +171,9 @@ int main(int argc, char *argv[]) {
float axisLength = 0.5f * ((float)min(squaresX, squaresY) * (squareLength)); float axisLength = 0.5f * ((float)min(squaresX, squaresY) * (squareLength));
// create charuco board object // create charuco board object
aruco::CharucoBoard board = Ptr<aruco::CharucoBoard> charucoboard =
aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary); aruco::CharucoBoard::create(squaresX, squaresY, squareLength, markerLength, dictionary);
Ptr<aruco::Board> board = charucoboard.staticCast<aruco::Board>();
double totalTime = 0; double totalTime = 0;
int totalIterations = 0; int totalIterations = 0;
...@@ -201,13 +202,13 @@ int main(int argc, char *argv[]) { ...@@ -201,13 +202,13 @@ int main(int argc, char *argv[]) {
int interpolatedCorners = 0; int interpolatedCorners = 0;
if(markerIds.size() > 0) if(markerIds.size() > 0)
interpolatedCorners = interpolatedCorners =
aruco::interpolateCornersCharuco(markerCorners, markerIds, image, board, aruco::interpolateCornersCharuco(markerCorners, markerIds, image, charucoboard,
charucoCorners, charucoIds, camMatrix, distCoeffs); charucoCorners, charucoIds, camMatrix, distCoeffs);
// estimate charuco board pose // estimate charuco board pose
bool validPose = false; bool validPose = false;
if(camMatrix.total() != 0) if(camMatrix.total() != 0)
validPose = aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, board, validPose = aruco::estimatePoseCharucoBoard(charucoCorners, charucoIds, charucoboard,
camMatrix, distCoeffs, rvec, tvec); camMatrix, distCoeffs, rvec, tvec);
......
...@@ -80,30 +80,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff ...@@ -80,30 +80,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { ...@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) {
bool autoScale = parser.has("as"); bool autoScale = parser.has("as");
float autoScaleFactor = autoScale ? parser.get<float>("as") : 1.f; float autoScaleFactor = autoScale ? parser.get<float>("as") : 1.f;
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -148,7 +148,7 @@ int main(int argc, char *argv[]) { ...@@ -148,7 +148,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
Mat camMatrix, distCoeffs; Mat camMatrix, distCoeffs;
......
...@@ -74,30 +74,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff ...@@ -74,30 +74,30 @@ static bool readCameraParameters(string filename, Mat &camMatrix, Mat &distCoeff
/** /**
*/ */
static bool readDetectorParameters(string filename, aruco::DetectorParameters &params) { static bool readDetectorParameters(string filename, Ptr<aruco::DetectorParameters> &params) {
FileStorage fs(filename, FileStorage::READ); FileStorage fs(filename, FileStorage::READ);
if(!fs.isOpened()) if(!fs.isOpened())
return false; return false;
fs["adaptiveThreshWinSizeMin"] >> params.adaptiveThreshWinSizeMin; fs["adaptiveThreshWinSizeMin"] >> params->adaptiveThreshWinSizeMin;
fs["adaptiveThreshWinSizeMax"] >> params.adaptiveThreshWinSizeMax; fs["adaptiveThreshWinSizeMax"] >> params->adaptiveThreshWinSizeMax;
fs["adaptiveThreshWinSizeStep"] >> params.adaptiveThreshWinSizeStep; fs["adaptiveThreshWinSizeStep"] >> params->adaptiveThreshWinSizeStep;
fs["adaptiveThreshConstant"] >> params.adaptiveThreshConstant; fs["adaptiveThreshConstant"] >> params->adaptiveThreshConstant;
fs["minMarkerPerimeterRate"] >> params.minMarkerPerimeterRate; fs["minMarkerPerimeterRate"] >> params->minMarkerPerimeterRate;
fs["maxMarkerPerimeterRate"] >> params.maxMarkerPerimeterRate; fs["maxMarkerPerimeterRate"] >> params->maxMarkerPerimeterRate;
fs["polygonalApproxAccuracyRate"] >> params.polygonalApproxAccuracyRate; fs["polygonalApproxAccuracyRate"] >> params->polygonalApproxAccuracyRate;
fs["minCornerDistanceRate"] >> params.minCornerDistanceRate; fs["minCornerDistanceRate"] >> params->minCornerDistanceRate;
fs["minDistanceToBorder"] >> params.minDistanceToBorder; fs["minDistanceToBorder"] >> params->minDistanceToBorder;
fs["minMarkerDistanceRate"] >> params.minMarkerDistanceRate; fs["minMarkerDistanceRate"] >> params->minMarkerDistanceRate;
fs["doCornerRefinement"] >> params.doCornerRefinement; fs["doCornerRefinement"] >> params->doCornerRefinement;
fs["cornerRefinementWinSize"] >> params.cornerRefinementWinSize; fs["cornerRefinementWinSize"] >> params->cornerRefinementWinSize;
fs["cornerRefinementMaxIterations"] >> params.cornerRefinementMaxIterations; fs["cornerRefinementMaxIterations"] >> params->cornerRefinementMaxIterations;
fs["cornerRefinementMinAccuracy"] >> params.cornerRefinementMinAccuracy; fs["cornerRefinementMinAccuracy"] >> params->cornerRefinementMinAccuracy;
fs["markerBorderBits"] >> params.markerBorderBits; fs["markerBorderBits"] >> params->markerBorderBits;
fs["perspectiveRemovePixelPerCell"] >> params.perspectiveRemovePixelPerCell; fs["perspectiveRemovePixelPerCell"] >> params->perspectiveRemovePixelPerCell;
fs["perspectiveRemoveIgnoredMarginPerCell"] >> params.perspectiveRemoveIgnoredMarginPerCell; fs["perspectiveRemoveIgnoredMarginPerCell"] >> params->perspectiveRemoveIgnoredMarginPerCell;
fs["maxErroneousBitsInBorderRate"] >> params.maxErroneousBitsInBorderRate; fs["maxErroneousBitsInBorderRate"] >> params->maxErroneousBitsInBorderRate;
fs["minOtsuStdDev"] >> params.minOtsuStdDev; fs["minOtsuStdDev"] >> params->minOtsuStdDev;
fs["errorCorrectionRate"] >> params.errorCorrectionRate; fs["errorCorrectionRate"] >> params->errorCorrectionRate;
return true; return true;
} }
...@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) { ...@@ -119,7 +119,7 @@ int main(int argc, char *argv[]) {
bool estimatePose = parser.has("c"); bool estimatePose = parser.has("c");
float markerLength = parser.get<float>("l"); float markerLength = parser.get<float>("l");
aruco::DetectorParameters detectorParams; Ptr<aruco::DetectorParameters> detectorParams = aruco::DetectorParameters::create();
if(parser.has("dp")) { if(parser.has("dp")) {
bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams); bool readOk = readDetectorParameters(parser.get<string>("dp"), detectorParams);
if(!readOk) { if(!readOk) {
...@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { ...@@ -127,7 +127,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
} }
detectorParams.doCornerRefinement = true; // do corner refinement in markers detectorParams->doCornerRefinement = true; // do corner refinement in markers
int camId = parser.get<int>("ci"); int camId = parser.get<int>("ci");
...@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { ...@@ -141,7 +141,7 @@ int main(int argc, char *argv[]) {
return 0; return 0;
} }
aruco::Dictionary dictionary = Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId)); aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictionaryId));
Mat camMatrix, distCoeffs; Mat camMatrix, distCoeffs;
......
...@@ -76,6 +76,15 @@ DetectorParameters::DetectorParameters() ...@@ -76,6 +76,15 @@ DetectorParameters::DetectorParameters()
errorCorrectionRate(0.6) {} errorCorrectionRate(0.6) {}
/**
* @brief Create a new set of DetectorParameters with default values.
*/
Ptr<DetectorParameters> DetectorParameters::create() {
Ptr<DetectorParameters> params = makePtr<DetectorParameters>();
return params;
}
/** /**
* @brief Convert input image to gray if it is a 3-channels image * @brief Convert input image to gray if it is a 3-channels image
*/ */
...@@ -267,7 +276,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody { ...@@ -267,7 +276,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
DetectInitialCandidatesParallel(const Mat *_grey, DetectInitialCandidatesParallel(const Mat *_grey,
vector< vector< vector< Point2f > > > *_candidatesArrays, vector< vector< vector< Point2f > > > *_candidatesArrays,
vector< vector< vector< Point > > > *_contoursArrays, vector< vector< vector< Point > > > *_contoursArrays,
DetectorParameters *_params) const Ptr<DetectorParameters> &_params)
: grey(_grey), candidatesArrays(_candidatesArrays), contoursArrays(_contoursArrays), : grey(_grey), candidatesArrays(_candidatesArrays), contoursArrays(_contoursArrays),
params(_params) {} params(_params) {}
...@@ -296,7 +305,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody { ...@@ -296,7 +305,7 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
const Mat *grey; const Mat *grey;
vector< vector< vector< Point2f > > > *candidatesArrays; vector< vector< vector< Point2f > > > *candidatesArrays;
vector< vector< vector< Point > > > *contoursArrays; vector< vector< vector< Point > > > *contoursArrays;
DetectorParameters *params; const Ptr<DetectorParameters> &params;
}; };
...@@ -305,15 +314,15 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody { ...@@ -305,15 +314,15 @@ class DetectInitialCandidatesParallel : public ParallelLoopBody {
*/ */
static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f > > &candidates, static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f > > &candidates,
vector< vector< Point > > &contours, vector< vector< Point > > &contours,
DetectorParameters params) { const Ptr<DetectorParameters> &params) {
CV_Assert(params.adaptiveThreshWinSizeMin >= 3 && params.adaptiveThreshWinSizeMax >= 3); CV_Assert(params->adaptiveThreshWinSizeMin >= 3 && params->adaptiveThreshWinSizeMax >= 3);
CV_Assert(params.adaptiveThreshWinSizeMax >= params.adaptiveThreshWinSizeMin); CV_Assert(params->adaptiveThreshWinSizeMax >= params->adaptiveThreshWinSizeMin);
CV_Assert(params.adaptiveThreshWinSizeStep > 0); CV_Assert(params->adaptiveThreshWinSizeStep > 0);
// number of window sizes (scales) to apply adaptive thresholding // number of window sizes (scales) to apply adaptive thresholding
int nScales = (params.adaptiveThreshWinSizeMax - params.adaptiveThreshWinSizeMin) / int nScales = (params->adaptiveThreshWinSizeMax - params->adaptiveThreshWinSizeMin) /
params.adaptiveThreshWinSizeStep + 1; params->adaptiveThreshWinSizeStep + 1;
vector< vector< vector< Point2f > > > candidatesArrays((size_t) nScales); vector< vector< vector< Point2f > > > candidatesArrays((size_t) nScales);
vector< vector< vector< Point > > > contoursArrays((size_t) nScales); vector< vector< vector< Point > > > contoursArrays((size_t) nScales);
...@@ -333,7 +342,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f > ...@@ -333,7 +342,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
// this is the parallel call for the previous commented loop (result is equivalent) // this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_(Range(0, nScales), DetectInitialCandidatesParallel(&grey, &candidatesArrays, parallel_for_(Range(0, nScales), DetectInitialCandidatesParallel(&grey, &candidatesArrays,
&contoursArrays, &params)); &contoursArrays, params));
// join candidates // join candidates
for(int i = 0; i < nScales; i++) { for(int i = 0; i < nScales; i++) {
...@@ -349,7 +358,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f > ...@@ -349,7 +358,7 @@ static void _detectInitialCandidates(const Mat &grey, vector< vector< Point2f >
* @brief Detect square candidates in the input image * @brief Detect square candidates in the input image
*/ */
static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates, static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates,
OutputArrayOfArrays _contours, DetectorParameters params) { OutputArrayOfArrays _contours, const Ptr<DetectorParameters> &_params) {
Mat image = _image.getMat(); Mat image = _image.getMat();
CV_Assert(image.total() != 0); CV_Assert(image.total() != 0);
...@@ -361,7 +370,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates ...@@ -361,7 +370,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates
vector< vector< Point2f > > candidates; vector< vector< Point2f > > candidates;
vector< vector< Point > > contours; vector< vector< Point > > contours;
/// 2. DETECT FIRST SET OF CANDIDATES /// 2. DETECT FIRST SET OF CANDIDATES
_detectInitialCandidates(grey, candidates, contours, params); _detectInitialCandidates(grey, candidates, contours, _params);
/// 3. SORT CORNERS /// 3. SORT CORNERS
_reorderCandidatesCorners(candidates); _reorderCandidatesCorners(candidates);
...@@ -370,7 +379,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates ...@@ -370,7 +379,7 @@ static void _detectCandidates(InputArray _image, OutputArrayOfArrays _candidates
vector< vector< Point2f > > candidatesOut; vector< vector< Point2f > > candidatesOut;
vector< vector< Point > > contoursOut; vector< vector< Point > > contoursOut;
_filterTooCloseCandidates(candidates, candidatesOut, contours, contoursOut, _filterTooCloseCandidates(candidates, candidatesOut, contours, contoursOut,
params.minMarkerDistanceRate); _params->minMarkerDistanceRate);
// parse output // parse output
_candidates.create((int)candidatesOut.size(), 1, CV_32FC2); _candidates.create((int)candidatesOut.size(), 1, CV_32FC2);
...@@ -489,35 +498,35 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) { ...@@ -489,35 +498,35 @@ static int _getBorderErrors(const Mat &bits, int markerSize, int borderSize) {
/** /**
* @brief Tries to identify one candidate given the dictionary * @brief Tries to identify one candidate given the dictionary
*/ */
static bool _identifyOneCandidate(const Dictionary &dictionary, InputArray _image, static bool _identifyOneCandidate(Ptr<Dictionary> &dictionary, InputArray _image,
InputOutputArray _corners, int &idx, DetectorParameters params) { InputOutputArray _corners, int &idx, const Ptr<DetectorParameters> &params) {
CV_Assert(_corners.total() == 4); CV_Assert(_corners.total() == 4);
CV_Assert(_image.getMat().total() != 0); CV_Assert(_image.getMat().total() != 0);
CV_Assert(params.markerBorderBits > 0); CV_Assert(params->markerBorderBits > 0);
// get bits // get bits
Mat candidateBits = Mat candidateBits =
_extractBits(_image, _corners, dictionary.markerSize, params.markerBorderBits, _extractBits(_image, _corners, dictionary->markerSize, params->markerBorderBits,
params.perspectiveRemovePixelPerCell, params->perspectiveRemovePixelPerCell,
params.perspectiveRemoveIgnoredMarginPerCell, params.minOtsuStdDev); params->perspectiveRemoveIgnoredMarginPerCell, params->minOtsuStdDev);
// analyze border bits // analyze border bits
int maximumErrorsInBorder = int maximumErrorsInBorder =
int(dictionary.markerSize * dictionary.markerSize * params.maxErroneousBitsInBorderRate); int(dictionary->markerSize * dictionary->markerSize * params->maxErroneousBitsInBorderRate);
int borderErrors = int borderErrors =
_getBorderErrors(candidateBits, dictionary.markerSize, params.markerBorderBits); _getBorderErrors(candidateBits, dictionary->markerSize, params->markerBorderBits);
if(borderErrors > maximumErrorsInBorder) return false; // border is wrong if(borderErrors > maximumErrorsInBorder) return false; // border is wrong
// take only inner bits // take only inner bits
Mat onlyBits = Mat onlyBits =
candidateBits.rowRange(params.markerBorderBits, candidateBits.rowRange(params->markerBorderBits,
candidateBits.rows - params.markerBorderBits) candidateBits.rows - params->markerBorderBits)
.colRange(params.markerBorderBits, candidateBits.rows - params.markerBorderBits); .colRange(params->markerBorderBits, candidateBits.rows - params->markerBorderBits);
// try to indentify the marker // try to indentify the marker
int rotation; int rotation;
if(!dictionary.identify(onlyBits, idx, rotation, params.errorCorrectionRate)) if(!dictionary->identify(onlyBits, idx, rotation, params->errorCorrectionRate))
return false; return false;
else { else {
// shift corner positions to the correct rotation // shift corner positions to the correct rotation
...@@ -539,9 +548,9 @@ static bool _identifyOneCandidate(const Dictionary &dictionary, InputArray _imag ...@@ -539,9 +548,9 @@ static bool _identifyOneCandidate(const Dictionary &dictionary, InputArray _imag
class IdentifyCandidatesParallel : public ParallelLoopBody { class IdentifyCandidatesParallel : public ParallelLoopBody {
public: public:
IdentifyCandidatesParallel(const Mat *_grey, InputArrayOfArrays _candidates, IdentifyCandidatesParallel(const Mat *_grey, InputArrayOfArrays _candidates,
InputArrayOfArrays _contours, const Dictionary *_dictionary, InputArrayOfArrays _contours, Ptr<Dictionary> &_dictionary,
vector< int > *_idsTmp, vector< char > *_validCandidates, vector< int > *_idsTmp, vector< char > *_validCandidates,
DetectorParameters *_params) const Ptr<DetectorParameters> &_params)
: grey(_grey), candidates(_candidates), contours(_contours), dictionary(_dictionary), : grey(_grey), candidates(_candidates), contours(_contours), dictionary(_dictionary),
idsTmp(_idsTmp), validCandidates(_validCandidates), params(_params) {} idsTmp(_idsTmp), validCandidates(_validCandidates), params(_params) {}
...@@ -552,7 +561,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody { ...@@ -552,7 +561,7 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
for(int i = begin; i < end; i++) { for(int i = begin; i < end; i++) {
int currId; int currId;
Mat currentCandidate = candidates.getMat(i); Mat currentCandidate = candidates.getMat(i);
if(_identifyOneCandidate(*dictionary, *grey, currentCandidate, currId, *params)) { if(_identifyOneCandidate(dictionary, *grey, currentCandidate, currId, params)) {
(*validCandidates)[i] = 1; (*validCandidates)[i] = 1;
(*idsTmp)[i] = currId; (*idsTmp)[i] = currId;
} }
...@@ -564,21 +573,65 @@ class IdentifyCandidatesParallel : public ParallelLoopBody { ...@@ -564,21 +573,65 @@ class IdentifyCandidatesParallel : public ParallelLoopBody {
const Mat *grey; const Mat *grey;
InputArrayOfArrays candidates, contours; InputArrayOfArrays candidates, contours;
const Dictionary *dictionary; Ptr<Dictionary> &dictionary;
vector< int > *idsTmp; vector< int > *idsTmp;
vector< char > *validCandidates; vector< char > *validCandidates;
DetectorParameters *params; const Ptr<DetectorParameters> &params;
}; };
/**
* @brief Copy the contents of a Mat vector to an OutputArray, settings its size.
*/
void _copyVector2Output(vector< Mat > &vec, OutputArrayOfArrays out);
/**
*
*/
void _copyVector2Output(vector< Mat > &vec, OutputArrayOfArrays out) {
out.release();
out.create((int)vec.size(), 1, CV_32FC2);
if(out.isMatVector()) {
for (unsigned int i = 0; i < vec.size(); i++) {
out.create(4, 1, CV_32FC2, i, true);
Mat &m = out.getMatRef(i);
vec[i].copyTo(m);
}
}
else if(out.isUMatVector()) {
for (unsigned int i = 0; i < vec.size(); i++) {
out.create(4, 1, CV_32FC2, i, true);
UMat &m = out.getUMatRef(i);
vec[i].copyTo(m);
}
}
else if(out.kind() == _OutputArray::STD_VECTOR_VECTOR){
for (unsigned int i = 0; i < vec.size(); i++) {
out.create(4, 1, CV_32FC2, i, true);
Mat m = out.getMat(i);
vec[i].copyTo(m);
}
}
else {
CV_Error(cv::Error::StsNotImplemented,
"Only Mat vector, UMat vector, and vector<vector> OutputArrays are currently supported.");
}
}
/** /**
* @brief Identify square candidates according to a marker dictionary * @brief Identify square candidates according to a marker dictionary
*/ */
static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidates, static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidates,
InputArrayOfArrays _contours, const Dictionary &dictionary, InputArrayOfArrays _contours, Ptr<Dictionary> &_dictionary,
OutputArrayOfArrays _accepted, OutputArray _ids, OutputArrayOfArrays _accepted, OutputArray _ids,
DetectorParameters params, const Ptr<DetectorParameters> &params,
OutputArrayOfArrays _rejected = noArray()) { OutputArrayOfArrays _rejected = noArray()) {
int ncandidates = (int)_candidates.total(); int ncandidates = (int)_candidates.total();
...@@ -607,8 +660,8 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate ...@@ -607,8 +660,8 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate
// this is the parallel call for the previous commented loop (result is equivalent) // this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_(Range(0, ncandidates), parallel_for_(Range(0, ncandidates),
IdentifyCandidatesParallel(&grey, _candidates, _contours, &dictionary, &idsTmp, IdentifyCandidatesParallel(&grey, _candidates, _contours, _dictionary, &idsTmp,
&validCandidates, &params)); &validCandidates, params));
for(int i = 0; i < ncandidates; i++) { for(int i = 0; i < ncandidates; i++) {
if(validCandidates[i] == 1) { if(validCandidates[i] == 1) {
...@@ -620,24 +673,14 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate ...@@ -620,24 +673,14 @@ static void _identifyCandidates(InputArray _image, InputArrayOfArrays _candidate
} }
// parse output // parse output
_accepted.create((int)accepted.size(), 1, CV_32FC2); _copyVector2Output(accepted, _accepted);
for(unsigned int i = 0; i < accepted.size(); i++) {
_accepted.create(4, 1, CV_32FC2, i, true);
Mat m = _accepted.getMat(i);
accepted[i].copyTo(m);
}
_ids.create((int)ids.size(), 1, CV_32SC1); _ids.create((int)ids.size(), 1, CV_32SC1);
for(unsigned int i = 0; i < ids.size(); i++) for(unsigned int i = 0; i < ids.size(); i++)
_ids.getMat().ptr< int >(0)[i] = ids[i]; _ids.getMat().ptr< int >(0)[i] = ids[i];
if(_rejected.needed()) { if(_rejected.needed()) {
_rejected.create((int)rejected.size(), 1, CV_32FC2); _copyVector2Output(rejected, _rejected);
for(unsigned int i = 0; i < rejected.size(); i++) {
_rejected.create(4, 1, CV_32FC2, i, true);
Mat m = _rejected.getMat(i);
rejected[i].copyTo(m);
}
} }
} }
...@@ -744,7 +787,7 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi ...@@ -744,7 +787,7 @@ static void _getSingleMarkerObjectPoints(float markerLength, OutputArray _objPoi
class MarkerSubpixelParallel : public ParallelLoopBody { class MarkerSubpixelParallel : public ParallelLoopBody {
public: public:
MarkerSubpixelParallel(const Mat *_grey, OutputArrayOfArrays _corners, MarkerSubpixelParallel(const Mat *_grey, OutputArrayOfArrays _corners,
DetectorParameters *_params) const Ptr<DetectorParameters> &_params)
: grey(_grey), corners(_corners), params(_params) {} : grey(_grey), corners(_corners), params(_params) {}
void operator()(const Range &range) const { void operator()(const Range &range) const {
...@@ -765,15 +808,15 @@ class MarkerSubpixelParallel : public ParallelLoopBody { ...@@ -765,15 +808,15 @@ class MarkerSubpixelParallel : public ParallelLoopBody {
const Mat *grey; const Mat *grey;
OutputArrayOfArrays corners; OutputArrayOfArrays corners;
DetectorParameters *params; const Ptr<DetectorParameters> &params;
}; };
/** /**
*/ */
void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays _corners, void detectMarkers(InputArray _image, Ptr<Dictionary> &_dictionary, OutputArrayOfArrays _corners,
OutputArray _ids, DetectorParameters params, OutputArray _ids, const Ptr<DetectorParameters> &_params,
OutputArrayOfArrays _rejectedImgPoints) { OutputArrayOfArrays _rejectedImgPoints) {
CV_Assert(_image.getMat().total() != 0); CV_Assert(_image.getMat().total() != 0);
...@@ -784,19 +827,19 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays ...@@ -784,19 +827,19 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays
/// STEP 1: Detect marker candidates /// STEP 1: Detect marker candidates
vector< vector< Point2f > > candidates; vector< vector< Point2f > > candidates;
vector< vector< Point > > contours; vector< vector< Point > > contours;
_detectCandidates(grey, candidates, contours, params); _detectCandidates(grey, candidates, contours, _params);
/// STEP 2: Check candidate codification (identify markers) /// STEP 2: Check candidate codification (identify markers)
_identifyCandidates(grey, candidates, contours, dictionary, _corners, _ids, params, _identifyCandidates(grey, candidates, contours, _dictionary, _corners, _ids, _params,
_rejectedImgPoints); _rejectedImgPoints);
/// STEP 3: Filter detected markers; /// STEP 3: Filter detected markers;
_filterDetectedMarkers(_corners, _ids, _corners, _ids); _filterDetectedMarkers(_corners, _ids, _corners, _ids);
/// STEP 4: Corner refinement /// STEP 4: Corner refinement
if(params.doCornerRefinement) { if(_params->doCornerRefinement) {
CV_Assert(params.cornerRefinementWinSize > 0 && params.cornerRefinementMaxIterations > 0 && CV_Assert(_params->cornerRefinementWinSize > 0 && _params->cornerRefinementMaxIterations > 0 &&
params.cornerRefinementMinAccuracy > 0); _params->cornerRefinementMinAccuracy > 0);
//// do corner refinement for each of the detected markers //// do corner refinement for each of the detected markers
// for (unsigned int i = 0; i < _corners.total(); i++) { // for (unsigned int i = 0; i < _corners.total(); i++) {
...@@ -809,7 +852,7 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays ...@@ -809,7 +852,7 @@ void detectMarkers(InputArray _image, Dictionary dictionary, OutputArrayOfArrays
// this is the parallel call for the previous commented loop (result is equivalent) // this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_(Range(0, (int)_corners.total()), parallel_for_(Range(0, (int)_corners.total()),
MarkerSubpixelParallel(&grey, _corners, &params)); MarkerSubpixelParallel(&grey, _corners, _params));
} }
} }
...@@ -883,11 +926,11 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength, ...@@ -883,11 +926,11 @@ void estimatePoseSingleMarkers(InputArrayOfArrays _corners, float markerLength,
* @brief Given a board configuration and a set of detected markers, returns the corresponding * @brief Given a board configuration and a set of detected markers, returns the corresponding
* image points and object points to call solvePnP * image points and object points to call solvePnP
*/ */
static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detectedIds, static void _getBoardObjectAndImagePoints(Ptr<Board> &_board, InputArray _detectedIds,
InputArrayOfArrays _detectedCorners, InputArrayOfArrays _detectedCorners,
OutputArray _imgPoints, OutputArray _objPoints) { OutputArray _imgPoints, OutputArray _objPoints) {
CV_Assert(board.ids.size() == board.objPoints.size()); CV_Assert(_board->ids.size() == _board->objPoints.size());
CV_Assert(_detectedIds.total() == _detectedCorners.total()); CV_Assert(_detectedIds.total() == _detectedCorners.total());
size_t nDetectedMarkers = _detectedIds.total(); size_t nDetectedMarkers = _detectedIds.total();
...@@ -901,10 +944,10 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect ...@@ -901,10 +944,10 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect
// look for detected markers that belong to the board and get their information // look for detected markers that belong to the board and get their information
for(unsigned int i = 0; i < nDetectedMarkers; i++) { for(unsigned int i = 0; i < nDetectedMarkers; i++) {
int currentId = _detectedIds.getMat().ptr< int >(0)[i]; int currentId = _detectedIds.getMat().ptr< int >(0)[i];
for(unsigned int j = 0; j < board.ids.size(); j++) { for(unsigned int j = 0; j < _board->ids.size(); j++) {
if(currentId == board.ids[j]) { if(currentId == _board->ids[j]) {
for(int p = 0; p < 4; p++) { for(int p = 0; p < 4; p++) {
objPnts.push_back(board.objPoints[j][p]); objPnts.push_back(_board->objPoints[j][p]);
imgPnts.push_back(_detectedCorners.getMat(i).ptr< Point2f >(0)[p]); imgPnts.push_back(_detectedCorners.getMat(i).ptr< Point2f >(0)[p]);
} }
} }
...@@ -926,7 +969,7 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect ...@@ -926,7 +969,7 @@ static void _getBoardObjectAndImagePoints(const Board &board, InputArray _detect
/** /**
* Project board markers that are not included in the list of detected markers * Project board markers that are not included in the list of detected markers
*/ */
static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArrays _detectedCorners, static void _projectUndetectedMarkers(Ptr<Board> &_board, InputOutputArrayOfArrays _detectedCorners,
InputOutputArray _detectedIds, InputArray _cameraMatrix, InputOutputArray _detectedIds, InputArray _cameraMatrix,
InputArray _distCoeffs, InputArray _distCoeffs,
OutputArrayOfArrays _undetectedMarkersProjectedCorners, OutputArrayOfArrays _undetectedMarkersProjectedCorners,
...@@ -935,7 +978,7 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -935,7 +978,7 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// first estimate board pose with the current avaible markers // first estimate board pose with the current avaible markers
Mat rvec, tvec; Mat rvec, tvec;
int boardDetectedMarkers; int boardDetectedMarkers;
boardDetectedMarkers = aruco::estimatePoseBoard(_detectedCorners, _detectedIds, board, boardDetectedMarkers = aruco::estimatePoseBoard(_detectedCorners, _detectedIds, _board,
_cameraMatrix, _distCoeffs, rvec, tvec); _cameraMatrix, _distCoeffs, rvec, tvec);
// at least one marker from board so rvec and tvec are valid // at least one marker from board so rvec and tvec are valid
...@@ -944,10 +987,10 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -944,10 +987,10 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// search undetected markers and project them using the previous pose // search undetected markers and project them using the previous pose
vector< vector< Point2f > > undetectedCorners; vector< vector< Point2f > > undetectedCorners;
vector< int > undetectedIds; vector< int > undetectedIds;
for(unsigned int i = 0; i < board.ids.size(); i++) { for(unsigned int i = 0; i < _board->ids.size(); i++) {
int foundIdx = -1; int foundIdx = -1;
for(unsigned int j = 0; j < _detectedIds.total(); j++) { for(unsigned int j = 0; j < _detectedIds.total(); j++) {
if(board.ids[i] == _detectedIds.getMat().ptr< int >()[j]) { if(_board->ids[i] == _detectedIds.getMat().ptr< int >()[j]) {
foundIdx = j; foundIdx = j;
break; break;
} }
...@@ -956,8 +999,8 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -956,8 +999,8 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// not detected // not detected
if(foundIdx == -1) { if(foundIdx == -1) {
undetectedCorners.push_back(vector< Point2f >()); undetectedCorners.push_back(vector< Point2f >());
undetectedIds.push_back(board.ids[i]); undetectedIds.push_back(_board->ids[i]);
projectPoints(board.objPoints[i], rvec, tvec, _cameraMatrix, _distCoeffs, projectPoints(_board->objPoints[i], rvec, tvec, _cameraMatrix, _distCoeffs,
undetectedCorners.back()); undetectedCorners.back());
} }
} }
...@@ -984,19 +1027,19 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -984,19 +1027,19 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
* Interpolate board markers that are not included in the list of detected markers using * Interpolate board markers that are not included in the list of detected markers using
* global homography * global homography
*/ */
static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArrays _detectedCorners, static void _projectUndetectedMarkers(Ptr<Board> &_board, InputOutputArrayOfArrays _detectedCorners,
InputOutputArray _detectedIds, InputOutputArray _detectedIds,
OutputArrayOfArrays _undetectedMarkersProjectedCorners, OutputArrayOfArrays _undetectedMarkersProjectedCorners,
OutputArray _undetectedMarkersIds) { OutputArray _undetectedMarkersIds) {
// check board points are in the same plane, if not, global homography cannot be applied // check board points are in the same plane, if not, global homography cannot be applied
CV_Assert(board.objPoints.size() > 0); CV_Assert(_board->objPoints.size() > 0);
CV_Assert(board.objPoints[0].size() > 0); CV_Assert(_board->objPoints[0].size() > 0);
float boardZ = board.objPoints[0][0].z; float boardZ = _board->objPoints[0][0].z;
for(unsigned int i = 0; i < board.objPoints.size(); i++) { for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
for(unsigned int j = 0; j < board.objPoints[i].size(); j++) { for(unsigned int j = 0; j < _board->objPoints[i].size(); j++) {
CV_Assert(boardZ == board.objPoints[i][j].z); CV_Assert(boardZ == _board->objPoints[i][j].z);
} }
} }
...@@ -1007,14 +1050,14 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -1007,14 +1050,14 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
// missing markers in different vectors // missing markers in different vectors
vector< int > undetectedMarkersIds; // ids of missing markers vector< int > undetectedMarkersIds; // ids of missing markers
// find markers included in board, and missing markers from board. Fill the previous vectors // find markers included in board, and missing markers from board. Fill the previous vectors
for(unsigned int j = 0; j < board.ids.size(); j++) { for(unsigned int j = 0; j < _board->ids.size(); j++) {
bool found = false; bool found = false;
for(unsigned int i = 0; i < _detectedIds.total(); i++) { for(unsigned int i = 0; i < _detectedIds.total(); i++) {
if(_detectedIds.getMat().ptr< int >()[i] == board.ids[j]) { if(_detectedIds.getMat().ptr< int >()[i] == _board->ids[j]) {
for(int c = 0; c < 4; c++) { for(int c = 0; c < 4; c++) {
imageCornersAll.push_back(_detectedCorners.getMat(i).ptr< Point2f >()[c]); imageCornersAll.push_back(_detectedCorners.getMat(i).ptr< Point2f >()[c]);
detectedMarkersObj2DAll.push_back( detectedMarkersObj2DAll.push_back(
Point2f(board.objPoints[j][c].x, board.objPoints[j][c].y)); Point2f(_board->objPoints[j][c].x, _board->objPoints[j][c].y));
} }
found = true; found = true;
break; break;
...@@ -1024,9 +1067,9 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -1024,9 +1067,9 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
undetectedMarkersObj2D.push_back(vector< Point2f >()); undetectedMarkersObj2D.push_back(vector< Point2f >());
for(int c = 0; c < 4; c++) { for(int c = 0; c < 4; c++) {
undetectedMarkersObj2D.back().push_back( undetectedMarkersObj2D.back().push_back(
Point2f(board.objPoints[j][c].x, board.objPoints[j][c].y)); Point2f(_board->objPoints[j][c].x, _board->objPoints[j][c].y));
} }
undetectedMarkersIds.push_back(board.ids[j]); undetectedMarkersIds.push_back(_board->ids[j]);
} }
} }
if(imageCornersAll.size() == 0) return; if(imageCornersAll.size() == 0) return;
...@@ -1054,28 +1097,30 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra ...@@ -1054,28 +1097,30 @@ static void _projectUndetectedMarkers(const Board &board, InputOutputArrayOfArra
/** /**
*/ */
void refineDetectedMarkers(InputArray _image, const Board &board, void refineDetectedMarkers(InputArray _image, Ptr<Board> &_board,
InputOutputArrayOfArrays _detectedCorners, InputOutputArray _detectedIds, InputOutputArrayOfArrays _detectedCorners, InputOutputArray _detectedIds,
InputOutputArray _rejectedCorners, InputArray _cameraMatrix, InputOutputArray _rejectedCorners, InputArray _cameraMatrix,
InputArray _distCoeffs, float minRepDistance, float errorCorrectionRate, InputArray _distCoeffs, float minRepDistance, float errorCorrectionRate,
bool checkAllOrders, OutputArray _recoveredIdxs, bool checkAllOrders, OutputArray _recoveredIdxs,
DetectorParameters params) { const Ptr<DetectorParameters> &_params) {
CV_Assert(minRepDistance > 0); CV_Assert(minRepDistance > 0);
if(_detectedIds.total() == 0 || _rejectedCorners.total() == 0) return; if(_detectedIds.total() == 0 || _rejectedCorners.total() == 0) return;
DetectorParameters &params = *_params;
// get projections of missing markers in the board // get projections of missing markers in the board
vector< vector< Point2f > > undetectedMarkersCorners; vector< vector< Point2f > > undetectedMarkersCorners;
vector< int > undetectedMarkersIds; vector< int > undetectedMarkersIds;
if(_cameraMatrix.total() != 0) { if(_cameraMatrix.total() != 0) {
// reproject based on camera projection model // reproject based on camera projection model
_projectUndetectedMarkers(board, _detectedCorners, _detectedIds, _cameraMatrix, _distCoeffs, _projectUndetectedMarkers(_board, _detectedCorners, _detectedIds, _cameraMatrix, _distCoeffs,
undetectedMarkersCorners, undetectedMarkersIds); undetectedMarkersCorners, undetectedMarkersIds);
} else { } else {
// reproject based on global homography // reproject based on global homography
_projectUndetectedMarkers(board, _detectedCorners, _detectedIds, undetectedMarkersCorners, _projectUndetectedMarkers(_board, _detectedCorners, _detectedIds, undetectedMarkersCorners,
undetectedMarkersIds); undetectedMarkersIds);
} }
...@@ -1083,8 +1128,9 @@ void refineDetectedMarkers(InputArray _image, const Board &board, ...@@ -1083,8 +1128,9 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
vector< bool > alreadyIdentified(_rejectedCorners.total(), false); vector< bool > alreadyIdentified(_rejectedCorners.total(), false);
// maximum bits that can be corrected // maximum bits that can be corrected
Dictionary &dictionary = *(_board->dictionary);
int maxCorrectionRecalculated = int maxCorrectionRecalculated =
int(double(board.dictionary.maxCorrectionBits) * errorCorrectionRate); int(double(dictionary.maxCorrectionBits) * errorCorrectionRate);
Mat grey; Mat grey;
_convertToGrey(_image, grey); _convertToGrey(_image, grey);
...@@ -1152,7 +1198,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board, ...@@ -1152,7 +1198,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
// extract bits // extract bits
Mat bits = _extractBits( Mat bits = _extractBits(
grey, rotatedMarker, board.dictionary.markerSize, params.markerBorderBits, grey, rotatedMarker, dictionary.markerSize, params.markerBorderBits,
params.perspectiveRemovePixelPerCell, params.perspectiveRemovePixelPerCell,
params.perspectiveRemoveIgnoredMarginPerCell, params.minOtsuStdDev); params.perspectiveRemoveIgnoredMarginPerCell, params.minOtsuStdDev);
...@@ -1161,7 +1207,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board, ...@@ -1161,7 +1207,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
.colRange(params.markerBorderBits, bits.rows - params.markerBorderBits); .colRange(params.markerBorderBits, bits.rows - params.markerBorderBits);
codeDistance = codeDistance =
board.dictionary.getDistanceToId(onlyBits, undetectedMarkersIds[i], false); dictionary.getDistanceToId(onlyBits, undetectedMarkersIds[i], false);
} }
// if everythin is ok, assign values to current best match // if everythin is ok, assign values to current best match
...@@ -1250,7 +1296,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board, ...@@ -1250,7 +1296,7 @@ void refineDetectedMarkers(InputArray _image, const Board &board,
/** /**
*/ */
int estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, const Board &board, int estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, Ptr<Board> &board,
InputArray _cameraMatrix, InputArray _distCoeffs, OutputArray _rvec, InputArray _cameraMatrix, InputArray _distCoeffs, OutputArray _rvec,
OutputArray _tvec) { OutputArray _tvec) {
...@@ -1279,33 +1325,33 @@ int estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, const Board ...@@ -1279,33 +1325,33 @@ int estimatePoseBoard(InputArrayOfArrays _corners, InputArray _ids, const Board
/** /**
*/ */
void GridBoard::draw(Size outSize, OutputArray _img, int marginSize, int borderBits) { void GridBoard::draw(Size outSize, OutputArray _img, int marginSize, int borderBits) {
aruco::drawPlanarBoard((*this), outSize, _img, marginSize, borderBits); _drawPlanarBoardImpl(this, outSize, _img, marginSize, borderBits);
} }
/** /**
*/ */
GridBoard GridBoard::create(int markersX, int markersY, float markerLength, float markerSeparation, Ptr<GridBoard> GridBoard::create(int markersX, int markersY, float markerLength, float markerSeparation,
Dictionary _dictionary) { Ptr<Dictionary> &dictionary) {
GridBoard res;
CV_Assert(markersX > 0 && markersY > 0 && markerLength > 0 && markerSeparation > 0); CV_Assert(markersX > 0 && markersY > 0 && markerLength > 0 && markerSeparation > 0);
res._markersX = markersX; Ptr<GridBoard> res = makePtr<GridBoard>();
res._markersY = markersY;
res._markerLength = markerLength; res->_markersX = markersX;
res._markerSeparation = markerSeparation; res->_markersY = markersY;
res.dictionary = _dictionary; res->_markerLength = markerLength;
res->_markerSeparation = markerSeparation;
res->dictionary = dictionary;
size_t totalMarkers = (size_t) markersX * markersY; size_t totalMarkers = (size_t) markersX * markersY;
res.ids.resize(totalMarkers); res->ids.resize(totalMarkers);
res.objPoints.reserve(totalMarkers); res->objPoints.reserve(totalMarkers);
// fill ids with first identifiers // fill ids with first identifiers
for(unsigned int i = 0; i < totalMarkers; i++) { for(unsigned int i = 0; i < totalMarkers; i++) {
res.ids[i] = i; res->ids[i] = i;
} }
// calculate Board objPoints // calculate Board objPoints
...@@ -1319,7 +1365,7 @@ GridBoard GridBoard::create(int markersX, int markersY, float markerLength, floa ...@@ -1319,7 +1365,7 @@ GridBoard GridBoard::create(int markersX, int markersY, float markerLength, floa
corners[1] = corners[0] + Point3f(markerLength, 0, 0); corners[1] = corners[0] + Point3f(markerLength, 0, 0);
corners[2] = corners[0] + Point3f(markerLength, -markerLength, 0); corners[2] = corners[0] + Point3f(markerLength, -markerLength, 0);
corners[3] = corners[0] + Point3f(0, -markerLength, 0); corners[3] = corners[0] + Point3f(0, -markerLength, 0);
res.objPoints.push_back(corners); res->objPoints.push_back(corners);
} }
} }
...@@ -1403,15 +1449,13 @@ void drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _dis ...@@ -1403,15 +1449,13 @@ void drawAxis(InputOutputArray _image, InputArray _cameraMatrix, InputArray _dis
/** /**
*/ */
void drawMarker(Dictionary dictionary, int id, int sidePixels, OutputArray _img, int borderBits) { void drawMarker(Ptr<Dictionary> &dictionary, int id, int sidePixels, OutputArray _img, int borderBits) {
dictionary.drawMarker(id, sidePixels, _img, borderBits); dictionary->drawMarker(id, sidePixels, _img, borderBits);
} }
/** void _drawPlanarBoardImpl(Board *_board, Size outSize, OutputArray _img, int marginSize,
*/
void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int marginSize,
int borderBits) { int borderBits) {
CV_Assert(outSize.area() > 0); CV_Assert(outSize.area() > 0);
...@@ -1424,17 +1468,17 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar ...@@ -1424,17 +1468,17 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
out.colRange(marginSize, out.cols - marginSize).rowRange(marginSize, out.rows - marginSize); out.colRange(marginSize, out.cols - marginSize).rowRange(marginSize, out.rows - marginSize);
// calculate max and min values in XY plane // calculate max and min values in XY plane
CV_Assert(board.objPoints.size() > 0); CV_Assert(_board->objPoints.size() > 0);
float minX, maxX, minY, maxY; float minX, maxX, minY, maxY;
minX = maxX = board.objPoints[0][0].x; minX = maxX = _board->objPoints[0][0].x;
minY = maxY = board.objPoints[0][0].y; minY = maxY = _board->objPoints[0][0].y;
for(unsigned int i = 0; i < board.objPoints.size(); i++) { for(unsigned int i = 0; i < _board->objPoints.size(); i++) {
for(int j = 0; j < 4; j++) { for(int j = 0; j < 4; j++) {
minX = min(minX, board.objPoints[i][j].x); minX = min(minX, _board->objPoints[i][j].x);
maxX = max(maxX, board.objPoints[i][j].x); maxX = max(maxX, _board->objPoints[i][j].x);
minY = min(minY, board.objPoints[i][j].y); minY = min(minY, _board->objPoints[i][j].y);
maxY = max(maxY, board.objPoints[i][j].y); maxY = max(maxY, _board->objPoints[i][j].y);
} }
} }
...@@ -1459,14 +1503,15 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar ...@@ -1459,14 +1503,15 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
} }
// now paint each marker // now paint each marker
for(unsigned int m = 0; m < board.objPoints.size(); m++) { Dictionary &dictionary = *(_board->dictionary);
for(unsigned int m = 0; m < _board->objPoints.size(); m++) {
// transform corners to markerZone coordinates // transform corners to markerZone coordinates
vector< Point2f > outCorners; vector< Point2f > outCorners;
outCorners.resize(4); outCorners.resize(4);
for(int j = 0; j < 4; j++) { for(int j = 0; j < 4; j++) {
Point2f p0, p1, pf; Point2f p0, p1, pf;
p0 = Point2f(board.objPoints[m][j].x, board.objPoints[m][j].y); p0 = Point2f(_board->objPoints[m][j].x, _board->objPoints[m][j].y);
// remove negativity // remove negativity
p1.x = p0.x - minX; p1.x = p0.x - minX;
p1.y = p0.y - minY; p1.y = p0.y - minY;
...@@ -1476,9 +1521,9 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar ...@@ -1476,9 +1521,9 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
} }
// get tiny marker // get tiny marker
int tinyMarkerSize = 10 * board.dictionary.markerSize + 2; int tinyMarkerSize = 10 * dictionary.markerSize + 2;
Mat tinyMarker; Mat tinyMarker;
board.dictionary.drawMarker(board.ids[m], tinyMarkerSize, tinyMarker, borderBits); dictionary.drawMarker(_board->ids[m], tinyMarkerSize, tinyMarker, borderBits);
// interpolate tiny marker to marker position in markerZone // interpolate tiny marker to marker position in markerZone
Mat inCorners(4, 1, CV_32FC2); Mat inCorners(4, 1, CV_32FC2);
...@@ -1506,10 +1551,19 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar ...@@ -1506,10 +1551,19 @@ void drawPlanarBoard(const Board &board, Size outSize, OutputArray _img, int mar
/**
*/
void drawPlanarBoard(Ptr<Board> &_board, Size outSize, OutputArray _img, int marginSize,
int borderBits) {
_drawPlanarBoardImpl(_board, outSize, _img, marginSize, borderBits);
}
/** /**
*/ */
double calibrateCameraAruco(InputArrayOfArrays _corners, InputArray _ids, InputArray _counter, double calibrateCameraAruco(InputArrayOfArrays _corners, InputArray _ids, InputArray _counter,
const Board &board, Size imageSize, InputOutputArray _cameraMatrix, Ptr<Board> &board, Size imageSize, InputOutputArray _cameraMatrix,
InputOutputArray _distCoeffs, OutputArrayOfArrays _rvecs, InputOutputArray _distCoeffs, OutputArrayOfArrays _rvecs,
OutputArrayOfArrays _tvecs, int flags, TermCriteria criteria) { OutputArrayOfArrays _tvecs, int flags, TermCriteria criteria) {
...@@ -1544,5 +1598,8 @@ double calibrateCameraAruco(InputArrayOfArrays _corners, InputArray _ids, InputA ...@@ -1544,5 +1598,8 @@ double calibrateCameraAruco(InputArrayOfArrays _corners, InputArray _ids, InputA
return calibrateCamera(processedObjectPoints, processedImagePoints, imageSize, _cameraMatrix, return calibrateCamera(processedObjectPoints, processedImagePoints, imageSize, _cameraMatrix,
_distCoeffs, _rvecs, _tvecs, flags, criteria); _distCoeffs, _rvecs, _tvecs, flags, criteria);
} }
} }
} }
...@@ -93,8 +93,8 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord ...@@ -93,8 +93,8 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord
// draw markers // draw markers
Mat markersImg; Mat markersImg;
aruco::drawPlanarBoard((*this), chessboardZoneImg.size(), markersImg, aruco::_drawPlanarBoardImpl(this, chessboardZoneImg.size(), markersImg,
diffSquareMarkerLengthPixels, borderBits); diffSquareMarkerLengthPixels, borderBits);
markersImg.copyTo(chessboardZoneImg); markersImg.copyTo(chessboardZoneImg);
...@@ -120,17 +120,17 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord ...@@ -120,17 +120,17 @@ void CharucoBoard::draw(Size outSize, OutputArray _img, int marginSize, int bord
/** /**
*/ */
CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength, Ptr<CharucoBoard> CharucoBoard::create(int squaresX, int squaresY, float squareLength,
float markerLength, Dictionary dictionary) { float markerLength, Ptr<Dictionary> &dictionary) {
CV_Assert(squaresX > 1 && squaresY > 1 && markerLength > 0 && squareLength > markerLength); CV_Assert(squaresX > 1 && squaresY > 1 && markerLength > 0 && squareLength > markerLength);
CharucoBoard res; Ptr<CharucoBoard> res = makePtr<CharucoBoard>();
res._squaresX = squaresX; res->_squaresX = squaresX;
res._squaresY = squaresY; res->_squaresY = squaresY;
res._squareLength = squareLength; res->_squareLength = squareLength;
res._markerLength = markerLength; res->_markerLength = markerLength;
res.dictionary = dictionary; res->dictionary = dictionary;
float diffSquareMarkerLength = (squareLength - markerLength) / 2; float diffSquareMarkerLength = (squareLength - markerLength) / 2;
...@@ -147,10 +147,10 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength ...@@ -147,10 +147,10 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength
corners[1] = corners[0] + Point3f(markerLength, 0, 0); corners[1] = corners[0] + Point3f(markerLength, 0, 0);
corners[2] = corners[0] + Point3f(markerLength, -markerLength, 0); corners[2] = corners[0] + Point3f(markerLength, -markerLength, 0);
corners[3] = corners[0] + Point3f(0, -markerLength, 0); corners[3] = corners[0] + Point3f(0, -markerLength, 0);
res.objPoints.push_back(corners); res->objPoints.push_back(corners);
// first ids in dictionary // first ids in dictionary
int nextId = (int)res.ids.size(); int nextId = (int)res->ids.size();
res.ids.push_back(nextId); res->ids.push_back(nextId);
} }
} }
...@@ -161,11 +161,11 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength ...@@ -161,11 +161,11 @@ CharucoBoard CharucoBoard::create(int squaresX, int squaresY, float squareLength
corner.x = (x + 1) * squareLength; corner.x = (x + 1) * squareLength;
corner.y = (y + 1) * squareLength; corner.y = (y + 1) * squareLength;
corner.z = 0; corner.z = 0;
res.chessboardCorners.push_back(corner); res->chessboardCorners.push_back(corner);
} }
} }
res._getNearestMarkerCorners(); res->_getNearestMarkerCorners();
return res; return res;
} }
...@@ -230,7 +230,7 @@ void CharucoBoard::_getNearestMarkerCorners() { ...@@ -230,7 +230,7 @@ void CharucoBoard::_getNearestMarkerCorners() {
/** /**
* Remove charuco corners if any of their minMarkers closest markers has not been detected * Remove charuco corners if any of their minMarkers closest markers has not been detected
*/ */
static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board, static unsigned int _filterCornersWithoutMinMarkers(Ptr<CharucoBoard> &_board,
InputArray _allCharucoCorners, InputArray _allCharucoCorners,
InputArray _allCharucoIds, InputArray _allCharucoIds,
InputArray _allArucoIds, int minMarkers, InputArray _allArucoIds, int minMarkers,
...@@ -246,8 +246,8 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board, ...@@ -246,8 +246,8 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board,
int currentCharucoId = _allCharucoIds.getMat().ptr< int >(0)[i]; int currentCharucoId = _allCharucoIds.getMat().ptr< int >(0)[i];
int totalMarkers = 0; // nomber of closest marker detected int totalMarkers = 0; // nomber of closest marker detected
// look for closest markers // look for closest markers
for(unsigned int m = 0; m < board.nearestMarkerIdx[currentCharucoId].size(); m++) { for(unsigned int m = 0; m < _board->nearestMarkerIdx[currentCharucoId].size(); m++) {
int markerId = board.ids[board.nearestMarkerIdx[currentCharucoId][m]]; int markerId = _board->ids[_board->nearestMarkerIdx[currentCharucoId][m]];
bool found = false; bool found = false;
for(unsigned int k = 0; k < _allArucoIds.getMat().total(); k++) { for(unsigned int k = 0; k < _allArucoIds.getMat().total(); k++) {
if(_allArucoIds.getMat().ptr< int >(0)[k] == markerId) { if(_allArucoIds.getMat().ptr< int >(0)[k] == markerId) {
...@@ -286,7 +286,7 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board, ...@@ -286,7 +286,7 @@ static unsigned int _filterCornersWithoutMinMarkers(const CharucoBoard &board,
class CharucoSubpixelParallel : public ParallelLoopBody { class CharucoSubpixelParallel : public ParallelLoopBody {
public: public:
CharucoSubpixelParallel(const Mat *_grey, vector< Point2f > *_filteredChessboardImgPoints, CharucoSubpixelParallel(const Mat *_grey, vector< Point2f > *_filteredChessboardImgPoints,
vector< Size > *_filteredWinSizes, DetectorParameters *_params) vector< Size > *_filteredWinSizes, const Ptr<DetectorParameters> &_params)
: grey(_grey), filteredChessboardImgPoints(_filteredChessboardImgPoints), : grey(_grey), filteredChessboardImgPoints(_filteredChessboardImgPoints),
filteredWinSizes(_filteredWinSizes), params(_params) {} filteredWinSizes(_filteredWinSizes), params(_params) {}
...@@ -316,7 +316,7 @@ class CharucoSubpixelParallel : public ParallelLoopBody { ...@@ -316,7 +316,7 @@ class CharucoSubpixelParallel : public ParallelLoopBody {
const Mat *grey; const Mat *grey;
vector< Point2f > *filteredChessboardImgPoints; vector< Point2f > *filteredChessboardImgPoints;
vector< Size > *filteredWinSizes; vector< Size > *filteredWinSizes;
DetectorParameters *params; const Ptr<DetectorParameters> &params;
}; };
...@@ -358,7 +358,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In ...@@ -358,7 +358,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
else else
_image.getMat().copyTo(grey); _image.getMat().copyTo(grey);
DetectorParameters params; // use default params for corner refinement const Ptr<DetectorParameters> params = DetectorParameters::create(); // use default params for corner refinement
//// For each of the charuco corners, apply subpixel refinement using its correspondind winSize //// For each of the charuco corners, apply subpixel refinement using its correspondind winSize
// for(unsigned int i=0; i<filteredChessboardImgPoints.size(); i++) { // for(unsigned int i=0; i<filteredChessboardImgPoints.size(); i++) {
...@@ -377,7 +377,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In ...@@ -377,7 +377,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
// this is the parallel call for the previous commented loop (result is equivalent) // this is the parallel call for the previous commented loop (result is equivalent)
parallel_for_( parallel_for_(
Range(0, (int)filteredChessboardImgPoints.size()), Range(0, (int)filteredChessboardImgPoints.size()),
CharucoSubpixelParallel(&grey, &filteredChessboardImgPoints, &filteredWinSizes, &params)); CharucoSubpixelParallel(&grey, &filteredChessboardImgPoints, &filteredWinSizes, params));
// parse output // parse output
_selectedCorners.create((int)filteredChessboardImgPoints.size(), 1, CV_32FC2); _selectedCorners.create((int)filteredChessboardImgPoints.size(), 1, CV_32FC2);
...@@ -399,7 +399,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In ...@@ -399,7 +399,7 @@ static unsigned int _selectAndRefineChessboardCorners(InputArray _allCorners, In
* distance to their closest markers * distance to their closest markers
*/ */
static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, InputArray markerIds, static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, InputArray markerIds,
InputArray charucoCorners, const CharucoBoard &board, InputArray charucoCorners, Ptr<CharucoBoard> &board,
vector< Size > &sizes) { vector< Size > &sizes) {
unsigned int nCharucoCorners = (unsigned int)charucoCorners.getMat().total(); unsigned int nCharucoCorners = (unsigned int)charucoCorners.getMat().total();
...@@ -407,15 +407,15 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input ...@@ -407,15 +407,15 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
for(unsigned int i = 0; i < nCharucoCorners; i++) { for(unsigned int i = 0; i < nCharucoCorners; i++) {
if(charucoCorners.getMat().ptr< Point2f >(0)[i] == Point2f(-1, -1)) continue; if(charucoCorners.getMat().ptr< Point2f >(0)[i] == Point2f(-1, -1)) continue;
if(board.nearestMarkerIdx[i].size() == 0) continue; if(board->nearestMarkerIdx[i].size() == 0) continue;
double minDist = -1; double minDist = -1;
int counter = 0; int counter = 0;
// calculate the distance to each of the closest corner of each closest marker // calculate the distance to each of the closest corner of each closest marker
for(unsigned int j = 0; j < board.nearestMarkerIdx[i].size(); j++) { for(unsigned int j = 0; j < board->nearestMarkerIdx[i].size(); j++) {
// find marker // find marker
int markerId = board.ids[board.nearestMarkerIdx[i][j]]; int markerId = board->ids[board->nearestMarkerIdx[i][j]];
int markerIdx = -1; int markerIdx = -1;
for(unsigned int k = 0; k < markerIds.getMat().total(); k++) { for(unsigned int k = 0; k < markerIds.getMat().total(); k++) {
if(markerIds.getMat().ptr< int >(0)[k] == markerId) { if(markerIds.getMat().ptr< int >(0)[k] == markerId) {
...@@ -425,7 +425,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input ...@@ -425,7 +425,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
} }
if(markerIdx == -1) continue; if(markerIdx == -1) continue;
Point2f markerCorner = Point2f markerCorner =
markerCorners.getMat(markerIdx).ptr< Point2f >(0)[board.nearestMarkerCorners[i][j]]; markerCorners.getMat(markerIdx).ptr< Point2f >(0)[board->nearestMarkerCorners[i][j]];
Point2f charucoCorner = charucoCorners.getMat().ptr< Point2f >(0)[i]; Point2f charucoCorner = charucoCorners.getMat().ptr< Point2f >(0)[i];
double dist = norm(markerCorner - charucoCorner); double dist = norm(markerCorner - charucoCorner);
if(minDist == -1) minDist = dist; // if first distance, just assign it if(minDist == -1) minDist = dist; // if first distance, just assign it
...@@ -453,7 +453,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input ...@@ -453,7 +453,7 @@ static void _getMaximumSubPixWindowSizes(InputArrayOfArrays markerCorners, Input
*/ */
static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorners, static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorners,
InputArray _markerIds, InputArray _image, InputArray _markerIds, InputArray _image,
const CharucoBoard &board, Ptr<CharucoBoard> &_board,
InputArray _cameraMatrix, InputArray _distCoeffs, InputArray _cameraMatrix, InputArray _distCoeffs,
OutputArray _charucoCorners, OutputArray _charucoCorners,
OutputArray _charucoIds) { OutputArray _charucoIds) {
...@@ -465,22 +465,24 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne ...@@ -465,22 +465,24 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
// approximated pose estimation using marker corners // approximated pose estimation using marker corners
Mat approximatedRvec, approximatedTvec; Mat approximatedRvec, approximatedTvec;
int detectedBoardMarkers; int detectedBoardMarkers;
Ptr<Board> _b = _board.staticCast<Board>();
detectedBoardMarkers = detectedBoardMarkers =
aruco::estimatePoseBoard(_markerCorners, _markerIds, board, _cameraMatrix, _distCoeffs, aruco::estimatePoseBoard(_markerCorners, _markerIds, _b,
approximatedRvec, approximatedTvec); _cameraMatrix, _distCoeffs, approximatedRvec, approximatedTvec);
if(detectedBoardMarkers == 0) return 0; if(detectedBoardMarkers == 0) return 0;
// project chessboard corners // project chessboard corners
vector< Point2f > allChessboardImgPoints; vector< Point2f > allChessboardImgPoints;
projectPoints(board.chessboardCorners, approximatedRvec, approximatedTvec, _cameraMatrix,
projectPoints(_board->chessboardCorners, approximatedRvec, approximatedTvec, _cameraMatrix,
_distCoeffs, allChessboardImgPoints); _distCoeffs, allChessboardImgPoints);
// calculate maximum window sizes for subpixel refinement. The size is limited by the distance // calculate maximum window sizes for subpixel refinement. The size is limited by the distance
// to the closes marker corner to avoid erroneous displacements to marker corners // to the closes marker corner to avoid erroneous displacements to marker corners
vector< Size > subPixWinSizes; vector< Size > subPixWinSizes;
_getMaximumSubPixWindowSizes(_markerCorners, _markerIds, allChessboardImgPoints, board, _getMaximumSubPixWindowSizes(_markerCorners, _markerIds, allChessboardImgPoints, _board,
subPixWinSizes); subPixWinSizes);
// filter corners outside the image and subpixel-refine charuco corners // filter corners outside the image and subpixel-refine charuco corners
...@@ -489,7 +491,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne ...@@ -489,7 +491,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
allChessboardImgPoints, _image, _charucoCorners, _charucoIds, subPixWinSizes); allChessboardImgPoints, _image, _charucoCorners, _charucoIds, subPixWinSizes);
// to return a charuco corner, its two closes aruco markers should have been detected // to return a charuco corner, its two closes aruco markers should have been detected
nRefinedCorners = _filterCornersWithoutMinMarkers(board, _charucoCorners, _charucoIds, nRefinedCorners = _filterCornersWithoutMinMarkers(_board, _charucoCorners, _charucoIds,
_markerIds, 2, _charucoCorners, _charucoIds); _markerIds, 2, _charucoCorners, _charucoIds);
return nRefinedCorners; return nRefinedCorners;
...@@ -502,7 +504,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne ...@@ -502,7 +504,7 @@ static int _interpolateCornersCharucoApproxCalib(InputArrayOfArrays _markerCorne
*/ */
static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners, static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
InputArray _markerIds, InputArray _image, InputArray _markerIds, InputArray _image,
const CharucoBoard &board, Ptr<CharucoBoard> &_board,
OutputArray _charucoCorners, OutputArray _charucoCorners,
OutputArray _charucoIds) { OutputArray _charucoIds) {
...@@ -518,28 +520,28 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners, ...@@ -518,28 +520,28 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
for(unsigned int i = 0; i < nMarkers; i++) { for(unsigned int i = 0; i < nMarkers; i++) {
vector< Point2f > markerObjPoints2D; vector< Point2f > markerObjPoints2D;
int markerId = _markerIds.getMat().ptr< int >(0)[i]; int markerId = _markerIds.getMat().ptr< int >(0)[i];
vector< int >::const_iterator it = find(board.ids.begin(), board.ids.end(), markerId); vector< int >::const_iterator it = find(_board->ids.begin(), _board->ids.end(), markerId);
if(it == board.ids.end()) continue; if(it == _board->ids.end()) continue;
int boardIdx = (int)std::distance(board.ids.begin(), it); int boardIdx = (int)std::distance<std::vector<int>::const_iterator>(_board->ids.begin(), it);
markerObjPoints2D.resize(4); markerObjPoints2D.resize(4);
for(unsigned int j = 0; j < 4; j++) for(unsigned int j = 0; j < 4; j++)
markerObjPoints2D[j] = markerObjPoints2D[j] =
Point2f(board.objPoints[boardIdx][j].x, board.objPoints[boardIdx][j].y); Point2f(_board->objPoints[boardIdx][j].x, _board->objPoints[boardIdx][j].y);
transformations[i] = getPerspectiveTransform(markerObjPoints2D, _markerCorners.getMat(i)); transformations[i] = getPerspectiveTransform(markerObjPoints2D, _markerCorners.getMat(i));
} }
unsigned int nCharucoCorners = (unsigned int)board.chessboardCorners.size(); unsigned int nCharucoCorners = (unsigned int)_board->chessboardCorners.size();
vector< Point2f > allChessboardImgPoints(nCharucoCorners, Point2f(-1, -1)); vector< Point2f > allChessboardImgPoints(nCharucoCorners, Point2f(-1, -1));
// for each charuco corner, calculate its interpolation position based on the closest markers // for each charuco corner, calculate its interpolation position based on the closest markers
// homographies // homographies
for(unsigned int i = 0; i < nCharucoCorners; i++) { for(unsigned int i = 0; i < nCharucoCorners; i++) {
Point2f objPoint2D = Point2f(board.chessboardCorners[i].x, board.chessboardCorners[i].y); Point2f objPoint2D = Point2f(_board->chessboardCorners[i].x, _board->chessboardCorners[i].y);
vector< Point2f > interpolatedPositions; vector< Point2f > interpolatedPositions;
for(unsigned int j = 0; j < board.nearestMarkerIdx[i].size(); j++) { for(unsigned int j = 0; j < _board->nearestMarkerIdx[i].size(); j++) {
int markerId = board.ids[board.nearestMarkerIdx[i][j]]; int markerId = _board->ids[_board->nearestMarkerIdx[i][j]];
int markerIdx = -1; int markerIdx = -1;
for(unsigned int k = 0; k < _markerIds.getMat().total(); k++) { for(unsigned int k = 0; k < _markerIds.getMat().total(); k++) {
if(_markerIds.getMat().ptr< int >(0)[k] == markerId) { if(_markerIds.getMat().ptr< int >(0)[k] == markerId) {
...@@ -569,7 +571,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners, ...@@ -569,7 +571,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
// calculate maximum window sizes for subpixel refinement. The size is limited by the distance // calculate maximum window sizes for subpixel refinement. The size is limited by the distance
// to the closes marker corner to avoid erroneous displacements to marker corners // to the closes marker corner to avoid erroneous displacements to marker corners
vector< Size > subPixWinSizes; vector< Size > subPixWinSizes;
_getMaximumSubPixWindowSizes(_markerCorners, _markerIds, allChessboardImgPoints, board, _getMaximumSubPixWindowSizes(_markerCorners, _markerIds, allChessboardImgPoints, _board,
subPixWinSizes); subPixWinSizes);
...@@ -579,7 +581,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners, ...@@ -579,7 +581,7 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
allChessboardImgPoints, _image, _charucoCorners, _charucoIds, subPixWinSizes); allChessboardImgPoints, _image, _charucoCorners, _charucoIds, subPixWinSizes);
// to return a charuco corner, its two closes aruco markers should have been detected // to return a charuco corner, its two closes aruco markers should have been detected
nRefinedCorners = _filterCornersWithoutMinMarkers(board, _charucoCorners, _charucoIds, nRefinedCorners = _filterCornersWithoutMinMarkers(_board, _charucoCorners, _charucoIds,
_markerIds, 2, _charucoCorners, _charucoIds); _markerIds, 2, _charucoCorners, _charucoIds);
return nRefinedCorners; return nRefinedCorners;
...@@ -590,19 +592,19 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners, ...@@ -590,19 +592,19 @@ static int _interpolateCornersCharucoLocalHom(InputArrayOfArrays _markerCorners,
/** /**
*/ */
int interpolateCornersCharuco(InputArrayOfArrays _markerCorners, InputArray _markerIds, int interpolateCornersCharuco(InputArrayOfArrays _markerCorners, InputArray _markerIds,
InputArray _image, const CharucoBoard &board, InputArray _image, Ptr<CharucoBoard> &_board,
OutputArray _charucoCorners, OutputArray _charucoIds, OutputArray _charucoCorners, OutputArray _charucoIds,
InputArray _cameraMatrix, InputArray _distCoeffs) { InputArray _cameraMatrix, InputArray _distCoeffs) {
// if camera parameters are avaible, use approximated calibration // if camera parameters are avaible, use approximated calibration
if(_cameraMatrix.total() != 0) { if(_cameraMatrix.total() != 0) {
return _interpolateCornersCharucoApproxCalib(_markerCorners, _markerIds, _image, board, return _interpolateCornersCharucoApproxCalib(_markerCorners, _markerIds, _image, _board,
_cameraMatrix, _distCoeffs, _charucoCorners, _cameraMatrix, _distCoeffs, _charucoCorners,
_charucoIds); _charucoIds);
} }
// else use local homography // else use local homography
else { else {
return _interpolateCornersCharucoLocalHom(_markerCorners, _markerIds, _image, board, return _interpolateCornersCharucoLocalHom(_markerCorners, _markerIds, _image, _board,
_charucoCorners, _charucoIds); _charucoCorners, _charucoIds);
} }
} }
...@@ -679,7 +681,7 @@ static bool _arePointsEnoughForPoseEstimation(const vector< Point3f > &points) { ...@@ -679,7 +681,7 @@ static bool _arePointsEnoughForPoseEstimation(const vector< Point3f > &points) {
/** /**
*/ */
bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds, bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds,
CharucoBoard &board, InputArray _cameraMatrix, InputArray _distCoeffs, Ptr<CharucoBoard> &_board, InputArray _cameraMatrix, InputArray _distCoeffs,
OutputArray _rvec, OutputArray _tvec) { OutputArray _rvec, OutputArray _tvec) {
CV_Assert((_charucoCorners.getMat().total() == _charucoIds.getMat().total())); CV_Assert((_charucoCorners.getMat().total() == _charucoIds.getMat().total()));
...@@ -691,8 +693,8 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds ...@@ -691,8 +693,8 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds
objPoints.reserve(_charucoIds.getMat().total()); objPoints.reserve(_charucoIds.getMat().total());
for(unsigned int i = 0; i < _charucoIds.getMat().total(); i++) { for(unsigned int i = 0; i < _charucoIds.getMat().total(); i++) {
int currId = _charucoIds.getMat().ptr< int >(0)[i]; int currId = _charucoIds.getMat().ptr< int >(0)[i];
CV_Assert(currId >= 0 && currId < (int)board.chessboardCorners.size()); CV_Assert(currId >= 0 && currId < (int)_board->chessboardCorners.size());
objPoints.push_back(board.chessboardCorners[currId]); objPoints.push_back(_board->chessboardCorners[currId]);
} }
// points need to be in different lines, check if detected points are enough // points need to be in different lines, check if detected points are enough
...@@ -709,12 +711,11 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds ...@@ -709,12 +711,11 @@ bool estimatePoseCharucoBoard(InputArray _charucoCorners, InputArray _charucoIds
/** /**
*/ */
double calibrateCameraCharuco(InputArrayOfArrays _charucoCorners, InputArrayOfArrays _charucoIds, double calibrateCameraCharuco(InputArrayOfArrays _charucoCorners, InputArrayOfArrays _charucoIds,
const CharucoBoard &board, Size imageSize, Ptr<CharucoBoard> &_board, Size imageSize,
InputOutputArray _cameraMatrix, InputOutputArray _distCoeffs, InputOutputArray _cameraMatrix, InputOutputArray _distCoeffs,
OutputArrayOfArrays _rvecs, OutputArrayOfArrays _tvecs, int flags, OutputArrayOfArrays _rvecs, OutputArrayOfArrays _tvecs, int flags,
TermCriteria criteria) { TermCriteria criteria) {
CV_Assert(_charucoIds.total() > 0 && (_charucoIds.total() == _charucoCorners.total())); CV_Assert(_charucoIds.total() > 0 && (_charucoIds.total() == _charucoCorners.total()));
// Join object points of charuco corners in a single vector for calibrateCamera() function // Join object points of charuco corners in a single vector for calibrateCamera() function
...@@ -727,8 +728,8 @@ double calibrateCameraCharuco(InputArrayOfArrays _charucoCorners, InputArrayOfAr ...@@ -727,8 +728,8 @@ double calibrateCameraCharuco(InputArrayOfArrays _charucoCorners, InputArrayOfAr
for(unsigned int j = 0; j < nCorners; j++) { for(unsigned int j = 0; j < nCorners; j++) {
int pointId = _charucoIds.getMat(i).ptr< int >(0)[j]; int pointId = _charucoIds.getMat(i).ptr< int >(0)[j];
CV_Assert(pointId >= 0 && pointId < (int)board.chessboardCorners.size()); CV_Assert(pointId >= 0 && pointId < (int)_board->chessboardCorners.size());
allObjPoints[i].push_back(board.chessboardCorners[pointId]); allObjPoints[i].push_back(_board->chessboardCorners[pointId]);
} }
} }
...@@ -750,9 +751,9 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners, ...@@ -750,9 +751,9 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
const float minRepDistanceRate = 0.12f; const float minRepDistanceRate = 0.12f;
// create Charuco board layout for diamond (3x3 layout) // create Charuco board layout for diamond (3x3 layout)
CharucoBoard charucoDiamondLayout; Ptr<Dictionary> dict = getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME(0));
Dictionary dict = getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME(0)); Ptr<CharucoBoard> _charucoDiamondLayout = CharucoBoard::create(3, 3, squareMarkerLengthRate, 1., dict);
charucoDiamondLayout = CharucoBoard::create(3, 3, squareMarkerLengthRate, 1., dict);
vector< vector< Point2f > > diamondCorners; vector< vector< Point2f > > diamondCorners;
vector< Vec4i > diamondIds; vector< Vec4i > diamondIds;
...@@ -808,13 +809,15 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners, ...@@ -808,13 +809,15 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
// modify charuco layout id to make sure all the ids are different than current id // modify charuco layout id to make sure all the ids are different than current id
for(int k = 1; k < 4; k++) for(int k = 1; k < 4; k++)
charucoDiamondLayout.ids[k] = currentId + 1 + k; _charucoDiamondLayout->ids[k] = currentId + 1 + k;
// current id is assigned to [0], so it is the marker on the top // current id is assigned to [0], so it is the marker on the top
charucoDiamondLayout.ids[0] = currentId; _charucoDiamondLayout->ids[0] = currentId;
// try to find the rest of markers in the diamond // try to find the rest of markers in the diamond
vector< int > acceptedIdxs; vector< int > acceptedIdxs;
aruco::refineDetectedMarkers(grey, charucoDiamondLayout, currentMarker, currentMarkerId, Ptr<Board> _b = _charucoDiamondLayout.staticCast<Board>();
aruco::refineDetectedMarkers(grey, _b,
currentMarker, currentMarkerId,
candidates, noArray(), noArray(), minRepDistance, -1, false, candidates, noArray(), noArray(), minRepDistance, -1, false,
acceptedIdxs); acceptedIdxs);
...@@ -836,7 +839,7 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners, ...@@ -836,7 +839,7 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
// interpolate the charuco corners of the diamond // interpolate the charuco corners of the diamond
vector< Point2f > currentMarkerCorners; vector< Point2f > currentMarkerCorners;
Mat aux; Mat aux;
interpolateCornersCharuco(currentMarker, currentMarkerId, grey, charucoDiamondLayout, interpolateCornersCharuco(currentMarker, currentMarkerId, grey, _charucoDiamondLayout,
currentMarkerCorners, aux, _cameraMatrix, _distCoeffs); currentMarkerCorners, aux, _cameraMatrix, _distCoeffs);
// if everything is ok, save the diamond // if everything is ok, save the diamond
...@@ -878,22 +881,22 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners, ...@@ -878,22 +881,22 @@ void detectCharucoDiamond(InputArray _image, InputArrayOfArrays _markerCorners,
/** /**
*/ */
void drawCharucoDiamond(Dictionary dictionary, Vec4i ids, int squareLength, int markerLength, void drawCharucoDiamond(Ptr<Dictionary> &dictionary, Vec4i ids, int squareLength, int markerLength,
OutputArray _img, int marginSize, int borderBits) { OutputArray _img, int marginSize, int borderBits) {
CV_Assert(squareLength > 0 && markerLength > 0 && squareLength > markerLength); CV_Assert(squareLength > 0 && markerLength > 0 && squareLength > markerLength);
CV_Assert(marginSize >= 0 && borderBits > 0); CV_Assert(marginSize >= 0 && borderBits > 0);
// create a charuco board similar to a charuco marker and print it // create a charuco board similar to a charuco marker and print it
CharucoBoard board = Ptr<CharucoBoard> board =
CharucoBoard::create(3, 3, (float)squareLength, (float)markerLength, dictionary); CharucoBoard::create(3, 3, (float)squareLength, (float)markerLength, dictionary);
// assign the charuco marker ids // assign the charuco marker ids
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
board.ids[i] = ids[i]; board->ids[i] = ids[i];
Size outSize(3 * squareLength + 2 * marginSize, 3 * squareLength + 2 * marginSize); Size outSize(3 * squareLength + 2 * marginSize, 3 * squareLength + 2 * marginSize);
board.draw(outSize, _img, marginSize, borderBits); board->draw(outSize, _img, marginSize, borderBits);
} }
......
...@@ -48,6 +48,16 @@ namespace aruco { ...@@ -48,6 +48,16 @@ namespace aruco {
using namespace std; using namespace std;
/**
*/
Dictionary::Dictionary(const Ptr<Dictionary> &_dictionary) {
markerSize = _dictionary->markerSize;
maxCorrectionBits = _dictionary->maxCorrectionBits;
bytesList = _dictionary->bytesList.clone();
}
/** /**
*/ */
Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) { Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) {
...@@ -57,6 +67,28 @@ Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) { ...@@ -57,6 +67,28 @@ Dictionary::Dictionary(const Mat &_bytesList, int _markerSize, int _maxcorr) {
} }
/**
*/
Ptr<Dictionary> Dictionary::create(int nMarkers, int markerSize) {
Ptr<Dictionary> baseDictionary = makePtr<Dictionary>();
return create(nMarkers, markerSize, baseDictionary);
}
/**
*/
Ptr<Dictionary> Dictionary::create(int nMarkers, int markerSize,
Ptr<Dictionary> &baseDictionary) {
return generateCustomDictionary(nMarkers, markerSize, baseDictionary);
}
/**
*/
Ptr<Dictionary> Dictionary::get(int dict) {
return getPredefinedDictionary(dict);
}
/** /**
*/ */
...@@ -259,50 +291,55 @@ const Dictionary DICT_7X7_250_DATA = Dictionary(Mat(250, (7*7 + 7)/8 ,CV_8UC4, ( ...@@ -259,50 +291,55 @@ const Dictionary DICT_7X7_250_DATA = Dictionary(Mat(250, (7*7 + 7)/8 ,CV_8UC4, (
const Dictionary DICT_7X7_1000_DATA = Dictionary(Mat(1000, (7*7 + 7)/8 ,CV_8UC4, (uchar*)DICT_7X7_1000_BYTES), 7, 6); const Dictionary DICT_7X7_1000_DATA = Dictionary(Mat(1000, (7*7 + 7)/8 ,CV_8UC4, (uchar*)DICT_7X7_1000_BYTES), 7, 6);
const Dictionary &getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name) { Ptr<Dictionary> getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME name) {
switch(name) { switch(name) {
case DICT_ARUCO_ORIGINAL: case DICT_ARUCO_ORIGINAL:
return DICT_ARUCO_DATA; return makePtr<Dictionary>(DICT_ARUCO_DATA);
case DICT_4X4_50: case DICT_4X4_50:
return DICT_4X4_50_DATA; return makePtr<Dictionary>(DICT_4X4_50_DATA);
case DICT_4X4_100: case DICT_4X4_100:
return DICT_4X4_100_DATA; return makePtr<Dictionary>(DICT_4X4_100_DATA);
case DICT_4X4_250: case DICT_4X4_250:
return DICT_4X4_250_DATA; return makePtr<Dictionary>(DICT_4X4_250_DATA);
case DICT_4X4_1000: case DICT_4X4_1000:
return DICT_4X4_1000_DATA; return makePtr<Dictionary>(DICT_4X4_1000_DATA);
case DICT_5X5_50: case DICT_5X5_50:
return DICT_5X5_50_DATA; return makePtr<Dictionary>(DICT_5X5_50_DATA);
case DICT_5X5_100: case DICT_5X5_100:
return DICT_5X5_100_DATA; return makePtr<Dictionary>(DICT_5X5_100_DATA);
case DICT_5X5_250: case DICT_5X5_250:
return DICT_5X5_250_DATA; return makePtr<Dictionary>(DICT_5X5_250_DATA);
case DICT_5X5_1000: case DICT_5X5_1000:
return DICT_5X5_1000_DATA; return makePtr<Dictionary>(DICT_5X5_1000_DATA);
case DICT_6X6_50: case DICT_6X6_50:
return DICT_6X6_50_DATA; return makePtr<Dictionary>(DICT_6X6_50_DATA);
case DICT_6X6_100: case DICT_6X6_100:
return DICT_6X6_100_DATA; return makePtr<Dictionary>(DICT_6X6_100_DATA);
case DICT_6X6_250: case DICT_6X6_250:
return DICT_6X6_250_DATA; return makePtr<Dictionary>(DICT_6X6_250_DATA);
case DICT_6X6_1000: case DICT_6X6_1000:
return DICT_6X6_1000_DATA; return makePtr<Dictionary>(DICT_6X6_1000_DATA);
case DICT_7X7_50: case DICT_7X7_50:
return DICT_7X7_50_DATA; return makePtr<Dictionary>(DICT_7X7_50_DATA);
case DICT_7X7_100: case DICT_7X7_100:
return DICT_7X7_100_DATA; return makePtr<Dictionary>(DICT_7X7_100_DATA);
case DICT_7X7_250: case DICT_7X7_250:
return DICT_7X7_250_DATA; return makePtr<Dictionary>(DICT_7X7_250_DATA);
case DICT_7X7_1000: case DICT_7X7_1000:
return DICT_7X7_1000_DATA; return makePtr<Dictionary>(DICT_7X7_1000_DATA);
} }
return DICT_4X4_50_DATA; return makePtr<Dictionary>(DICT_4X4_50_DATA);
}
Ptr<Dictionary> getPredefinedDictionary(int dict) {
return getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME(dict));
} }
...@@ -339,11 +376,11 @@ static int _getSelfDistance(const Mat &marker) { ...@@ -339,11 +376,11 @@ static int _getSelfDistance(const Mat &marker) {
/** /**
*/ */
Dictionary generateCustomDictionary(int nMarkers, int markerSize, Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize,
const Dictionary &baseDictionary) { Ptr<Dictionary> &baseDictionary) {
Dictionary out; Ptr<Dictionary> out = makePtr<Dictionary>();
out.markerSize = markerSize; out->markerSize = markerSize;
// theoretical maximum intermarker distance // theoretical maximum intermarker distance
// See S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014. // See S. Garrido-Jurado, R. Muñoz-Salinas, F. J. Madrid-Cuevas, and M. J. Marín-Jiménez. 2014.
...@@ -353,17 +390,17 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize, ...@@ -353,17 +390,17 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
int tau = 2 * (int)std::floor(float(C) * 4.f / 3.f); int tau = 2 * (int)std::floor(float(C) * 4.f / 3.f);
// if baseDictionary is provided, calculate its intermarker distance // if baseDictionary is provided, calculate its intermarker distance
if(baseDictionary.bytesList.rows > 0) { if(baseDictionary->bytesList.rows > 0) {
CV_Assert(baseDictionary.markerSize == markerSize); CV_Assert(baseDictionary->markerSize == markerSize);
out.bytesList = baseDictionary.bytesList.clone(); out->bytesList = baseDictionary->bytesList.clone();
int minDistance = markerSize * markerSize + 1; int minDistance = markerSize * markerSize + 1;
for(int i = 0; i < out.bytesList.rows; i++) { for(int i = 0; i < out->bytesList.rows; i++) {
Mat markerBytes = out.bytesList.rowRange(i, i + 1); Mat markerBytes = out->bytesList.rowRange(i, i + 1);
Mat markerBits = Dictionary::getBitsFromByteList(markerBytes, markerSize); Mat markerBits = Dictionary::getBitsFromByteList(markerBytes, markerSize);
minDistance = min(minDistance, _getSelfDistance(markerBits)); minDistance = min(minDistance, _getSelfDistance(markerBits));
for(int j = i + 1; j < out.bytesList.rows; j++) { for(int j = i + 1; j < out->bytesList.rows; j++) {
minDistance = min(minDistance, out.getDistanceToId(markerBits, j)); minDistance = min(minDistance, out->getDistanceToId(markerBits, j));
} }
} }
tau = minDistance; tau = minDistance;
...@@ -377,7 +414,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize, ...@@ -377,7 +414,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
const int maxUnproductiveIterations = 5000; const int maxUnproductiveIterations = 5000;
int unproductiveIterations = 0; int unproductiveIterations = 0;
while(out.bytesList.rows < nMarkers) { while(out->bytesList.rows < nMarkers) {
Mat currentMarker = _generateRandomMarker(markerSize); Mat currentMarker = _generateRandomMarker(markerSize);
int selfDistance = _getSelfDistance(currentMarker); int selfDistance = _getSelfDistance(currentMarker);
...@@ -386,8 +423,8 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize, ...@@ -386,8 +423,8 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
// if self distance is better or equal than current best option, calculate distance // if self distance is better or equal than current best option, calculate distance
// to previous accepted markers // to previous accepted markers
if(selfDistance >= bestTau) { if(selfDistance >= bestTau) {
for(int i = 0; i < out.bytesList.rows; i++) { for(int i = 0; i < out->bytesList.rows; i++) {
int currentDistance = out.getDistanceToId(currentMarker, i); int currentDistance = out->getDistanceToId(currentMarker, i);
minDistance = min(currentDistance, minDistance); minDistance = min(currentDistance, minDistance);
if(minDistance <= bestTau) { if(minDistance <= bestTau) {
break; break;
...@@ -400,7 +437,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize, ...@@ -400,7 +437,7 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
unproductiveIterations = 0; unproductiveIterations = 0;
bestTau = 0; bestTau = 0;
Mat bytes = Dictionary::getByteListFromBits(currentMarker); Mat bytes = Dictionary::getByteListFromBits(currentMarker);
out.bytesList.push_back(bytes); out->bytesList.push_back(bytes);
} else { } else {
unproductiveIterations++; unproductiveIterations++;
...@@ -416,15 +453,25 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize, ...@@ -416,15 +453,25 @@ Dictionary generateCustomDictionary(int nMarkers, int markerSize,
tau = bestTau; tau = bestTau;
bestTau = 0; bestTau = 0;
Mat bytes = Dictionary::getByteListFromBits(bestMarker); Mat bytes = Dictionary::getByteListFromBits(bestMarker);
out.bytesList.push_back(bytes); out->bytesList.push_back(bytes);
} }
} }
} }
// update the maximum number of correction bits for the generated dictionary // update the maximum number of correction bits for the generated dictionary
out.maxCorrectionBits = (tau - 1) / 2; out->maxCorrectionBits = (tau - 1) / 2;
return out; return out;
} }
/**
*/
Ptr<Dictionary> generateCustomDictionary(int nMarkers, int markerSize) {
Ptr<Dictionary> baseDictionary = makePtr<Dictionary>();
return generateCustomDictionary(nMarkers, markerSize, baseDictionary);
}
} }
} }
...@@ -62,7 +62,7 @@ CV_ArucoDetectionSimple::CV_ArucoDetectionSimple() {} ...@@ -62,7 +62,7 @@ CV_ArucoDetectionSimple::CV_ArucoDetectionSimple() {}
void CV_ArucoDetectionSimple::run(int) { void CV_ArucoDetectionSimple::run(int) {
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
// 20 images // 20 images
for(int i = 0; i < 20; i++) { for(int i = 0; i < 20; i++) {
...@@ -99,7 +99,7 @@ void CV_ArucoDetectionSimple::run(int) { ...@@ -99,7 +99,7 @@ void CV_ArucoDetectionSimple::run(int) {
// detect markers // detect markers
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
// check detection results // check detection results
...@@ -183,7 +183,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec, ...@@ -183,7 +183,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/** /**
* @brief Create a synthetic image of a marker with perspective * @brief Create a synthetic image of a marker with perspective
*/ */
static Mat projectMarker(aruco::Dictionary dictionary, int id, Mat cameraMatrix, double yaw, static Mat projectMarker(Ptr<aruco::Dictionary> &dictionary, int id, Mat cameraMatrix, double yaw,
double pitch, double distance, Size imageSize, int markerBorder, double pitch, double distance, Size imageSize, int markerBorder,
vector< Point2f > &corners) { vector< Point2f > &corners) {
...@@ -257,7 +257,7 @@ void CV_ArucoDetectionPerspective::run(int) { ...@@ -257,7 +257,7 @@ void CV_ArucoDetectionPerspective::run(int) {
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
cameraMatrix.at< double >(0, 2) = imgSize.width / 2; cameraMatrix.at< double >(0, 2) = imgSize.width / 2;
cameraMatrix.at< double >(1, 2) = imgSize.height / 2; cameraMatrix.at< double >(1, 2) = imgSize.height / 2;
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
// detect from different positions // detect from different positions
for(double distance = 0.1; distance <= 0.5; distance += 0.2) { for(double distance = 0.1; distance <= 0.5; distance += 0.2) {
...@@ -275,9 +275,9 @@ void CV_ArucoDetectionPerspective::run(int) { ...@@ -275,9 +275,9 @@ void CV_ArucoDetectionPerspective::run(int) {
// detect markers // detect markers
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 1; params->minDistanceToBorder = 1;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
// check results // check results
...@@ -320,7 +320,7 @@ CV_ArucoDetectionMarkerSize::CV_ArucoDetectionMarkerSize() {} ...@@ -320,7 +320,7 @@ CV_ArucoDetectionMarkerSize::CV_ArucoDetectionMarkerSize() {}
void CV_ArucoDetectionMarkerSize::run(int) { void CV_ArucoDetectionMarkerSize::run(int) {
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
int markerSide = 20; int markerSide = 20;
int imageSize = 200; int imageSize = 200;
...@@ -337,10 +337,10 @@ void CV_ArucoDetectionMarkerSize::run(int) { ...@@ -337,10 +337,10 @@ void CV_ArucoDetectionMarkerSize::run(int) {
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
// set a invalid minMarkerPerimeterRate // set a invalid minMarkerPerimeterRate
params.minMarkerPerimeterRate = min(4., (4. * markerSide) / float(imageSize) + 0.1); params->minMarkerPerimeterRate = min(4., (4. * markerSide) / float(imageSize) + 0.1);
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(corners.size() != 0) { if(corners.size() != 0) {
ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::minMarkerPerimeterRate"); ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::minMarkerPerimeterRate");
...@@ -349,7 +349,7 @@ void CV_ArucoDetectionMarkerSize::run(int) { ...@@ -349,7 +349,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
} }
// set an valid minMarkerPerimeterRate // set an valid minMarkerPerimeterRate
params.minMarkerPerimeterRate = max(0., (4. * markerSide) / float(imageSize) - 0.1); params->minMarkerPerimeterRate = max(0., (4. * markerSide) / float(imageSize) - 0.1);
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) { if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) {
ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::minMarkerPerimeterRate"); ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::minMarkerPerimeterRate");
...@@ -358,7 +358,7 @@ void CV_ArucoDetectionMarkerSize::run(int) { ...@@ -358,7 +358,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
} }
// set a invalid maxMarkerPerimeterRate // set a invalid maxMarkerPerimeterRate
params.maxMarkerPerimeterRate = min(4., (4. * markerSide) / float(imageSize) - 0.1); params->maxMarkerPerimeterRate = min(4., (4. * markerSide) / float(imageSize) - 0.1);
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(corners.size() != 0) { if(corners.size() != 0) {
ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::maxMarkerPerimeterRate"); ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::maxMarkerPerimeterRate");
...@@ -367,7 +367,7 @@ void CV_ArucoDetectionMarkerSize::run(int) { ...@@ -367,7 +367,7 @@ void CV_ArucoDetectionMarkerSize::run(int) {
} }
// set an valid maxMarkerPerimeterRate // set an valid maxMarkerPerimeterRate
params.maxMarkerPerimeterRate = max(0., (4. * markerSide) / float(imageSize) + 0.1); params->maxMarkerPerimeterRate = max(0., (4. * markerSide) / float(imageSize) + 0.1);
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) { if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) {
ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::maxMarkerPerimeterRate"); ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::maxMarkerPerimeterRate");
...@@ -395,11 +395,12 @@ CV_ArucoBitCorrection::CV_ArucoBitCorrection() {} ...@@ -395,11 +395,12 @@ CV_ArucoBitCorrection::CV_ArucoBitCorrection() {}
void CV_ArucoBitCorrection::run(int) { void CV_ArucoBitCorrection::run(int) {
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> _dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::Dictionary dictionary2 = dictionary; aruco::Dictionary &dictionary = *_dictionary;
aruco::Dictionary dictionary2 = *_dictionary;
int markerSide = 50; int markerSide = 50;
int imageSize = 150; int imageSize = 150;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
// 10 markers // 10 markers
for(int l = 0; l < 10; l++) { for(int l = 0; l < 10; l++) {
...@@ -411,9 +412,9 @@ void CV_ArucoBitCorrection::run(int) { ...@@ -411,9 +412,9 @@ void CV_ArucoBitCorrection::run(int) {
// 5 valid cases // 5 valid cases
for(int i = 0; i < 5; i++) { for(int i = 0; i < 5; i++) {
// how many bit errors (the error is low enough so it can be corrected) // how many bit errors (the error is low enough so it can be corrected)
params.errorCorrectionRate = 0.2 + i * 0.1; params->errorCorrectionRate = 0.2 + i * 0.1;
int errors = int errors =
(int)std::floor(dictionary.maxCorrectionBits * params.errorCorrectionRate - 1.); (int)std::floor(dictionary.maxCorrectionBits * params->errorCorrectionRate - 1.);
// create erroneous marker in currentCodeBits // create erroneous marker in currentCodeBits
Mat currentCodeBits = Mat currentCodeBits =
...@@ -427,14 +428,14 @@ void CV_ArucoBitCorrection::run(int) { ...@@ -427,14 +428,14 @@ void CV_ArucoBitCorrection::run(int) {
Mat currentCodeBytesError = aruco::Dictionary::getByteListFromBits(currentCodeBits); Mat currentCodeBytesError = aruco::Dictionary::getByteListFromBits(currentCodeBits);
currentCodeBytesError.copyTo(dictionary2.bytesList.rowRange(id, id + 1)); currentCodeBytesError.copyTo(dictionary2.bytesList.rowRange(id, id + 1));
Mat img = Mat(imageSize, imageSize, CV_8UC1, Scalar::all(255)); Mat img = Mat(imageSize, imageSize, CV_8UC1, Scalar::all(255));
aruco::drawMarker(dictionary2, id, markerSide, marker); dictionary2.drawMarker(id, markerSide, marker);
Mat aux = img.colRange(30, 30 + markerSide).rowRange(50, 50 + markerSide); Mat aux = img.colRange(30, 30 + markerSide).rowRange(50, 50 + markerSide);
marker.copyTo(aux); marker.copyTo(aux);
// try to detect using original dictionary // try to detect using original dictionary
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, _dictionary, corners, ids, params);
if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) { if(corners.size() != 1 || (corners.size() == 1 && ids[0] != id)) {
ts->printf(cvtest::TS::LOG, "Error in bit correction"); ts->printf(cvtest::TS::LOG, "Error in bit correction");
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
...@@ -445,9 +446,9 @@ void CV_ArucoBitCorrection::run(int) { ...@@ -445,9 +446,9 @@ void CV_ArucoBitCorrection::run(int) {
// 5 invalid cases // 5 invalid cases
for(int i = 0; i < 5; i++) { for(int i = 0; i < 5; i++) {
// how many bit errors (the error is too high to be corrected) // how many bit errors (the error is too high to be corrected)
params.errorCorrectionRate = 0.2 + i * 0.1; params->errorCorrectionRate = 0.2 + i * 0.1;
int errors = int errors =
(int)std::floor(dictionary.maxCorrectionBits * params.errorCorrectionRate + 1.); (int)std::floor(dictionary.maxCorrectionBits * params->errorCorrectionRate + 1.);
// create erroneous marker in currentCodeBits // create erroneous marker in currentCodeBits
Mat currentCodeBits = Mat currentCodeBits =
...@@ -458,21 +459,23 @@ void CV_ArucoBitCorrection::run(int) { ...@@ -458,21 +459,23 @@ void CV_ArucoBitCorrection::run(int) {
} }
// dictionary3 is only composed by the modified marker (in its original form) // dictionary3 is only composed by the modified marker (in its original form)
aruco::Dictionary dictionary3 = dictionary; Ptr<aruco::Dictionary> _dictionary3 = makePtr<aruco::Dictionary>(
dictionary3.bytesList = dictionary2.bytesList.rowRange(id, id + 1).clone(); dictionary2.bytesList.rowRange(id, id + 1).clone(),
dictionary.markerSize,
dictionary.maxCorrectionBits);
// add erroneous marker to dictionary2 in order to create the erroneous marker image // add erroneous marker to dictionary2 in order to create the erroneous marker image
Mat currentCodeBytesError = aruco::Dictionary::getByteListFromBits(currentCodeBits); Mat currentCodeBytesError = aruco::Dictionary::getByteListFromBits(currentCodeBits);
currentCodeBytesError.copyTo(dictionary2.bytesList.rowRange(id, id + 1)); currentCodeBytesError.copyTo(dictionary2.bytesList.rowRange(id, id + 1));
Mat img = Mat(imageSize, imageSize, CV_8UC1, Scalar::all(255)); Mat img = Mat(imageSize, imageSize, CV_8UC1, Scalar::all(255));
aruco::drawMarker(dictionary2, id, markerSide, marker); dictionary2.drawMarker(id, markerSide, marker);
Mat aux = img.colRange(30, 30 + markerSide).rowRange(50, 50 + markerSide); Mat aux = img.colRange(30, 30 + markerSide).rowRange(50, 50 + markerSide);
marker.copyTo(aux); marker.copyTo(aux);
// try to detect using dictionary3, it should fail // try to detect using dictionary3, it should fail
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::detectMarkers(img, dictionary3, corners, ids, params); aruco::detectMarkers(img, _dictionary3, corners, ids, params);
if(corners.size() != 0) { if(corners.size() != 0) {
ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::errorCorrectionRate"); ts->printf(cvtest::TS::LOG, "Error in DetectorParameters::errorCorrectionRate");
ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY); ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
......
...@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec, ...@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/** /**
* @brief Project a synthetic marker * @brief Project a synthetic marker
*/ */
static void projectMarker(Mat &img, aruco::Dictionary dictionary, int id, static void projectMarker(Mat &img, Ptr<aruco::Dictionary> &dictionary, int id,
vector< Point3f > markerObjPoints, Mat cameraMatrix, Mat rvec, Mat tvec, vector< Point3f > markerObjPoints, Mat cameraMatrix, Mat rvec, Mat tvec,
int markerBorder) { int markerBorder) {
...@@ -140,15 +140,15 @@ static void projectMarker(Mat &img, aruco::Dictionary dictionary, int id, ...@@ -140,15 +140,15 @@ static void projectMarker(Mat &img, aruco::Dictionary dictionary, int id,
/** /**
* @brief Get a synthetic image of GridBoard in perspective * @brief Get a synthetic image of GridBoard in perspective
*/ */
static Mat projectBoard(aruco::GridBoard board, Mat cameraMatrix, double yaw, double pitch, static Mat projectBoard(Ptr<aruco::GridBoard> &board, Mat cameraMatrix, double yaw, double pitch,
double distance, Size imageSize, int markerBorder) { double distance, Size imageSize, int markerBorder) {
Mat rvec, tvec; Mat rvec, tvec;
getSyntheticRT(yaw, pitch, distance, rvec, tvec); getSyntheticRT(yaw, pitch, distance, rvec, tvec);
Mat img = Mat(imageSize, CV_8UC1, Scalar::all(255)); Mat img = Mat(imageSize, CV_8UC1, Scalar::all(255));
for(unsigned int m = 0; m < board.ids.size(); m++) { for(unsigned int m = 0; m < board->ids.size(); m++) {
projectMarker(img, board.dictionary, board.ids[m], board.objPoints[m], cameraMatrix, rvec, projectMarker(img, board->dictionary, board->ids[m], board->objPoints[m], cameraMatrix, rvec,
tvec, markerBorder); tvec, markerBorder);
} }
...@@ -177,8 +177,9 @@ void CV_ArucoBoardPose::run(int) { ...@@ -177,8 +177,9 @@ void CV_ArucoBoardPose::run(int) {
int iter = 0; int iter = 0;
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1);
Size imgSize(500, 500); Size imgSize(500, 500);
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::GridBoard board = aruco::GridBoard::create(3, 3, 0.02f, 0.005f, dictionary); Ptr<aruco::GridBoard> gridboard = aruco::GridBoard::create(3, 3, 0.02f, 0.005f, dictionary);
Ptr<aruco::Board> board = gridboard.staticCast<aruco::Board>();
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
cameraMatrix.at< double >(0, 2) = imgSize.width / 2; cameraMatrix.at< double >(0, 2) = imgSize.width / 2;
cameraMatrix.at< double >(1, 2) = imgSize.height / 2; cameraMatrix.at< double >(1, 2) = imgSize.height / 2;
...@@ -188,21 +189,21 @@ void CV_ArucoBoardPose::run(int) { ...@@ -188,21 +189,21 @@ void CV_ArucoBoardPose::run(int) {
for(double distance = 0.2; distance <= 0.4; distance += 0.2) { for(double distance = 0.2; distance <= 0.4; distance += 0.2) {
for(int yaw = 0; yaw < 360; yaw += 100) { for(int yaw = 0; yaw < 360; yaw += 100) {
for(int pitch = 30; pitch <= 90; pitch += 50) { for(int pitch = 30; pitch <= 90; pitch += 50) {
for(unsigned int i = 0; i < board.ids.size(); i++) for(unsigned int i = 0; i < gridboard->ids.size(); i++)
board.ids[i] = (iter + int(i)) % 250; gridboard->ids[i] = (iter + int(i)) % 250;
int markerBorder = iter % 2 + 1; int markerBorder = iter % 2 + 1;
iter++; iter++;
// create synthetic image // create synthetic image
Mat img = projectBoard(board, cameraMatrix, deg2rad(pitch), deg2rad(yaw), distance, Mat img = projectBoard(gridboard, cameraMatrix, deg2rad(pitch), deg2rad(yaw), distance,
imgSize, markerBorder); imgSize, markerBorder);
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 3; params->minDistanceToBorder = 3;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(ids.size() == 0) { if(ids.size() == 0) {
...@@ -218,8 +219,8 @@ void CV_ArucoBoardPose::run(int) { ...@@ -218,8 +219,8 @@ void CV_ArucoBoardPose::run(int) {
// check result // check result
for(unsigned int i = 0; i < ids.size(); i++) { for(unsigned int i = 0; i < ids.size(); i++) {
int foundIdx = -1; int foundIdx = -1;
for(unsigned int j = 0; j < board.ids.size(); j++) { for(unsigned int j = 0; j < gridboard->ids.size(); j++) {
if(board.ids[j] == ids[i]) { if(gridboard->ids[j] == ids[i]) {
foundIdx = int(j); foundIdx = int(j);
break; break;
} }
...@@ -232,7 +233,7 @@ void CV_ArucoBoardPose::run(int) { ...@@ -232,7 +233,7 @@ void CV_ArucoBoardPose::run(int) {
} }
vector< Point2f > projectedCorners; vector< Point2f > projectedCorners;
projectPoints(board.objPoints[foundIdx], rvec, tvec, cameraMatrix, distCoeffs, projectPoints(gridboard->objPoints[foundIdx], rvec, tvec, cameraMatrix, distCoeffs,
projectedCorners); projectedCorners);
for(int c = 0; c < 4; c++) { for(int c = 0; c < 4; c++) {
...@@ -271,8 +272,9 @@ void CV_ArucoRefine::run(int) { ...@@ -271,8 +272,9 @@ void CV_ArucoRefine::run(int) {
int iter = 0; int iter = 0;
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1);
Size imgSize(500, 500); Size imgSize(500, 500);
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::GridBoard board = aruco::GridBoard::create(3, 3, 0.02f, 0.005f, dictionary); Ptr<aruco::GridBoard> gridboard = aruco::GridBoard::create(3, 3, 0.02f, 0.005f, dictionary);
Ptr<aruco::Board> board = gridboard.staticCast<aruco::Board>();
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
cameraMatrix.at< double >(0, 2) = imgSize.width / 2; cameraMatrix.at< double >(0, 2) = imgSize.width / 2;
cameraMatrix.at< double >(1, 2) = imgSize.height / 2; cameraMatrix.at< double >(1, 2) = imgSize.height / 2;
...@@ -282,23 +284,23 @@ void CV_ArucoRefine::run(int) { ...@@ -282,23 +284,23 @@ void CV_ArucoRefine::run(int) {
for(double distance = 0.2; distance <= 0.4; distance += 0.2) { for(double distance = 0.2; distance <= 0.4; distance += 0.2) {
for(int yaw = 0; yaw < 360; yaw += 100) { for(int yaw = 0; yaw < 360; yaw += 100) {
for(int pitch = 30; pitch <= 90; pitch += 50) { for(int pitch = 30; pitch <= 90; pitch += 50) {
for(unsigned int i = 0; i < board.ids.size(); i++) for(unsigned int i = 0; i < gridboard->ids.size(); i++)
board.ids[i] = (iter + int(i)) % 250; gridboard->ids[i] = (iter + int(i)) % 250;
int markerBorder = iter % 2 + 1; int markerBorder = iter % 2 + 1;
iter++; iter++;
// create synthetic image // create synthetic image
Mat img = projectBoard(board, cameraMatrix, deg2rad(pitch), deg2rad(yaw), distance, Mat img = projectBoard(gridboard, cameraMatrix, deg2rad(pitch), deg2rad(yaw), distance,
imgSize, markerBorder); imgSize, markerBorder);
// detect markers // detect markers
vector< vector< Point2f > > corners, rejected; vector< vector< Point2f > > corners, rejected;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 3; params->minDistanceToBorder = 3;
params.doCornerRefinement = true; params->doCornerRefinement = true;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params, rejected); aruco::detectMarkers(img, dictionary, corners, ids, params, rejected);
// remove a marker from detection // remove a marker from detection
......
...@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec, ...@@ -98,7 +98,7 @@ static void getSyntheticRT(double yaw, double pitch, double distance, Mat &rvec,
/** /**
* @brief Project a synthetic marker * @brief Project a synthetic marker
*/ */
static void projectMarker(Mat &img, aruco::Dictionary dictionary, int id, static void projectMarker(Mat &img, Ptr<aruco::Dictionary> dictionary, int id,
vector< Point3f > markerObjPoints, Mat cameraMatrix, Mat rvec, Mat tvec, vector< Point3f > markerObjPoints, Mat cameraMatrix, Mat rvec, Mat tvec,
int markerBorder) { int markerBorder) {
...@@ -176,7 +176,7 @@ static Mat projectChessboard(int squaresX, int squaresY, float squareSize, Size ...@@ -176,7 +176,7 @@ static Mat projectChessboard(int squaresX, int squaresY, float squareSize, Size
/** /**
* @brief Check pose estimation of charuco board * @brief Check pose estimation of charuco board
*/ */
static Mat projectCharucoBoard(aruco::CharucoBoard board, Mat cameraMatrix, double yaw, static Mat projectCharucoBoard(Ptr<aruco::CharucoBoard> &board, Mat cameraMatrix, double yaw,
double pitch, double distance, Size imageSize, int markerBorder, double pitch, double distance, Size imageSize, int markerBorder,
Mat &rvec, Mat &tvec) { Mat &rvec, Mat &tvec) {
...@@ -184,15 +184,15 @@ static Mat projectCharucoBoard(aruco::CharucoBoard board, Mat cameraMatrix, doub ...@@ -184,15 +184,15 @@ static Mat projectCharucoBoard(aruco::CharucoBoard board, Mat cameraMatrix, doub
// project markers // project markers
Mat img = Mat(imageSize, CV_8UC1, Scalar::all(255)); Mat img = Mat(imageSize, CV_8UC1, Scalar::all(255));
for(unsigned int m = 0; m < board.ids.size(); m++) { for(unsigned int m = 0; m < board->ids.size(); m++) {
projectMarker(img, board.dictionary, board.ids[m], board.objPoints[m], cameraMatrix, rvec, projectMarker(img, board->dictionary, board->ids[m], board->objPoints[m], cameraMatrix, rvec,
tvec, markerBorder); tvec, markerBorder);
} }
// project chessboard // project chessboard
Mat chessboard = Mat chessboard =
projectChessboard(board.getChessboardSize().width, board.getChessboardSize().height, projectChessboard(board->getChessboardSize().width, board->getChessboardSize().height,
board.getSquareLength(), imageSize, cameraMatrix, rvec, tvec); board->getSquareLength(), imageSize, cameraMatrix, rvec, tvec);
for(unsigned int i = 0; i < chessboard.total(); i++) { for(unsigned int i = 0; i < chessboard.total(); i++) {
if(chessboard.ptr< unsigned char >()[i] == 0) { if(chessboard.ptr< unsigned char >()[i] == 0) {
...@@ -226,8 +226,8 @@ void CV_CharucoDetection::run(int) { ...@@ -226,8 +226,8 @@ void CV_CharucoDetection::run(int) {
int iter = 0; int iter = 0;
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1);
Size imgSize(500, 500); Size imgSize(500, 500);
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::CharucoBoard board = aruco::CharucoBoard::create(4, 4, 0.03f, 0.015f, dictionary); Ptr<aruco::CharucoBoard> board = aruco::CharucoBoard::create(4, 4, 0.03f, 0.015f, dictionary);
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
cameraMatrix.at< double >(0, 2) = imgSize.width / 2; cameraMatrix.at< double >(0, 2) = imgSize.width / 2;
...@@ -251,9 +251,9 @@ void CV_CharucoDetection::run(int) { ...@@ -251,9 +251,9 @@ void CV_CharucoDetection::run(int) {
// detect markers // detect markers
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 3; params->minDistanceToBorder = 3;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(ids.size() == 0) { if(ids.size() == 0) {
...@@ -276,14 +276,14 @@ void CV_CharucoDetection::run(int) { ...@@ -276,14 +276,14 @@ void CV_CharucoDetection::run(int) {
// check results // check results
vector< Point2f > projectedCharucoCorners; vector< Point2f > projectedCharucoCorners;
projectPoints(board.chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs, projectPoints(board->chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs,
projectedCharucoCorners); projectedCharucoCorners);
for(unsigned int i = 0; i < charucoIds.size(); i++) { for(unsigned int i = 0; i < charucoIds.size(); i++) {
int currentId = charucoIds[i]; int currentId = charucoIds[i];
if(currentId >= (int)board.chessboardCorners.size()) { if(currentId >= (int)board->chessboardCorners.size()) {
ts->printf(cvtest::TS::LOG, "Invalid Charuco corner id"); ts->printf(cvtest::TS::LOG, "Invalid Charuco corner id");
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return; return;
...@@ -325,8 +325,8 @@ void CV_CharucoPoseEstimation::run(int) { ...@@ -325,8 +325,8 @@ void CV_CharucoPoseEstimation::run(int) {
int iter = 0; int iter = 0;
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1);
Size imgSize(500, 500); Size imgSize(500, 500);
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
aruco::CharucoBoard board = aruco::CharucoBoard::create(4, 4, 0.03f, 0.015f, dictionary); Ptr<aruco::CharucoBoard> board = aruco::CharucoBoard::create(4, 4, 0.03f, 0.015f, dictionary);
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
cameraMatrix.at< double >(0, 2) = imgSize.width / 2; cameraMatrix.at< double >(0, 2) = imgSize.width / 2;
...@@ -349,9 +349,9 @@ void CV_CharucoPoseEstimation::run(int) { ...@@ -349,9 +349,9 @@ void CV_CharucoPoseEstimation::run(int) {
// detect markers // detect markers
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 3; params->minDistanceToBorder = 3;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(ids.size() == 0) { if(ids.size() == 0) {
...@@ -381,14 +381,14 @@ void CV_CharucoPoseEstimation::run(int) { ...@@ -381,14 +381,14 @@ void CV_CharucoPoseEstimation::run(int) {
// check result // check result
vector< Point2f > projectedCharucoCorners; vector< Point2f > projectedCharucoCorners;
projectPoints(board.chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs, projectPoints(board->chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs,
projectedCharucoCorners); projectedCharucoCorners);
for(unsigned int i = 0; i < charucoIds.size(); i++) { for(unsigned int i = 0; i < charucoIds.size(); i++) {
int currentId = charucoIds[i]; int currentId = charucoIds[i];
if(currentId >= (int)board.chessboardCorners.size()) { if(currentId >= (int)board->chessboardCorners.size()) {
ts->printf(cvtest::TS::LOG, "Invalid Charuco corner id"); ts->printf(cvtest::TS::LOG, "Invalid Charuco corner id");
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return; return;
...@@ -429,10 +429,10 @@ void CV_CharucoDiamondDetection::run(int) { ...@@ -429,10 +429,10 @@ void CV_CharucoDiamondDetection::run(int) {
int iter = 0; int iter = 0;
Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1); Mat cameraMatrix = Mat::eye(3, 3, CV_64FC1);
Size imgSize(500, 500); Size imgSize(500, 500);
aruco::Dictionary dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250); Ptr<aruco::Dictionary> dictionary = aruco::getPredefinedDictionary(aruco::DICT_6X6_250);
float squareLength = 0.03f; float squareLength = 0.03f;
float markerLength = 0.015f; float markerLength = 0.015f;
aruco::CharucoBoard board = Ptr<aruco::CharucoBoard> board =
aruco::CharucoBoard::create(3, 3, squareLength, markerLength, dictionary); aruco::CharucoBoard::create(3, 3, squareLength, markerLength, dictionary);
cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650; cameraMatrix.at< double >(0, 0) = cameraMatrix.at< double >(1, 1) = 650;
...@@ -447,7 +447,7 @@ void CV_CharucoDiamondDetection::run(int) { ...@@ -447,7 +447,7 @@ void CV_CharucoDiamondDetection::run(int) {
int markerBorder = iter % 2 + 1; int markerBorder = iter % 2 + 1;
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
board.ids[i] = 4 * iter + i; board->ids[i] = 4 * iter + i;
iter++; iter++;
// get synthetic image // get synthetic image
...@@ -458,9 +458,9 @@ void CV_CharucoDiamondDetection::run(int) { ...@@ -458,9 +458,9 @@ void CV_CharucoDiamondDetection::run(int) {
// detect markers // detect markers
vector< vector< Point2f > > corners; vector< vector< Point2f > > corners;
vector< int > ids; vector< int > ids;
aruco::DetectorParameters params; Ptr<aruco::DetectorParameters> params = aruco::DetectorParameters::create();
params.minDistanceToBorder = 0; params->minDistanceToBorder = 0;
params.markerBorderBits = markerBorder; params->markerBorderBits = markerBorder;
aruco::detectMarkers(img, dictionary, corners, ids, params); aruco::detectMarkers(img, dictionary, corners, ids, params);
if(ids.size() != 4) { if(ids.size() != 4) {
...@@ -483,7 +483,7 @@ void CV_CharucoDiamondDetection::run(int) { ...@@ -483,7 +483,7 @@ void CV_CharucoDiamondDetection::run(int) {
} }
for(int i = 0; i < 4; i++) { for(int i = 0; i < 4; i++) {
if(diamondIds[0][i] != board.ids[i]) { if(diamondIds[0][i] != board->ids[i]) {
ts->printf(cvtest::TS::LOG, "Incorrect diamond ids"); ts->printf(cvtest::TS::LOG, "Incorrect diamond ids");
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH); ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return; return;
...@@ -492,7 +492,7 @@ void CV_CharucoDiamondDetection::run(int) { ...@@ -492,7 +492,7 @@ void CV_CharucoDiamondDetection::run(int) {
vector< Point2f > projectedDiamondCorners; vector< Point2f > projectedDiamondCorners;
projectPoints(board.chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs, projectPoints(board->chessboardCorners, rvec, tvec, cameraMatrix, distCoeffs,
projectedDiamondCorners); projectedDiamondCorners);
vector< Point2f > projectedDiamondCornersReorder(4); vector< Point2f > projectedDiamondCornersReorder(4);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment