8 #ifndef META_OCEAN_CV_DETECTOR_MESSENGER_CODE_DETECTOR_H
9 #define META_OCEAN_CV_DETECTOR_MESSENGER_CODE_DETECTOR_H
23 #include <unordered_set>
40 friend class QRCodeDetector;
47 static constexpr
size_t numberCodeBits = 260;
57 typedef std::vector<CodeBits>
Codes;
93 inline const Vector2& position()
const;
99 inline Scalar radius()
const;
105 inline unsigned int grayThreshold()
const;
179 static constexpr
int deltaThreshold = 20;
197 inline int history1();
203 inline int history2();
209 inline int history3();
216 inline void push(
const int newDelta);
246 static Codes detectMessengerCodes(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
Worker* worker =
nullptr);
273 template <
bool tCreateDebugInformation>
285 static inline Bullseyes detectBullseyes(
const uint8_t*
const yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
Worker* worker =
nullptr);
298 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);
338 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);
365 template <
bool tCreateDebugInformation>
366 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);
377 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);
396 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);
413 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);
428 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);
436 static inline bool isTransitionToBlack(
const uint8_t* pixel,
TransitionHistory& history);
444 static inline bool isTransitionToWhite(
const uint8_t* pixel,
TransitionHistory& history);
457 template <
bool tFindBlackPixel>
458 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);
472 template <
bool tFindBlackPixel>
473 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);
487 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);
494 static inline Scalar radius2bullseyesDistanceShort(
const Scalar radius);
501 static inline Scalar radius2bullseyesDistanceLong(
const Scalar radius);
536 grayThreshold_(grayThreshold)
553 return grayThreshold_;
571 return deltaMinus1 + deltaMinus2;
576 return deltaMinus1 + deltaMinus2 + deltaMinus3;
581 deltaMinus3 = deltaMinus2;
582 deltaMinus2 = deltaMinus1;
583 deltaMinus1 = newDelta;
595 ocean_assert(yFrame !=
nullptr);
596 ocean_assert(width >= 21u && height >= 21u);
599 bullseyes.reserve(16);
601 if (worker && height >= 600u)
603 Lock multiThreadLock;
604 worker->
executeFunction(
Worker::Function::createStatic(&
MessengerCodeDetector::detectBullseyesSubset, yFrame, width, height, &bullseyes, &multiThreadLock, yFramePaddingElements, 0u, 0u), 10u, height - 20u);
608 detectBullseyesSubset(yFrame, width, height, &bullseyes,
nullptr, yFramePaddingElements, 10u, height - 20u);
616 const int currentDelta = int(*(pixel + 0) - *(pixel - 1));
631 history.
push(currentDelta);
638 const int currentDelta = int(*(pixel + 0) - *(pixel - 1));
653 history.
push(currentDelta);
658 template <
bool tFindBlackPixel>
661 ocean_assert(yPointer !=
nullptr);
662 ocean_assert(maximalRows != 0u);
663 ocean_assert(frameStrideElements != 0u);
672 while (
int(--y) >= 0 && ++rows <= maximalRows && (tFindBlackPixel ? (
int(*(yPointer - frameStrideElements)) >
int(threshold)) : (
int(*(yPointer - frameStrideElements)) <
int(threshold))))
674 yPointer -= frameStrideElements;
677 return int(y) >= 0 && rows <= maximalRows;
680 template <
bool tFindBlackPixel>
681 bool 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)
683 ocean_assert(yPointer !=
nullptr);
684 ocean_assert(maximalRows != 0u);
685 ocean_assert(y < height);
686 ocean_assert(frameStrideElements != 0u);
688 if (y >= height - 1u)
695 while (++y < height && ++rows <= maximalRows && (tFindBlackPixel ? (
int(*(yPointer + frameStrideElements)) >
int(threshold)) : (
int(*(yPointer + frameStrideElements)) <
int(threshold))))
697 yPointer += frameStrideElements;
700 return y < height && rows <= maximalRows;
724 return radius *
Scalar(512.0 / 27.0);
Definition of a class holding a bullseye composed of a location and a radius.
Definition: MessengerCodeDetector.h:73
unsigned int grayThreshold_
The threshold that was used during the detection of this bullseye.
Definition: MessengerCodeDetector.h:116
const Vector2 & position() const
Returns the (center) position of the bullseye.
Definition: MessengerCodeDetector.h:541
Scalar radius_
The radius of the bullseye in pixels, with range (0, infinity).
Definition: MessengerCodeDetector.h:113
Bullseye()
Creates an invalid bullseye object.
Definition: MessengerCodeDetector.h:525
unsigned int grayThreshold() const
Returns the threshold that was used for the detection of this bullseye.
Definition: MessengerCodeDetector.h:551
Vector2 position_
The (center) position of the bullseye within the camera frame.
Definition: MessengerCodeDetector.h:110
Scalar radius() const
Returns the radius of the bullseye.
Definition: MessengerCodeDetector.h:546
This class implements a simple history for previous pixel transitions (a sliding window of pixel tran...
Definition: MessengerCodeDetector.h:185
int deltaMinus3
The third previous delta.
Definition: MessengerCodeDetector.h:232
int deltaMinus1
The previous delta.
Definition: MessengerCodeDetector.h:226
void push(const int newDelta)
Adds a new delta object as most recent history.
Definition: MessengerCodeDetector.h:579
int history2()
Returns the history with window size 2.
Definition: MessengerCodeDetector.h:569
int history1()
Returns the history with window size 1.
Definition: MessengerCodeDetector.h:564
int history3()
Returns the history with window size 3.
Definition: MessengerCodeDetector.h:574
TransitionHistory()
Creates a new history object.
Definition: MessengerCodeDetector.h:556
int deltaMinus2
The second previous delta.
Definition: MessengerCodeDetector.h:229
void reset()
Resets the history object.
Definition: MessengerCodeDetector.h:586
This class implements a detector for circular Messenger Codes.
Definition: MessengerCodeDetector.h:39
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.
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:716
std::bitset< numberCodeBits > CodeBits
Definition of a bitset containing the information of a Messenger Code.
Definition: MessengerCodeDetector.h:52
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...
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.
std::vector< IndexQuartet > IndexQuartets
Definition of a vector holding index quartets.
Definition: MessengerCodeDetector.h:67
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:614
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 Scalar radius2bullseyesDistanceShort(const Scalar radius)
Returns the short distance between two bullseyes of the same Messenger Code (for neighboring bullseye...
Definition: MessengerCodeDetector.h:703
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::vector< CodeBits > Codes
Definition of a vector holding codes.
Definition: MessengerCodeDetector.h:57
std::vector< Bullseye > Bullseyes
Definition of a vector holding bullseyes.
Definition: MessengerCodeDetector.h:122
std::array< unsigned int, 4 > IndexQuartet
Definition of an index quartet (an array with exactly four indices).
Definition: MessengerCodeDetector.h:62
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:659
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:593
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:681
static const Vectors2 & codeBitCoordinates()
Returns the reference to 260 coordinates of the Messenger Code's bit elements origin in the center of...
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:636
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:179
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.
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:2876
This class implements Ocean's image class.
Definition: Frame.h:1792
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:128
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