diff --git a/modules/objdetect/src/aruco/aruco_detector.cpp b/modules/objdetect/src/aruco/aruco_detector.cpp index 434e709810..819d78db10 100644 --- a/modules/objdetect/src/aruco/aruco_detector.cpp +++ b/modules/objdetect/src/aruco/aruco_detector.cpp @@ -383,31 +383,41 @@ static Mat _extractCellPixelRatio(InputArray _image, const vector& corn /** - * @brief Return number of erroneous bits in border, i.e. bits for which pixel ratio > validBitIdThreshold. + * @brief Return number of erroneous bits in border. + * + * Black border error if cellPixelRatio > validBitIdThreshold -> borderErrors + * White border error if 1 - cellPixelRatio > validBitIdThreshold + * <=> cellPixelRatio < 1 - validBitIdThreshold) -> invBorderErrors (inverted markers) */ - static int _getBorderErrors(const Mat &cellPixelRatio, int markerSize, int borderSize, float validBitIdThreshold) { +static void _getBorderErrors(const Mat &cellPixelRatio, int markerSize, int borderSize, float validBitIdThreshold, + int &borderErrors, int &invBorderErrors) { int sizeWithBorders = markerSize + 2 * borderSize; CV_Assert(markerSize > 0 && cellPixelRatio.cols == sizeWithBorders && cellPixelRatio.rows == sizeWithBorders); // Get border error. cellPixelRatio has the opposite color as the borders. - int totalErrors = 0; + const float invThreshold = 1.f - validBitIdThreshold; + borderErrors = invBorderErrors = 0; + const auto countCell = [&](float ratio) { + if(ratio > validBitIdThreshold) borderErrors++; + if(ratio < invThreshold) invBorderErrors++; + }; for(int y = 0; y < sizeWithBorders; y++) { + const float* row = cellPixelRatio.ptr(y); for(int k = 0; k < borderSize; k++) { // Left and right vertical sides - if(cellPixelRatio.ptr(y)[k] > validBitIdThreshold) totalErrors++; - if(cellPixelRatio.ptr(y)[sizeWithBorders - 1 - k] > validBitIdThreshold) totalErrors++; + countCell(row[k]); + countCell(row[sizeWithBorders - 1 - k]); } } for(int x = borderSize; x < sizeWithBorders - borderSize; x++) { for(int k = 0; k < borderSize; k++) { // Top and bottom horizontal sides - if(cellPixelRatio.ptr(k)[x] > validBitIdThreshold) totalErrors++; - if(cellPixelRatio.ptr(sizeWithBorders - 1 - k)[x] > validBitIdThreshold) totalErrors++; + countCell(cellPixelRatio.ptr(k)[x]); + countCell(cellPixelRatio.ptr(sizeWithBorders - 1 - k)[x]); } } - return totalErrors; } @@ -486,19 +496,16 @@ static uint8_t _identifyOneCandidate(const Dictionary& dictionary, const Mat& _i // analyze border bits int maximumErrorsInBorder = int(dictionary.markerSize * dictionary.markerSize * params.maxErroneousBitsInBorderRate); - int borderErrors = - _getBorderErrors(cellPixelRatio, dictionary.markerSize, params.markerBorderBits, params.validBitIdThreshold); + int borderErrors = 0, invBorderErrors = 0; + _getBorderErrors(cellPixelRatio, dictionary.markerSize, params.markerBorderBits, params.validBitIdThreshold, + borderErrors, invBorderErrors); // check if it is a white marker - if(params.detectInvertedMarker){ - Mat invCellPixelRatio = 1.f - cellPixelRatio; - int invBError = _getBorderErrors(invCellPixelRatio, dictionary.markerSize, params.markerBorderBits, params.validBitIdThreshold); - // white marker - if(invBError maximumErrorsInBorder) return 0; // border is wrong