diff --git a/modules/aruco/include/opencv2/aruco.hpp b/modules/aruco/include/opencv2/aruco.hpp index ba802a6fbaa..39c9802e277 100644 --- a/modules/aruco/include/opencv2/aruco.hpp +++ b/modules/aruco/include/opencv2/aruco.hpp @@ -144,6 +144,8 @@ enum CornerRefineMethod{ * done at full resolution. * - aprilTagQuadSigma: What Gaussian blur should be applied to the segmented image (used for quad detection?) * Parameter is the standard deviation in pixels. Very noisy images benefit from non-zero values (e.g. 0.8). + * - detectInvertedMarker: to check if there is a white marker. In order to generate a "white" marker just + * invert a normal marker by using a tilde, ~markerImage. (default false) */ struct CV_EXPORTS_W DetectorParameters { @@ -183,6 +185,9 @@ struct CV_EXPORTS_W DetectorParameters { CV_PROP_RW float aprilTagMaxLineFitMse; CV_PROP_RW int aprilTagMinWhiteBlackDiff; CV_PROP_RW int aprilTagDeglitch; + + // to detect white markers + CV_PROP_RW bool detectInvertedMarker; }; diff --git a/modules/aruco/src/aruco.cpp b/modules/aruco/src/aruco.cpp index 76cd9edb3e2..eb4915bbdae 100644 --- a/modules/aruco/src/aruco.cpp +++ b/modules/aruco/src/aruco.cpp @@ -86,7 +86,8 @@ DetectorParameters::DetectorParameters() aprilTagCriticalRad( (float)(10* CV_PI /180) ), aprilTagMaxLineFitMse(10.0), aprilTagMinWhiteBlackDiff(5), - aprilTagDeglitch(0){} + aprilTagDeglitch(0), + detectInvertedMarker(false){} /** @@ -512,7 +513,18 @@ static bool _identifyOneCandidate(const Ptr& dictionary, InputArray int(dictionary->markerSize * dictionary->markerSize * params->maxErroneousBitsInBorderRate); int borderErrors = _getBorderErrors(candidateBits, dictionary->markerSize, params->markerBorderBits); - if(borderErrors > maximumErrorsInBorder) return false; // border is wrong + + // check if it is a white marker + if(params->detectInvertedMarker){ + // to get from 255 to 1 + int invBError = _getBorderErrors(~candidateBits-254, dictionary->markerSize, params->markerBorderBits); + // white marker + if(invBError maximumErrorsInBorder) return false; // take only inner bits Mat onlyBits =