8 #ifndef META_OCEAN_CV_DETECTOR_HARRIS_CORNER_DETECTOR_H
9 #define META_OCEAN_CV_DETECTOR_HARRIS_CORNER_DETECTOR_H
48 FD_FRAME_IS_DISTORTED =
false,
50 FD_FRAME_IS_UNDISTORTED =
true,
59 PP_PIXEL_ACCURACY =
false,
61 PP_SUBPIXEL_ACCURACY =
true
85 inline PreciseCornerPosition(
const uint8_t* frame,
const unsigned int width,
const unsigned int height,
const unsigned int framePaddingElements);
97 bool precisePosition(
const unsigned int x,
const unsigned int y,
const int32_t strength,
Scalar& preciseX,
Scalar& preciseY, int32_t& preciseStrength);
129 static inline bool detectCorners(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition =
false,
Worker* worker =
nullptr);
148 static bool detectCorners(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
const unsigned int subFrameLeft,
const unsigned int subFrameTop,
const unsigned int subFrameWidth,
const unsigned int subFrameHeight,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition =
false,
Worker* worker =
nullptr);
161 static inline bool detectCorners(
const Frame& frame,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition =
false,
Worker* worker =
nullptr);
178 static inline bool detectCorners(
const Frame& frame,
const unsigned int subFrameLeft,
const unsigned int subFrameTop,
const unsigned int subFrameWidth,
const unsigned int subFrameHeight,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition =
false,
Worker* worker =
nullptr);
192 static void harrisVotesFrame(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements, int32_t* votes,
const unsigned int votesPaddingElements,
Worker* worker =
nullptr,
const bool setBorderPixels =
false);
206 static void harrisVotesFrameSobelResponse(
const int8_t* sobelResponse,
const unsigned int width,
const unsigned int height,
const unsigned int sobelResponsePaddingElements, int32_t* votes,
const unsigned int votesPaddingElements,
Worker* worker =
nullptr,
const bool setBorderPixels =
false);
219 static void harrisVotes(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
const PixelPosition* positions,
const size_t numberPositions, int32_t* votes,
Worker* worker =
nullptr);
230 static int32_t
harrisVotePixel(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int x,
const unsigned int y,
const unsigned int yFramePaddingElements);
252 static std::vector<int32_t>
harrisVotesSubPixel(
const uint8_t* yFrame,
const unsigned int width,
const Vectors2& positions,
const unsigned int yFramePaddingElements,
Worker* worker =
nullptr);
261 static inline int32_t harrisVotePixel(
const int8_t* sobelResponses,
const unsigned int width,
const unsigned int sobelResponsesPaddingElements);
270 static inline int32_t harrisVotePixel(
const int32_t* squaredSobelResponses,
const unsigned int width,
const unsigned int squaredSobelResponsesPaddingElements);
285 static inline int32_t harrisVote(
const int16_t*
const responsesXX0,
const int16_t*
const responsesXX1,
const int16_t*
const responsesXX2,
const int16_t*
const responsesYY0,
const int16_t*
const responsesYY1,
const int16_t*
const responsesYY2,
const int16_t*
const responsesXY0,
const int16_t*
const responsesXY1,
const int16_t*
const responsesXY2);
297 static constexpr int32_t determineInternalThreshold(
const unsigned int threshold);
307 template <
typename T>
308 static inline T determineThreshold(
const T vote);
323 static void harrisVotesByResponseSubset(
const int8_t* response,
const unsigned int width,
const unsigned int height,
const unsigned int responsePaddingElements, int32_t* votes,
const unsigned int votesPaddingElements,
const unsigned int firstRow,
const unsigned int numberRows);
335 static void harrisVotesSubPixelSubset(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int yFramePaddingElements,
const Vector2* positions, int32_t* votes,
const unsigned int firstPosition,
const unsigned int numberPositions);
350 static void detectCornerCandidatesSubset(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
const int32_t internalThreshold,
NonMaximumSuppressionVote* nonMaximumSuppression,
const unsigned int firstColumn,
const unsigned int numberColumns,
const unsigned int firstRow,
const unsigned int numberRows);
352 #if defined(OCEAN_HARDWARE_NEON_VERSION) && OCEAN_HARDWARE_NEON_VERSION >= 10
361 static void determine4VotesNEON(
const int32x4_t& Ixx_s_32x4,
const int32x4_t& Iyy_s_32x4,
const int32x4_t& Ixy_s_32x4, int32_t* votes);
370 static constexpr uint32_t
sqr(
const int32_t value);
377 static constexpr uint32_t
sqr(
const uint32_t value);
384 static constexpr uint64_t
sqr(
const int64_t value);
390 frameHeight_(height),
391 framePaddingElements_(framePaddingElements)
397 inline bool HarrisCornerDetector::detectCorners(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition,
Worker* worker)
399 ocean_assert(yFrame !=
nullptr);
400 ocean_assert(width >= 10u && height >= 7u);
402 return detectCorners(yFrame, width, height, yFramePaddingElements, 0u, 0u, width, height, threshold, frameIsUndistorted, corners, determineExactPosition, worker);
418 inline bool HarrisCornerDetector::detectCorners(
const Frame& frame,
const unsigned int subFrameLeft,
const unsigned int subFrameTop,
const unsigned int subFrameWidth,
const unsigned int subFrameHeight,
const unsigned int threshold,
const bool frameIsUndistorted,
HarrisCorners& corners,
const bool determineExactPosition,
Worker* worker)
428 return detectCorners(yFrame.
constdata<uint8_t>(), yFrame.
width(), yFrame.
height(), yFrame.
paddingElements(), subFrameLeft, subFrameTop, subFrameWidth, subFrameHeight, threshold, frameIsUndistorted, corners, determineExactPosition, worker);
433 ocean_assert(sobelResponse !=
nullptr);
434 ocean_assert(width >= 3u);
436 const unsigned int sobelResponsesStrideElements = width * 2u + sobelResponsesPaddingElements;
438 const int8_t*
const response0 = sobelResponse - sobelResponsesStrideElements;
439 const int8_t*
const response1 = sobelResponse;
440 const int8_t*
const response2 = sobelResponse + sobelResponsesStrideElements;
442 const uint32_t Ixx =
sqr(*(response0 - 2)) +
sqr(*(response0 + 0)) +
sqr(*(response0 + 2))
443 +
sqr(*(response1 - 2)) +
sqr(*(response1 + 0)) +
sqr(*(response1 + 2))
444 +
sqr(*(response2 - 2)) +
sqr(*(response2 + 0)) +
sqr(*(response2 + 2));
446 const uint32_t Iyy =
sqr(*(response0 - 1)) +
sqr(*(response0 + 1)) +
sqr(*(response0 + 3))
447 +
sqr(*(response1 - 1)) +
sqr(*(response1 + 1)) +
sqr(*(response1 + 3))
448 +
sqr(*(response2 - 1)) +
sqr(*(response2 + 1)) +
sqr(*(response2 + 3));
450 const int32_t Ixy = *(response0 - 2) * *(response0 - 1) + *(response0 + 0) * *(response0 + 1) + *(response0 + 2) * *(response0 + 3)
451 + *(response1 - 2) * *(response1 - 1) + *(response1 + 0) * *(response1 + 1) + *(response1 + 2) * *(response1 + 3)
452 + *(response2 - 2) * *(response2 - 1) + *(response2 + 0) * *(response2 + 1) + *(response2 + 2) * *(response2 + 3);
454 const int32_t determinant = int32_t((Ixx / 8u) * (Iyy / 8u)) - int32_t(
sqr((Ixy / 8)));
455 const uint32_t sqrTrace =
sqr((Ixx + Iyy) / 8u);
459 return determinant - int32_t((sqrTrace * 3u) / 64u);
464 ocean_assert(squaredSobelResponses !=
nullptr);
465 ocean_assert(width >= 3u);
467 const unsigned int squaredSobelResponsesStrideElements = width * 3u + squaredSobelResponsesPaddingElements;
469 const int32_t*
const response0 = squaredSobelResponses - squaredSobelResponsesStrideElements;
470 const int32_t*
const response1 = squaredSobelResponses;
471 const int32_t*
const response2 = squaredSobelResponses + squaredSobelResponsesStrideElements;
473 const uint32_t Ixx = uint32_t(*(response0 - 3) + *(response0 + 0) + *(response0 + 3)
474 + *(response1 - 3) + *(response1 + 0) + *(response1 + 3)
475 + *(response2 - 3) + *(response2 + 0) + *(response2 + 3));
477 const uint32_t Iyy = uint32_t(*(response0 - 2) + *(response0 + 1) + *(response0 + 4)
478 + *(response1 - 2) + *(response1 + 1) + *(response1 + 4)
479 + *(response2 - 2) + *(response2 + 1) + *(response2 + 4));
481 const int32_t Ixy = *(response0 - 1) + *(response0 + 2) + *(response0 + 5)
482 + *(response1 - 1) + *(response1 + 2) + *(response1 + 5)
483 + *(response2 - 1) + *(response2 + 2) + *(response2 + 5);
485 const int32_t determinant = int32_t((Ixx / 8u) * (Iyy / 8u)) - int32_t(
sqr((Ixy / 8)));
486 const uint32_t sqrTrace =
sqr((Ixx + Iyy) / 8u);
490 return determinant - int32_t((sqrTrace * 3u) / 64u);
493 inline int32_t
HarrisCornerDetector::harrisVote(
const int16_t*
const responsesXX0,
const int16_t*
const responsesXX1,
const int16_t*
const responsesXX2,
const int16_t*
const responsesYY0,
const int16_t*
const responsesYY1,
const int16_t*
const responsesYY2,
const int16_t*
const responsesXY0,
const int16_t*
const responsesXY1,
const int16_t*
const responsesXY2)
495 ocean_assert(responsesXX0 !=
nullptr && responsesXX1 !=
nullptr && responsesXX2 !=
nullptr);
496 ocean_assert(responsesYY0 !=
nullptr && responsesYY1 !=
nullptr && responsesYY2 !=
nullptr);
497 ocean_assert(responsesXY0 !=
nullptr && responsesXY1 !=
nullptr && responsesXY2 !=
nullptr);
499 ocean_assert(responsesXX0[0] >= 0 && responsesXX0[1] >= 0 && responsesXX0[2] >= 0);
500 ocean_assert(responsesXX1[0] >= 0 && responsesXX1[1] >= 0 && responsesXX1[2] >= 0);
501 ocean_assert(responsesXX2[0] >= 0 && responsesXX2[1] >= 0 && responsesXX2[2] >= 0);
503 ocean_assert(responsesYY0[0] >= 0 && responsesYY0[1] >= 0 && responsesYY0[2] >= 0);
504 ocean_assert(responsesYY1[0] >= 0 && responsesYY1[1] >= 0 && responsesYY1[2] >= 0);
505 ocean_assert(responsesYY2[0] >= 0 && responsesYY2[1] >= 0 && responsesYY2[2] >= 0);
507 const uint32_t Ixx = uint32_t(responsesXX0[0]) + uint32_t(responsesXX0[1]) + uint32_t(responsesXX0[2])
508 + uint32_t(responsesXX1[0]) + uint32_t(responsesXX1[1]) + uint32_t(responsesXX1[2])
509 + uint32_t(responsesXX2[0]) + uint32_t(responsesXX2[1]) + uint32_t(responsesXX2[2]);
511 const uint32_t Iyy = uint32_t(responsesYY0[0]) + uint32_t(responsesYY0[1]) + uint32_t(responsesYY0[2])
512 + uint32_t(responsesYY1[0]) + uint32_t(responsesYY1[1]) + uint32_t(responsesYY1[2])
513 + uint32_t(responsesYY2[0]) + uint32_t(responsesYY2[1]) + uint32_t(responsesYY2[2]);
515 const int32_t Ixy = int32_t(responsesXY0[0]) + int32_t(responsesXY0[1]) + int32_t(responsesXY0[2])
516 + int32_t(responsesXY1[0]) + int32_t(responsesXY1[1]) + int32_t(responsesXY1[2])
517 + int32_t(responsesXY2[0]) + int32_t(responsesXY2[1]) + int32_t(responsesXY2[2]);
519 const int32_t determinant = int32_t((Ixx / 8u) * (Iyy / 8u)) - int32_t(
sqr((Ixy / 8)));
520 const uint32_t sqrTrace =
sqr((Ixx + Iyy) / 8u);
524 return determinant - int32_t((sqrTrace * 3u) / 64u);
529 ocean_assert(threshold <= 512u);
531 return int32_t(
sqr(threshold * threshold / 8u));
546 template <
typename T>
549 static_assert(!std::is_floating_point<T>::value,
"Invalid data type!");
551 const double result = determineThreshold<double>(
double(vote));
559 ocean_assert(value >= -65535 && value <= 65535);
561 return uint32_t(value * value);
566 ocean_assert(value <= 65535u);
568 return value * value;
573 ocean_assert(value >= -4294967295ll && value <= 4294967295ll);
575 return value * value;
This class implements a helper object allowing to determine the precise 2D position of Harris corners...
Definition: HarrisCornerDetector.h:75
bool precisePosition(const unsigned int x, const unsigned int y, const int32_t strength, Scalar &preciseX, Scalar &preciseY, int32_t &preciseStrength)
Determines the precise position of a given (rough) Harris corner.
PreciseCornerPosition(const uint8_t *frame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements)
Creates a new object.
Definition: HarrisCornerDetector.h:387
const unsigned int framePaddingElements_
The optional number of padding elements at the end of each row, with range [0, infinity)
Definition: HarrisCornerDetector.h:111
const unsigned int frameWidth_
The frame width in pixel, with range [7, infinity)
Definition: HarrisCornerDetector.h:105
const uint8_t *const frameData_
The frame in which the Harris corners are detected.
Definition: HarrisCornerDetector.h:102
const unsigned int frameHeight_
The frame height in pixel, with range [7, infinity)
Definition: HarrisCornerDetector.h:108
This class implements the Harris corner detector.
Definition: HarrisCornerDetector.h:39
static constexpr uint32_t sqr(const int32_t value)
Returns the square value.
Definition: HarrisCornerDetector.h:557
static void harrisVotesSubPixelSubset(const uint8_t *yFrame, const unsigned int width, const unsigned int yFramePaddingElements, const Vector2 *positions, int32_t *votes, const unsigned int firstPosition, const unsigned int numberPositions)
Creates the Harris corner votes for a subset of specified sub-pixel positions from an 8 bit grayscale...
static void harrisVotes(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, const PixelPosition *positions, const size_t numberPositions, int32_t *votes, Worker *worker=nullptr)
Calculates the Harris corner votes for several given positions in a frame only.
static void harrisVotesFrameSobelResponse(const int8_t *sobelResponse, const unsigned int width, const unsigned int height, const unsigned int sobelResponsePaddingElements, int32_t *votes, const unsigned int votesPaddingElements, Worker *worker=nullptr, const bool setBorderPixels=false)
Creates the Harris corner votes for the horizontal and vertical sobel responses for an entire frame (...
static std::vector< int32_t > harrisVotesSubPixel(const uint8_t *yFrame, const unsigned int width, const Vectors2 &positions, const unsigned int yFramePaddingElements, Worker *worker=nullptr)
Calculates the Harris corner votes for specified sub-pixel positions from an 8 bit grayscale frame.
PositionPrecision
Definition of a boolean enum for precision properties (to improve code readability).
Definition: HarrisCornerDetector.h:57
static void detectCornerCandidatesSubset(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, const int32_t internalThreshold, NonMaximumSuppressionVote *nonMaximumSuppression, const unsigned int firstColumn, const unsigned int numberColumns, const unsigned int firstRow, const unsigned int numberRows)
Detects Harris corners inside a sub-frame of a given frame.
static void determine4VotesNEON(const int32x4_t &Ixx_s_32x4, const int32x4_t &Iyy_s_32x4, const int32x4_t &Ixy_s_32x4, int32_t *votes)
Calculates four Harris Corner votes for 3x3 regions from sums of (squared) sobel responses.
static void harrisVotesByResponseSubset(const int8_t *response, const unsigned int width, const unsigned int height, const unsigned int responsePaddingElements, int32_t *votes, const unsigned int votesPaddingElements, const unsigned int firstRow, const unsigned int numberRows)
Determines Harris votes inside a sub-frame of a given buffer holding the filter responses.
static T determineThreshold(const T vote)
Determines the (external) threshold corresponding to an (internal) Harris vote.
Definition: HarrisCornerDetector.h:547
NonMaximumSuppression< int32_t > NonMaximumSuppressionVote
Definition of a maximum suppression object holding integer strength parameters.
Definition: HarrisCornerDetector.h:69
static constexpr int32_t determineInternalThreshold(const unsigned int threshold)
Returns the threshold used internally for a given threshold.
Definition: HarrisCornerDetector.h:527
static int32_t harrisVoteSubPixel(const uint8_t *yFrame, const unsigned int width, const Scalar x, const Scalar y, const unsigned int yFramePaddingElements)
Calculates the Harris corner vote for one specific sub-pixel position from an 8 bit grayscale frame.
static bool detectCorners(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, const unsigned int subFrameLeft, const unsigned int subFrameTop, const unsigned int subFrameWidth, const unsigned int subFrameHeight, const unsigned int threshold, const bool frameIsUndistorted, HarrisCorners &corners, const bool determineExactPosition=false, Worker *worker=nullptr)
Detects Harris corners inside a sub-frame of a given 8 bit grayscale image.
static bool detectCorners(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, const unsigned int threshold, const bool frameIsUndistorted, HarrisCorners &corners, const bool determineExactPosition=false, Worker *worker=nullptr)
Detects Harris corners inside a given 8 bit grayscale image.
Definition: HarrisCornerDetector.h:397
static int32_t harrisVote(const int16_t *const responsesXX0, const int16_t *const responsesXX1, const int16_t *const responsesXX2, const int16_t *const responsesYY0, const int16_t *const responsesYY1, const int16_t *const responsesYY2, const int16_t *const responsesXY0, const int16_t *const responsesXY1, const int16_t *const responsesXY2)
Calculates one Harris Corner vote for a 3x3 region from three buffers storing Sobel responses product...
Definition: HarrisCornerDetector.h:493
FrameDistortion
Definition of a boolean enum for frame un-/distortion properties (to improve code readability).
Definition: HarrisCornerDetector.h:46
static int32_t harrisVotePixel(const uint8_t *yFrame, const unsigned int width, const unsigned int x, const unsigned int y, const unsigned int yFramePaddingElements)
Calculates the Harris corner vote for one specific pixel from an 8 bit grayscale frame.
static void harrisVotesFrame(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, int32_t *votes, const unsigned int votesPaddingElements, Worker *worker=nullptr, const bool setBorderPixels=false)
Creates the Harris corner votes for an entire frame (and therefore for each pixel) without applying a...
static bool convert(const Frame &source, const FrameType::PixelFormat targetPixelFormat, const FrameType::PixelOrigin targetPixelOrigin, Frame &target, const bool forceCopy=true, Worker *worker=nullptr, const Options &options=Options())
Converts a frame with arbitrary dimension, pixel format and pixel origin into a frame with the same d...
@ CP_AVOID_COPY_IF_POSSIBLE
Tries to avoid copying the frame data whenever possible.
Definition: FrameConverter.h:96
This class implements the possibility to find local maximum in a 2D array by applying a non-maximum-s...
Definition: NonMaximumSuppression.h:41
This class implements Ocean's image class.
Definition: Frame.h:1792
const T * constdata(const unsigned int planeIndex=0u) const
Returns a pointer to the read-only pixel data of a specific plane.
Definition: Frame.h:4168
bool isValid() const
Returns whether this frame is valid.
Definition: Frame.h:4448
unsigned int paddingElements(const unsigned int planeIndex=0u) const
Returns the optional number of padding elements at the end of each row for a specific plane.
Definition: Frame.h:4042
@ FORMAT_Y8
Pixel format for grayscale images with byte order Y and 8 bits per pixel.
Definition: Frame.h:594
unsigned int width() const
Returns the width of the frame format in pixel.
Definition: Frame.h:3143
@ ORIGIN_UPPER_LEFT
The first pixel lies in the upper left corner, the last pixel in the lower right corner.
Definition: Frame.h:1050
unsigned int height() const
Returns the height of the frame in pixel.
Definition: Frame.h:3148
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static T pow(const T x, const T y)
Returns x raised to the power of y.
Definition: Numeric.h:1860
static T abs(const T value)
Returns the absolute value of a given value.
Definition: Numeric.h:1220
This class implements a worker able to distribute function calls over different threads.
Definition: Worker.h:33
unsigned int sqr(const char value)
Returns the square value of a given value.
Definition: base/Utilities.h:1029
std::vector< HarrisCorner > HarrisCorners
Definition of a vector holding Harris corners.
Definition: HarrisCorner.h:24
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