8#ifndef META_OCEAN_CV_DETECTOR_MESSENGER_CODE_DETECTOR_H
9#define META_OCEAN_CV_DETECTOR_MESSENGER_CODE_DETECTOR_H
37 friend class QRCodeDetector;
44 static constexpr size_t numberCodeBits = 260;
54 using Codes = std::vector<CodeBits>;
90 inline const Vector2& position()
const;
96 inline Scalar radius()
const;
102 inline unsigned int grayThreshold()
const;
176 static constexpr int deltaThreshold = 20;
194 inline int history1();
200 inline int history2();
206 inline int history3();
213 inline void push(
const int newDelta);
243 static Codes detectMessengerCodes(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
Worker* worker =
nullptr);
270 template <
bool tCreateDebugInformation>
282 static inline Bullseyes detectBullseyes(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
Worker* worker =
nullptr);
295 static void detectBullseyesSubset(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
Bullseyes* bullseyes,
Lock* multiThreadLock,
const unsigned int yFramePaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
335 static bool correctRotation(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const Vector2* bullseyes,
const Scalar codeSize,
SquareMatrix3& homography,
const unsigned int yFramePaddingElements);
362 template <
bool tCreateDebugInformation>
363 static bool extractCodeBits(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const Scalar codeSize,
const SquareMatrix3& homography,
CodeBits& codeBits,
const unsigned int grayThreshold,
const unsigned int yFramePaddingElements,
Vectors2* codeBitsLocationFrame =
nullptr);
374 static void detectBullseyesInRow(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int y,
Bullseyes& bullseyes,
const unsigned int yFramePaddingElements);
393 static bool checkBullseyeInColumn(
const uint8_t*
const yFrame,
const unsigned int frameStrideElements,
const unsigned int height,
const unsigned int xCenter,
const unsigned int yCenter,
const unsigned int threshold,
const unsigned int blackRingSegmentMin,
const unsigned int blackRingSegmentMax,
const unsigned int whiteRingSegmentMin,
const unsigned int whiteRingSegmentMax,
const unsigned int dotSegmentMin,
const unsigned int dotSegmentMax);
410 static bool checkBullseyeInNeighborhood(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int xCenter,
const unsigned int yCenter,
const unsigned int threshold,
const float whiteRingRadius,
const float blackRingRadius,
const float whiteBorderRadius,
const unsigned int yFramePaddingElements);
425 static unsigned int determineThreshold(
const uint8_t* yPosition,
const unsigned int segmentSize1,
const unsigned int segmentSize2,
const unsigned int segmentSize3,
const unsigned int segmentSize4,
const unsigned int segmentSize5);
433 static inline bool isTransitionToBlack(
const uint8_t* pixel,
TransitionHistory& history);
441 static inline bool isTransitionToWhite(
const uint8_t* pixel,
TransitionHistory& history);
454 template <
bool tFindBlackPixel>
455 static bool findNextUpperPixel(
const uint8_t* yPointer,
const unsigned int y,
const unsigned int maximalRows,
const unsigned int threshold,
const unsigned int frameStrideElements,
unsigned int& rows);
469 template <
bool tFindBlackPixel>
470 static bool findNextLowerPixel(
const uint8_t* yPointer,
const unsigned int y,
const unsigned int height,
const unsigned int maximalRows,
const unsigned int threshold,
const unsigned int frameStrideElements,
unsigned int& rows);
484 static bool determineAccurateBullseyeLocation(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int xBullseye,
const unsigned int yBullseye,
const unsigned int threshold,
Vector2& location,
const unsigned int framePaddingElements);
491 static inline Scalar radius2bullseyesDistanceShort(
const Scalar radius);
498 static inline Scalar radius2bullseyesDistanceLong(
const Scalar radius);
533 grayThreshold_(grayThreshold)
550 return grayThreshold_;
568 return deltaMinus1 + deltaMinus2;
573 return deltaMinus1 + deltaMinus2 + deltaMinus3;
578 deltaMinus3 = deltaMinus2;
579 deltaMinus2 = deltaMinus1;
580 deltaMinus1 = newDelta;
592 ocean_assert(yFrame !=
nullptr);
593 ocean_assert(width >= 21u && height >= 21u);
596 bullseyes.reserve(16);
598 if (worker && height >= 600u)
600 Lock multiThreadLock;
601 worker->
executeFunction(
Worker::Function::createStatic(&
MessengerCodeDetector::detectBullseyesSubset, yFrame, width, height, &bullseyes, &multiThreadLock, yFramePaddingElements, 0u, 0u), 10u, height - 20u);
605 detectBullseyesSubset(yFrame, width, height, &bullseyes,
nullptr, yFramePaddingElements, 10u, height - 20u);
613 const int currentDelta = int(*(pixel + 0) - *(pixel - 1));
628 history.
push(currentDelta);
635 const int currentDelta = int(*(pixel + 0) - *(pixel - 1));
650 history.
push(currentDelta);
655template <
bool tFindBlackPixel>
658 ocean_assert(yPointer !=
nullptr);
659 ocean_assert(maximalRows != 0u);
660 ocean_assert(frameStrideElements != 0u);
669 while (
int(--y) >= 0 && ++rows <= maximalRows && (tFindBlackPixel ? (
int(*(yPointer - frameStrideElements)) >
int(threshold)) : (int(*(yPointer - frameStrideElements)) < int(threshold))))
671 yPointer -= frameStrideElements;
674 return int(y) >= 0 && rows <= maximalRows;
677template <
bool tFindBlackPixel>
678bool MessengerCodeDetector::findNextLowerPixel(
const uint8_t* yPointer,
unsigned int y,
const unsigned int height,
const unsigned int maximalRows,
const unsigned int threshold,
const unsigned int frameStrideElements,
unsigned int& rows)
680 ocean_assert(yPointer !=
nullptr);
681 ocean_assert(maximalRows != 0u);
682 ocean_assert(y < height);
683 ocean_assert(frameStrideElements != 0u);
685 if (y >= height - 1u)
692 while (++y < height && ++rows <= maximalRows && (tFindBlackPixel ? (
int(*(yPointer + frameStrideElements)) >
int(threshold)) : (int(*(yPointer + frameStrideElements)) < int(threshold))))
694 yPointer += frameStrideElements;
697 return y < height && rows <= maximalRows;
721 return radius *
Scalar(512.0 / 27.0);
Definition of a class holding a bullseye composed of a location and a radius.
Definition MessengerCodeDetector.h:70
unsigned int grayThreshold_
The threshold that was used during the detection of this bullseye.
Definition MessengerCodeDetector.h:113
const Vector2 & position() const
Returns the (center) position of the bullseye.
Definition MessengerCodeDetector.h:538
Scalar radius_
The radius of the bullseye in pixels, with range (0, infinity).
Definition MessengerCodeDetector.h:110
Bullseye()
Creates an invalid bullseye object.
Definition MessengerCodeDetector.h:522
unsigned int grayThreshold() const
Returns the threshold that was used for the detection of this bullseye.
Definition MessengerCodeDetector.h:548
Vector2 position_
The (center) position of the bullseye within the camera frame.
Definition MessengerCodeDetector.h:107
Scalar radius() const
Returns the radius of the bullseye.
Definition MessengerCodeDetector.h:543
This class implements a simple history for previous pixel transitions (a sliding window of pixel tran...
Definition MessengerCodeDetector.h:182
int deltaMinus3
The third previous delta.
Definition MessengerCodeDetector.h:229
int deltaMinus1
The previous delta.
Definition MessengerCodeDetector.h:223
void push(const int newDelta)
Adds a new delta object as most recent history.
Definition MessengerCodeDetector.h:576
int history2()
Returns the history with window size 2.
Definition MessengerCodeDetector.h:566
int history1()
Returns the history with window size 1.
Definition MessengerCodeDetector.h:561
int history3()
Returns the history with window size 3.
Definition MessengerCodeDetector.h:571
TransitionHistory()
Creates a new history object.
Definition MessengerCodeDetector.h:553
int deltaMinus2
The second previous delta.
Definition MessengerCodeDetector.h:226
void reset()
Resets the history object.
Definition MessengerCodeDetector.h:583
This class implements a detector for circular Messenger Codes.
Definition MessengerCodeDetector.h:36
static IndexQuartets extractCodeCandidates(const Vector2 *bullseyes, const Scalar *radii, const size_t size, const Scalar radiusScaleTolerance=Scalar(0.35), const Scalar distanceScaleTolerance=Scalar(0.17))
Extracts quartets of code bullseyes from a given set of bullseyes.
std::vector< CodeBits > Codes
Definition of a vector holding codes.
Definition MessengerCodeDetector.h:54
static bool isCodeInsideFrame(const unsigned int width, const unsigned int height, const SquareMatrix3 &homography, const Scalar codeSize)
Returns whether a Messenger Code, defined by a rectifying homography and code size,...
static void calculateRingBitCoordinates(const unsigned int bits, const IndexSet32 &bitsToSkip, const Scalar radius, Vectors2 &coordinates)
Calculates the bit coordinates of a ring of the Messenger Code.
static Scalar radius2bullseyesDistanceLong(const Scalar radius)
Returns the long distance between two bullseyes of the same Messenger Code (for opposite bullseyes) b...
Definition MessengerCodeDetector.h:713
static bool determineHomographyForBullseyeQuartet(const Vector2 *bullseyes, SquareMatrix3 &homography, Scalar &codeSize)
Calculates the homography rectifying the image content covered (and defined) by four bullseyes.
static void detectBullseyesSubset(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, Bullseyes *bullseyes, Lock *multiThreadLock, const unsigned int yFramePaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Detects Messenger Code bullseyes in subset of a given 8 bit grayscale image.
static Vectors2 calculateBitCoordiantes()
Returns 260 coordinates of the Messenger Code's bit elements origin in the center of the Code and nor...
std::vector< Bullseye > Bullseyes
Definition of a vector holding bullseyes.
Definition MessengerCodeDetector.h:119
static void detectBullseyesInRow(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int y, Bullseyes &bullseyes, const unsigned int yFramePaddingElements)
Detects Messenger Code bullseyes in a row of an grayscale image.
static bool checkBullseyeInColumn(const uint8_t *const yFrame, const unsigned int frameStrideElements, const unsigned int height, const unsigned int xCenter, const unsigned int yCenter, const unsigned int threshold, const unsigned int blackRingSegmentMin, const unsigned int blackRingSegmentMax, const unsigned int whiteRingSegmentMin, const unsigned int whiteRingSegmentMax, const unsigned int dotSegmentMin, const unsigned int dotSegmentMax)
Checks whether a column contains a bullseye at a specified location.
static bool isTransitionToBlack(const uint8_t *pixel, TransitionHistory &history)
Checks whether the given pixel is a transition-to-black pixel (whether the direct left neighbor is a ...
Definition MessengerCodeDetector.h:611
static bool determineAccurateBullseyeLocation(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int xBullseye, const unsigned int yBullseye, const unsigned int threshold, Vector2 &location, const unsigned int framePaddingElements)
Determines the sub-pixel location of the center dot of a known bullseye.
static unsigned int determineThreshold(const uint8_t *yPosition, const unsigned int segmentSize1, const unsigned int segmentSize2, const unsigned int segmentSize3, const unsigned int segmentSize4, const unsigned int segmentSize5)
Determines the gray threshold separating bright pixels form dark pixels.
static const Vectors2 & codeBitCoordinates()
Returns the reference to 260 coordinates of the Messenger Code's bit elements origin in the center of...
static Scalar radius2bullseyesDistanceShort(const Scalar radius)
Returns the short distance between two bullseyes of the same Messenger Code (for neighboring bullseye...
Definition MessengerCodeDetector.h:700
static bool extractCodeBits(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const Scalar codeSize, const SquareMatrix3 &homography, CodeBits &codeBits, const unsigned int grayThreshold, const unsigned int yFramePaddingElements, Vectors2 *codeBitsLocationFrame=nullptr)
Extracts the Messenger Code's bit information.
std::array< unsigned int, 4 > IndexQuartet
Definition of an index quartet (an array with exactly four indices).
Definition MessengerCodeDetector.h:59
std::vector< IndexQuartet > IndexQuartets
Definition of a vector holding index quartets.
Definition MessengerCodeDetector.h:64
static bool findNextUpperPixel(const uint8_t *yPointer, const unsigned int y, const unsigned int maximalRows, const unsigned int threshold, const unsigned int frameStrideElements, unsigned int &rows)
Finds either the next black or the next white pixel towards negative y direction (upwards in an image...
Definition MessengerCodeDetector.h:656
static bool checkBullseyeInNeighborhood(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int xCenter, const unsigned int yCenter, const unsigned int threshold, const float whiteRingRadius, const float blackRingRadius, const float whiteBorderRadius, const unsigned int yFramePaddingElements)
Checks whether the direction neighborhood contains a bullseye at a specified location.
static Bullseyes detectBullseyes(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, Worker *worker=nullptr)
Detects Messenger Code bullseyes in a given 8 bit grayscale image.
Definition MessengerCodeDetector.h:590
static bool findNextLowerPixel(const uint8_t *yPointer, const unsigned int y, const unsigned int height, const unsigned int maximalRows, const unsigned int threshold, const unsigned int frameStrideElements, unsigned int &rows)
Finds either the next black or the next white pixel towards positive y direction (downwards in an ima...
Definition MessengerCodeDetector.h:678
static bool isTransitionToWhite(const uint8_t *pixel, TransitionHistory &history)
Checks whether the given pixel is a transition-to-white pixel (whether the direct left neighbor is a ...
Definition MessengerCodeDetector.h:633
static Codes detectMessengerCodesWithDebugInformation(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, DebugInformation &debugInformation, const unsigned int yFramePaddingElements, Worker *worker=nullptr)
Detects Messenger Codes in a given 8 bit grayscale image and returns debug information.
static Codes detectMessengerCodes(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int paddingElements, Worker *worker=nullptr)
Detects Messenger Codes in a given 8 bit grayscale image.
static constexpr int deltaThreshold
The intensity threshold between two successive pixels to count as a transition from black to white (o...
Definition MessengerCodeDetector.h:176
static bool correctRotation(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const Vector2 *bullseyes, const Scalar codeSize, SquareMatrix3 &homography, const unsigned int yFramePaddingElements)
Corrects the orientation of a given homography already rectifying the content of a Messenger Code.
std::bitset< numberCodeBits > CodeBits
Definition of a bitset containing the information of a Messenger Code.
Definition MessengerCodeDetector.h:49
static Codes detectMessengerCodes(const uint8_t *const yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, DebugInformation *debugInformation=nullptr, Worker *worker=nullptr)
Detects Messenger Codes in a given 8 bit grayscale image.
static Caller< void > createStatic(typename StaticFunctionPointerMaker< void, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass, NullClass >::Type function)
Creates a new caller container for a static function with no function parameter.
Definition Caller.h:2877
This class implements Ocean's image class.
Definition Frame.h:1808
This class implements a recursive lock object.
Definition Lock.h:31
This class implements a worker able to distribute function calls over different threads.
Definition Worker.h:33
bool executeFunction(const Function &function, const unsigned int first, const unsigned int size, const unsigned int firstIndex=(unsigned int)(-1), const unsigned int sizeIndex=(unsigned int)(-1), const unsigned int minimalIterations=1u, const unsigned int threadIndex=(unsigned int)(-1))
Executes a callback function separable by two function parameters.
std::set< Index32 > IndexSet32
Definition of a set holding 32 bit indices.
Definition Base.h:114
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition Vector2.h:64
The namespace covering the entire Ocean framework.
Definition Accessor.h:15