8 #ifndef META_OCEAN_CV_DETECTOR_LINE_DETECTOR_ULF_H
9 #define META_OCEAN_CV_DETECTOR_LINE_DETECTOR_ULF_H
49 ET_SIGN_POSITIVE = 4u,
51 ET_SIGN_NEGATIVE = 8u,
53 ET_BAR_OR_STEP = ET_BAR | ET_STEP
66 SD_VERTICAL_AND_HORIZONTAL = SD_VERTICAL | SD_HORIZONTAL
93 inline unsigned int window()
const;
110 virtual void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const = 0;
124 virtual bool invokeHorizontal(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const;
150 static void determineRowSums(
const uint8_t* row,
const unsigned int width,
const unsigned int window, uint32_t* windowSums);
159 static void determineRowSums(
const uint8_t* row,
const unsigned int width,
const unsigned int window, uint16_t* windowSums);
169 static void determineRowSums(
const uint8_t* row,
const unsigned int width,
const unsigned int window, uint32_t* windowSums, uint32_t* windowSqrSums);
179 static void determineRowSums(
const uint8_t* row,
const unsigned int width,
const unsigned int window, uint16_t* windowSums, uint32_t* windowSqrSums);
189 static void applyRowSum(
const uint8_t* row,
const unsigned int width, uint16_t* sum);
200 static void applyRowSum(
const uint8_t* row,
const unsigned int width, uint16_t* sum, uint32_t* sqrSum);
234 static constexpr
unsigned int barSize_ = 3u;
243 explicit RMSBarEdgeDetectorI(
const unsigned int window = 4u,
const unsigned int minimalDelta = barDetectorMinimalDelta());
254 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int framePaddingElements)
const override;
268 bool invokeHorizontal(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const override;
287 static inline unsigned int staticAdjustThreshold(
const unsigned int threshold);
299 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int window,
const unsigned int minimalDelta,
const uint16_t*
const windowSums,
const uint32_t*
const windowSqrSums, int16_t* sqrResponses);
307 static inline EdgeDetectors asEdgeDetectors(
const unsigned int window = 4u,
const unsigned int minimalDelta = barDetectorMinimalDelta());
323 static constexpr
unsigned int stepSize_ = 1u;
342 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int framePaddingElements)
const override;
356 bool invokeHorizontal(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const override;
375 static inline unsigned int staticAdjustThreshold(
const unsigned int threshold);
386 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int window,
const uint16_t*
const windowSums,
const uint32_t*
const windowSqrSums, int16_t* sqrResponses);
393 static inline EdgeDetectors asEdgeDetectors(
const unsigned int window = 4u);
415 explicit RMSBarEdgeDetectorF(
const unsigned int window = 4u,
const unsigned int minimalDelta = barDetectorMinimalDelta());
421 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const override;
434 static inline unsigned int staticAdjustThreshold(
const unsigned int threshold);
446 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int window,
const unsigned int minimalDelta,
const uint32_t*
const windowSums,
const uint32_t*
const windowSqrSums, int16_t* sqrResponses);
471 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const override;
484 static inline unsigned int staticAdjustThreshold(
const unsigned int threshold);
495 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int window,
const uint32_t*
const windowSums,
const uint32_t*
const windowSqrSums, int16_t* sqrResponses);
520 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int framePaddingElements)
const override;
533 static inline unsigned int staticAdjustThreshold(
const unsigned int threshold);
543 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int window,
const uint32_t*
const windowSums, int16_t* responses);
550 static inline EdgeDetectors asEdgeDetectors(
const unsigned int window = 4u);
580 void invokeVertical(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int framePaddingElements)
const override;
586 bool invokeHorizontal(
const uint8_t* frame,
const unsigned int width,
const unsigned int height, int16_t* responses,
const unsigned int paddingElements)
const override;
606 static inline EdgeDetectors asEdgeDetectors(
const unsigned int window = 2u,
const unsigned int stepSize = 1u);
620 static void invokeRowVertical(
const uint8_t*
const row,
const unsigned int width,
const unsigned int stepSize,
const unsigned int window,
const uint16_t*
const windowSums, int16_t* responses);
637 static inline EdgeDetectors defaultEdgeDetectors(
const unsigned int window = 4u);
647 static inline EdgeDetectors performanceEdgeDetectors(
const unsigned int window = 4u);
664 static FiniteLines2 detectLines(
const uint8_t* yFrame,
const unsigned int width,
const unsigned int height,
const unsigned int framePaddingElements,
const EdgeDetectors& edgeDetectors = defaultEdgeDetectors(),
const unsigned int threshold = 50u,
const unsigned int minimalLength = 20u,
const float maximalStraightLineDistance = 1.6f,
EdgeTypes* types =
nullptr,
const ScanDirection scanDirection = SD_VERTICAL_AND_HORIZONTAL);
687 template <
typename T>
688 static void extractVerticalLines(T*
const responses,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
const bool transposed,
FiniteLines2& lines,
const unsigned int minimalStartThreshold,
const unsigned int minimalIntermediateThreshold,
const unsigned int minimalLength = 20u,
const float maximalStraightLineDistance = 1.6f,
EdgeTypes* types =
nullptr);
708 template <
typename T>
709 static void extractHorizontalLines(T*
const responses,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
FiniteLines2& lines,
const unsigned int minimalStartThreshold,
const unsigned int minimalIntermediateThreshold,
const unsigned int minimalLength = 20u,
const float maximalStraightLineDistance = 1.6f,
EdgeTypes* types =
nullptr);
739 template <
typename T, const
bool tPositiveThreshold, const
int tVerticalDirection>
740 static unsigned int followEdgeVertical(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsX,
const unsigned int paddingElements);
761 template <
typename T, const
bool tPositiveThreshold, const
int tHorizontalDirection>
762 static unsigned int followEdgeHorizontal(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsY,
const unsigned int paddingElements);
781 template <
typename T, const
bool tPositiveThreshold, const
int tVerticalDirection>
782 static unsigned int followEdgeVerticalBranchFree(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsX,
const unsigned int paddingElements);
795 static void separateStraightLines(
const unsigned int* pixelPositionsMajor,
const unsigned int firstPositionIndex,
const unsigned int lastPositionIndex,
FiniteLines2& lines,
const unsigned int minimalLength,
const float maximalOffset,
const bool majorIsY,
const bool refine);
816 static bool detectLines(
const uint8_t*
const yFrame,
Memory& yFrameTransposedMemory,
const unsigned int width,
const unsigned int height,
const unsigned int yFramePaddingElements,
unsigned int& yFrameTransposedMemoryPaddingElements,
const EdgeDetector& edgeDetector,
FiniteLines2& detectedLines,
const ScanDirection scanDirection,
const unsigned int threshold = 50u, int16_t* reusableResponseBuffer =
nullptr,
const unsigned int minimalLength = 20u,
const float maximalStraightLineDistance = 1.6f,
EdgeTypes* types =
nullptr);
826 template <
typename T, const
bool tPositiveThreshold>
827 static inline bool valueMatchesThreshold(
const T& value,
const T& threshold);
833 static constexpr
unsigned int barDetectorMinimalDelta();
866 return threshold * threshold;
871 return {std::make_shared<RMSBarEdgeDetectorI>(window, minimalDelta)};
888 return threshold * threshold;
893 return {std::make_shared<RMSStepEdgeDetectorI>(window)};
923 return {std::make_shared<ADBarEdgeDetectorI>(window)};
928 return {std::make_shared<SDStepEdgeDetectorI>(window, stepSize)};
933 return {std::make_shared<RMSBarEdgeDetectorI>(window,
barDetectorMinimalDelta()), std::make_shared<RMSStepEdgeDetectorI>(window)};
938 return {std::make_shared<ADBarEdgeDetectorI>(window), std::make_shared<SDStepEdgeDetectorI>(window)};
941 template <
typename T>
942 void LineDetectorULF::extractVerticalLines(T*
const responses,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
const bool transposed,
FiniteLines2& lines,
const unsigned int minimalStartThreshold,
const unsigned int minimalIntermediateThreshold,
const unsigned int minimalLength,
const float maximalStraightLineDistance,
EdgeTypes* types)
944 ocean_assert(responses !=
nullptr);
945 ocean_assert(width != 0u && height != 0u);
947 ocean_assert(minimalStartThreshold >= minimalIntermediateThreshold);
948 ocean_assert(minimalStartThreshold >= 0u && minimalIntermediateThreshold >= 0u);
952 ocean_assert(maximalStraightLineDistance >= 0.0f);
954 ocean_assert(types ==
nullptr || types->size() == lines.size());
956 Memory memoryPixelPositionsX = Memory::create<unsigned int>(height);
957 unsigned int* pixelPositionsX = memoryPixelPositionsX.
data<
unsigned int>();
959 const T* responsePixel = responses;
961 for (
unsigned int y = 0u; y < height; ++y)
963 for (
unsigned int x = 0u; x < width; ++x)
965 if ((
unsigned int)abs(*responsePixel) >= minimalStartThreshold)
967 unsigned int firstValidPixelPosition = y;
968 unsigned int lastValidPixelPosition = y;
972 if (*responsePixel >= T(minimalStartThreshold))
974 constexpr
bool positiveThreshold =
true;
976 lastValidPixelPosition = LineDetectorULF::followEdgeVertical<T, positiveThreshold, 1>(responses, width, height, x, y, T(minimalIntermediateThreshold), pixelPositionsX, paddingElements);
977 firstValidPixelPosition =
LineDetectorULF::followEdgeVertical<T, positiveThreshold, -1>(responses, width, height, x, y, T(minimalIntermediateThreshold), pixelPositionsX, paddingElements);
979 else if (*responsePixel <= -T(minimalStartThreshold))
981 constexpr
bool positiveThreshold =
false;
983 lastValidPixelPosition = LineDetectorULF::followEdgeVertical<T, positiveThreshold, 1>(responses, width, height, x, y, -T(minimalIntermediateThreshold), pixelPositionsX, paddingElements);
984 firstValidPixelPosition =
LineDetectorULF::followEdgeVertical<T, positiveThreshold, -1>(responses, width, height, x, y, -T(minimalIntermediateThreshold), pixelPositionsX, paddingElements);
987 ocean_assert(lastValidPixelPosition >= firstValidPixelPosition);
988 const unsigned int length = lastValidPixelPosition - firstValidPixelPosition + 1u;
990 if (length > minimalLength)
992 const size_t previousNumberLines = lines.size();
996 const size_t numberNewLines = lines.size() - previousNumberLines;
998 if (types && numberNewLines > 0)
1001 types->insert(types->end(), numberNewLines, edgeTypeSign);
1009 responsePixel += paddingElements;
1013 template <
typename T>
1014 void LineDetectorULF::extractHorizontalLines(T*
const responses,
const unsigned int width,
const unsigned int height,
const unsigned int paddingElements,
FiniteLines2& lines,
const unsigned int minimalStartThreshold,
const unsigned int minimalIntermediateThreshold,
const unsigned int minimalLength,
const float maximalStraightLineDistance,
EdgeTypes* types)
1016 ocean_assert(responses !=
nullptr);
1017 ocean_assert(width != 0u && height != 0u);
1019 ocean_assert(minimalStartThreshold >= minimalIntermediateThreshold);
1020 ocean_assert(minimalStartThreshold >= 0u && minimalIntermediateThreshold >= 0u);
1024 ocean_assert(maximalStraightLineDistance >= 0.0f);
1026 ocean_assert(types ==
nullptr || types->size() == lines.size());
1028 Memory memoryPixelPositionsY = Memory::create<unsigned int>(width);
1029 unsigned int* pixelPositionsY = memoryPixelPositionsY.
data<
unsigned int>();
1031 const T* responsePixel = responses;
1033 for (
unsigned int y = 0u; y < height; ++y)
1035 for (
unsigned int x = 0u; x < width; ++x)
1037 if ((
unsigned int)abs(*responsePixel) >= minimalStartThreshold)
1039 unsigned int firstValidPixelPosition = x;
1040 unsigned int lastValidPixelPosition = x;
1044 if (*responsePixel >= T(minimalStartThreshold))
1046 constexpr
bool positiveThreshold =
true;
1048 lastValidPixelPosition = LineDetectorULF::followEdgeHorizontal<T, positiveThreshold, 1>(responses, width, height, x, y, T(minimalIntermediateThreshold), pixelPositionsY, paddingElements);
1049 firstValidPixelPosition =
LineDetectorULF::followEdgeHorizontal<T, positiveThreshold, -1>(responses, width, height, x, y, T(minimalIntermediateThreshold), pixelPositionsY, paddingElements);
1051 else if (*responsePixel <= -T(minimalStartThreshold))
1053 constexpr
bool positiveThreshold =
false;
1055 lastValidPixelPosition = LineDetectorULF::followEdgeHorizontal<T, positiveThreshold, 1>(responses, width, height, x, y, -T(minimalIntermediateThreshold), pixelPositionsY, paddingElements);
1056 firstValidPixelPosition =
LineDetectorULF::followEdgeHorizontal<T, positiveThreshold, -1>(responses, width, height, x, y, -T(minimalIntermediateThreshold), pixelPositionsY, paddingElements);
1059 ocean_assert(lastValidPixelPosition >= firstValidPixelPosition);
1060 const unsigned int length = lastValidPixelPosition - firstValidPixelPosition + 1u;
1062 if (length > minimalLength)
1064 const size_t previousNumberLines = lines.size();
1068 const size_t numberNewLines = lines.size() - previousNumberLines;
1070 if (types && numberNewLines > 0)
1073 types->insert(types->end(), numberNewLines, edgeTypeSign);
1081 responsePixel += paddingElements;
1085 template <
typename T, const
bool tPositiveThreshold, const
int tVerticalDirection>
1086 unsigned int LineDetectorULF::followEdgeVertical(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsX,
const unsigned int paddingElements)
1088 static_assert(tVerticalDirection == 1 || tVerticalDirection == -1,
"Invalid direction value!");
1090 ocean_assert(data !=
nullptr);
1091 ocean_assert(x < width && y < height);
1092 ocean_assert(threshold != T(0));
1093 ocean_assert(pixelPositionsX !=
nullptr);
1095 const unsigned int dataStrideElements = width + paddingElements;
1097 data += y * dataStrideElements + x;
1100 pixelPositionsX[y] = x;
1102 unsigned int nextX = x;
1103 unsigned int nextY = (
unsigned int)(
int(y) + tVerticalDirection);
1105 data += tVerticalDirection * int(dataStrideElements);
1107 while (nextY < height)
1109 ocean_assert(nextX < width);
1111 T bestValue = threshold;
1115 if (nextX < width - 1u && valueMatchesThreshold<T, tPositiveThreshold>(*(data + 1), threshold ))
1117 bestValue = *(data + 1);
1122 if (nextX >= 1u && valueMatchesThreshold<T, tPositiveThreshold>(*(data - 1), bestValue))
1124 bestValue = *(data - 1);
1129 if (valueMatchesThreshold<T, tPositiveThreshold>(*data, bestValue))
1143 nextX += bestOffset;
1144 pixelPositionsX[nextY] = nextX;
1146 data += tVerticalDirection * int(dataStrideElements);
1148 nextY = (
unsigned int)(
int(nextY) + tVerticalDirection);
1151 ocean_assert(pixelPositionsX[
int(nextY) - tVerticalDirection] < width);
1153 ocean_assert((
unsigned int)(
int(nextY) - tVerticalDirection) < height);
1156 return (
unsigned int)(int(nextY) - tVerticalDirection);
1159 template <
typename T, const
bool tPositiveThreshold, const
int tHorizontalDirection>
1160 unsigned int LineDetectorULF::followEdgeHorizontal(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsY,
const unsigned int paddingElements)
1162 static_assert(tHorizontalDirection == 1 || tHorizontalDirection == -1,
"Invalid direction value!");
1164 ocean_assert(data !=
nullptr);
1165 ocean_assert(x < width && y < height);
1166 ocean_assert(threshold != T(0));
1167 ocean_assert(pixelPositionsY !=
nullptr);
1169 const unsigned int dataStrideElements = width + paddingElements;
1171 data += y * dataStrideElements + x;
1174 pixelPositionsY[x] = y;
1176 unsigned int nextX = (
unsigned int)(
int(x) + tHorizontalDirection);
1177 unsigned int nextY = y;
1179 data += tHorizontalDirection;
1181 while (nextX < width)
1183 ocean_assert(nextY < height);
1185 T bestValue = threshold;
1189 if (nextY < height - 1u && valueMatchesThreshold<T, tPositiveThreshold>(*(data + dataStrideElements), threshold ))
1191 bestValue = *(data + dataStrideElements);
1196 if (nextY >= 1u && valueMatchesThreshold<T, tPositiveThreshold>(*(data - dataStrideElements), bestValue))
1198 bestValue = *(data - dataStrideElements);
1203 if (valueMatchesThreshold<T, tPositiveThreshold>(*data, bestValue))
1214 data += bestOffset * int(dataStrideElements);
1217 nextY += bestOffset;
1218 pixelPositionsY[nextX] = nextY;
1220 data += tHorizontalDirection;
1222 nextX = (
unsigned int)(
int(nextX) + tHorizontalDirection);
1225 ocean_assert(pixelPositionsY[
int(nextX) - tHorizontalDirection] < height);
1227 ocean_assert((
unsigned int)(
int(nextX) - tHorizontalDirection) < width);
1230 return (
unsigned int)(int(nextX) - tHorizontalDirection);
1233 template <
typename T, const
bool tPositiveThreshold, const
int tVerticalDirection>
1234 unsigned int LineDetectorULF::followEdgeVerticalBranchFree(T* data,
const unsigned int width,
const unsigned int height,
const unsigned int x,
const unsigned int y,
const T& threshold,
unsigned int* pixelPositionsX,
const unsigned int paddingElements)
1236 static_assert(tVerticalDirection == 1 || tVerticalDirection == -1,
"Invalid direction value!");
1238 ocean_assert(data !=
nullptr);
1239 ocean_assert(x < width && y < height);
1240 ocean_assert(threshold != T(0));
1241 ocean_assert(pixelPositionsX !=
nullptr);
1243 const unsigned int dataStrideElements = width + paddingElements;
1245 data += y * dataStrideElements + x;
1248 pixelPositionsX[y] = x;
1250 const int intThreshold = int(threshold);
1252 unsigned int nextX = x;
1253 unsigned int nextY = (
unsigned int)(
int(y) + tVerticalDirection);
1255 data += tVerticalDirection * int(dataStrideElements);
1257 while (nextY < height)
1259 ocean_assert(nextX < width);
1261 const int leftOrCenterValue = *(data - int(nextX - 1u < width));
1262 const int centerValue = *data;
1263 const int rightOrCenterValue = *(data + int(nextX < width - 1u));
1268 ocean_assert(leftOrCenterValue == *(data - 1));
1270 ocean_assert(leftOrCenterValue == *data);
1272 if (nextX + 1u < width)
1273 ocean_assert(rightOrCenterValue == *(data + 1));
1275 ocean_assert(rightOrCenterValue == *data);
1282 const int useCenterValue = tPositiveThreshold ? (centerValue >= intThreshold && centerValue >= leftOrCenterValue && centerValue >= rightOrCenterValue) : centerValue <= intThreshold && centerValue <= leftOrCenterValue && centerValue <= rightOrCenterValue;
1283 ocean_assert(useCenterValue == 0 || useCenterValue == 1);
1286 const int useRightValue = tPositiveThreshold ? (rightOrCenterValue >= intThreshold && rightOrCenterValue > centerValue && rightOrCenterValue > leftOrCenterValue) : (rightOrCenterValue <= intThreshold && rightOrCenterValue < centerValue && rightOrCenterValue < leftOrCenterValue);
1287 ocean_assert(useRightValue == 0 || useRightValue == 1);
1290 const int useLeftValue = tPositiveThreshold ? (leftOrCenterValue >= intThreshold && leftOrCenterValue > centerValue && leftOrCenterValue >= rightOrCenterValue) : (leftOrCenterValue <= intThreshold && leftOrCenterValue < centerValue && leftOrCenterValue <= rightOrCenterValue);
1291 ocean_assert(useLeftValue == 0 || useLeftValue == 1);
1293 ocean_assert(useCenterValue + useLeftValue + useRightValue == 0 || useCenterValue + useLeftValue + useRightValue == 1);
1295 const int useNoValue = 1 - useCenterValue - useLeftValue - useRightValue;
1296 ocean_assert(useNoValue == 0 || useNoValue == 1);
1298 if (useNoValue != 0)
1304 ocean_assert(useLeftValue == 0);
1305 ocean_assert(useCenterValue == 0);
1306 ocean_assert(useRightValue == 0);
1308 if constexpr (tPositiveThreshold)
1310 ocean_assert(*data < intThreshold);
1311 ocean_assert(nextX == 0u || *(data - 1) < intThreshold);
1312 ocean_assert(nextX + 1u >= width || *(data + 1) < intThreshold);
1316 ocean_assert(*data > intThreshold);
1317 ocean_assert(nextX == 0u || *(data - 1) > intThreshold);
1318 ocean_assert(nextX + 1u >= width || *(data + 1) > intThreshold);
1326 const int nextOffsetX = -useLeftValue + useRightValue;
1330 if (useNoValue == 0)
1334 if (nextOffsetX == -1)
1336 ocean_assert(useLeftValue == 1);
1337 ocean_assert(nextX >= 1u);
1339 if constexpr (tPositiveThreshold)
1341 ocean_assert(*(data - 1) >= intThreshold);
1342 ocean_assert(*(data - 1) > *data);
1343 ocean_assert(nextX + 1u >= width || *(data - 1) >= *(data + 1));
1347 ocean_assert(*(data - 1) <= intThreshold);
1348 ocean_assert(*(data - 1) < *data);
1349 ocean_assert(nextX + 1u >= width || *(data - 1) <= *(data + 1));
1352 else if (nextOffsetX == 0)
1354 ocean_assert(useCenterValue == 1);
1356 if constexpr (tPositiveThreshold)
1358 ocean_assert(*data >= intThreshold);
1359 ocean_assert(nextX >= 1u || *data >= *(data - 1));
1360 ocean_assert(nextX + 1u >= width || *data >= *(data + 1));
1364 ocean_assert(*data <= intThreshold);
1365 ocean_assert(nextX >= 1u || *data <= *(data - 1));
1366 ocean_assert(nextX + 1u >= width || *data <= *(data + 1));
1371 ocean_assert(nextOffsetX == 1);
1373 ocean_assert(useRightValue == 1);
1374 ocean_assert(nextX + 1u < width);
1376 if constexpr (tPositiveThreshold)
1378 ocean_assert(*(data + 1) >= intThreshold);
1379 ocean_assert(*(data + 1) > *data);
1380 ocean_assert(nextX == 0u || *(data + 1) > *(data - 1));
1384 ocean_assert(*(data + 1) <= intThreshold);
1385 ocean_assert(*(data + 1) < *data);
1386 ocean_assert(nextX == 0u || *(data + 1) < *(data - 1));
1390 ocean_assert(
int(nextX) + nextOffsetX >= 0 && nextX + nextOffsetX <
int(width));
1395 data += nextOffsetX;
1398 nextX += nextOffsetX;
1399 pixelPositionsX[nextY] = nextX;
1401 data += tVerticalDirection * int(dataStrideElements);
1403 nextY += tVerticalDirection;
1406 ocean_assert(pixelPositionsX[
int(nextY) - tVerticalDirection] < width);
1409 return (
unsigned int)(int(nextY) - tVerticalDirection);
1412 template <
typename T, const
bool tPositiveThreshold>
1415 if constexpr (tPositiveThreshold)
1417 return value >= threshold;
1421 return value <= threshold;
This class implements an integer-based bar edge detector based on averaged differences.
Definition: LineDetectorULF.h:502
static EdgeDetectors asEdgeDetectors(const unsigned int window=4u)
Returns a vector containing just this edge detector with shared pointer (to simplify the usage with d...
Definition: LineDetectorULF.h:921
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int framePaddingElements) const override
Invokes the vertical edge detection for the entire frame.
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int window, const uint32_t *const windowSums, int16_t *responses)
Invokes the vertical edge detection in one row of the input frame.
static unsigned int staticAdjustThreshold(const unsigned int threshold)
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
Definition: LineDetectorULF.h:916
ADBarEdgeDetectorI(const unsigned int window=4u)
Create a new edge detector object.
This class implements the almost abstract base class for all edge detectors.
Definition: LineDetectorULF.h:81
static void determineRowSums(const uint8_t *row, const unsigned int width, const unsigned int window, uint32_t *windowSums)
Determines the sums of pixel intensities of sliding windows within a row of a frame.
virtual ~EdgeDetector()=default
Destructor of an edge detector.
static void determineRowSums(const uint8_t *row, const unsigned int width, const unsigned int window, uint32_t *windowSums, uint32_t *windowSqrSums)
Determines the sums of pixel intensities (and sums of squared pixel intensities) of sliding windows w...
virtual void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const =0
Invokes the vertical edge detection for the entire frame.
EdgeType edgeType() const
Returns the type of the edges this detector detects.
Definition: LineDetectorULF.h:849
virtual unsigned int adjustThreshold(const unsigned int threshold) const
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
const EdgeType edgeType_
Definition: LineDetectorULF.h:217
static void applyRowSum(const uint8_t *row, const unsigned int width, uint16_t *sum)
Either adds or subtracts one row from the sum and square sum buffers.
const unsigned int window_
The width of the sliding window in pixel, with range [1, infinity)
Definition: LineDetectorULF.h:214
EdgeDetector(const unsigned int window, const EdgeType edgeType)
Protected default constructor.
Definition: LineDetectorULF.h:837
virtual bool hasInvokeHorizontal(const unsigned int width, const unsigned int height) const
Returns whether this EdgeDetector object has an implementation for invokeHorizontal().
virtual bool invokeHorizontal(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const
Invokes the horizontal edge detection for the entire frame.
static void applyRowSum(const uint8_t *row, const unsigned int width, uint16_t *sum, uint32_t *sqrSum)
Either adds or subtracts one row from the sum and square sum buffers.
static void determineRowSums(const uint8_t *row, const unsigned int width, const unsigned int window, uint16_t *windowSums, uint32_t *windowSqrSums)
Determines the sums of pixel intensities (and sums of squared pixel intensities) of sliding windows w...
static void determineRowSums(const uint8_t *row, const unsigned int width, const unsigned int window, uint16_t *windowSums)
Determines the sums of pixel intensities of sliding windows within a row of a frame.
unsigned int window() const
Returns the width of the sliding window in pixel, with range [1, infinity)
Definition: LineDetectorULF.h:844
This class implements a floating-point-based bar edge detector based on root mean square residuals.
Definition: LineDetectorULF.h:407
static unsigned int staticAdjustThreshold(const unsigned int threshold)
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
Definition: LineDetectorULF.h:896
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int window, const unsigned int minimalDelta, const uint32_t *const windowSums, const uint32_t *const windowSqrSums, int16_t *sqrResponses)
Invokes the vertical edge detection in one row of the input frame.
RMSBarEdgeDetectorF(const unsigned int window=4u, const unsigned int minimalDelta=barDetectorMinimalDelta())
Create a new edge detector object.
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const override
Invokes the vertical edge detection for the entire frame.
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
const unsigned int minimalDelta_
The minimal intensity delta between average and center pixel, with range [0, 255].
Definition: LineDetectorULF.h:451
This class implements an integer-based bar edge detector based on root mean square residuals.
Definition: LineDetectorULF.h:230
bool hasInvokeHorizontal(const unsigned int width, const unsigned int height) const override
Returns whether this EdgeDetector object has an implementation for invokeHorizontal().
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int framePaddingElements) const override
Invokes the vertical edge detection for the entire frame.
RMSBarEdgeDetectorI(const unsigned int window=4u, const unsigned int minimalDelta=barDetectorMinimalDelta())
Create a new edge detector object.
bool invokeHorizontal(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const override
Invokes the horizontal edge detection for the entire frame.
static EdgeDetectors asEdgeDetectors(const unsigned int window=4u, const unsigned int minimalDelta=barDetectorMinimalDelta())
Returns a vector containing just this edge detector with shared pointer (to simplify the usage with d...
Definition: LineDetectorULF.h:869
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int window, const unsigned int minimalDelta, const uint16_t *const windowSums, const uint32_t *const windowSqrSums, int16_t *sqrResponses)
Invokes the vertical edge detection in one row of the input frame.
const unsigned int minimalDelta_
The minimal intensity delta between average and center pixel, with range [0, 255].
Definition: LineDetectorULF.h:312
static unsigned int staticAdjustThreshold(const unsigned int threshold)
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
Definition: LineDetectorULF.h:854
This class implements a floating-point-based bar step detector based on root mean square residuals.
Definition: LineDetectorULF.h:458
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int window, const uint32_t *const windowSums, const uint32_t *const windowSqrSums, int16_t *sqrResponses)
Invokes the vertical edge detection in one row of the input frame.
static unsigned int staticAdjustThreshold(const unsigned int threshold)
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
Definition: LineDetectorULF.h:906
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const override
Invokes the vertical edge detection for the entire frame.
RMSStepEdgeDetectorF(const unsigned int window=4u)
Create a new edge detector object.
This class implements an integer-based bar step detector based on root mean square residuals.
Definition: LineDetectorULF.h:319
static unsigned int staticAdjustThreshold(const unsigned int threshold)
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
Definition: LineDetectorULF.h:874
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int framePaddingElements) const override
Invokes the vertical edge detection for the entire frame.
bool hasInvokeHorizontal(const unsigned int width, const unsigned int height) const override
Returns whether this EdgeDetector object has an implementation for invokeHorizontal().
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
bool invokeHorizontal(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const override
Invokes the horizontal edge detection for the entire frame.
static EdgeDetectors asEdgeDetectors(const unsigned int window=4u)
Returns a vector containing just this edge detector with shared pointer (to simplify the usage with d...
Definition: LineDetectorULF.h:891
RMSStepEdgeDetectorI(const unsigned int window=4u)
Create a new edge detector object.
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int window, const uint16_t *const windowSums, const uint32_t *const windowSqrSums, int16_t *sqrResponses)
Invokes the vertical edge detection in one row of the input frame.
This class implements an integer-based (sum difference) step edge detector that computes the differen...
Definition: LineDetectorULF.h:561
const unsigned int stepSize_
The number of pixels between both windows sums, "should be odd", "should" have range [1,...
Definition: LineDetectorULF.h:625
void invokeVertical(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int framePaddingElements) const override
Invokes the vertical edge detection for the entire frame.
bool hasInvokeHorizontal(const unsigned int width, const unsigned int height) const override
Returns whether this EdgeDetector object has an implementation for invokeHorizontal().
static void invokeRowVertical(const uint8_t *const row, const unsigned int width, const unsigned int stepSize, const unsigned int window, const uint16_t *const windowSums, int16_t *responses)
Invokes the vertical edge detection in one row of the input image with a fixed window width of 2 pixe...
bool invokeHorizontal(const uint8_t *frame, const unsigned int width, const unsigned int height, int16_t *responses, const unsigned int paddingElements) const override
Invokes the horizontal edge detection for the entire frame.
SDStepEdgeDetectorI(const unsigned int window=2u, const unsigned int stepSize=1u)
Create a new edge detector object.
unsigned int adjustThreshold(const unsigned int threshold) const override
Adjusts the edge detection threshold (which is specified independently of the applied edge detection ...
static EdgeDetectors asEdgeDetectors(const unsigned int window=2u, const unsigned int stepSize=1u)
Returns a vector containing just this edge detector with shared pointer (to simplify the usage with d...
Definition: LineDetectorULF.h:926
This class implements a line detector optimized for urban lines (Urban Line Finder).
Definition: LineDetectorULF.h:34
ScanDirection
Definition of scan direction of the line detection.
Definition: LineDetectorULF.h:60
static FiniteLines2 detectLines(const uint8_t *yFrame, const unsigned int width, const unsigned int height, const unsigned int framePaddingElements, const EdgeDetectors &edgeDetectors=defaultEdgeDetectors(), const unsigned int threshold=50u, const unsigned int minimalLength=20u, const float maximalStraightLineDistance=1.6f, EdgeTypes *types=nullptr, const ScanDirection scanDirection=SD_VERTICAL_AND_HORIZONTAL)
Detects finite lines within a given 8bit grayscale image.
std::vector< EdgeType > EdgeTypes
Definition of a vector holding edge types.
Definition: LineDetectorULF.h:72
static void separateStraightLines(const unsigned int *pixelPositionsMajor, const unsigned int firstPositionIndex, const unsigned int lastPositionIndex, FiniteLines2 &lines, const unsigned int minimalLength, const float maximalOffset, const bool majorIsY, const bool refine)
Separates a set of connected pixels (almost defining a straight line) into individual perfect straigh...
static unsigned int followEdgeHorizontal(T *data, const unsigned int width, const unsigned int height, const unsigned int x, const unsigned int y, const T &threshold, unsigned int *pixelPositionsY, const unsigned int paddingElements)
Follows an edge in horizontal direction while applying a vertical search radius with one pixel (-1,...
Definition: LineDetectorULF.h:1160
static constexpr unsigned int barDetectorMinimalDelta()
The threshold for the minimal delta for bar detectors.
Definition: LineDetectorULF.h:1425
static bool valueMatchesThreshold(const T &value, const T &threshold)
Returns whether a given value is larger than or equal to a given threshold (or smaller than or equal ...
Definition: LineDetectorULF.h:1413
static EdgeDetectors performanceEdgeDetectors(const unsigned int window=4u)
Returns ULF's two high performance edge detectors.
Definition: LineDetectorULF.h:936
EdgeType
Definition of individual edge types.
Definition: LineDetectorULF.h:41
@ ET_SIGN_NEGATIVE
Negative sign edge; e.g., a dark bar edge.
Definition: LineDetectorULF.h:51
@ ET_SIGN_POSITIVE
Positive sign edge; e.g., a bright bar edge.
Definition: LineDetectorULF.h:49
static void extractVerticalLines(T *const responses, const unsigned int width, const unsigned int height, const unsigned int paddingElements, const bool transposed, FiniteLines2 &lines, const unsigned int minimalStartThreshold, const unsigned int minimalIntermediateThreshold, const unsigned int minimalLength=20u, const float maximalStraightLineDistance=1.6f, EdgeTypes *types=nullptr)
Extracts straight vertical (+/- 45 degree) finite lines from a given frame with edge responses.
Definition: LineDetectorULF.h:942
static bool detectLines(const uint8_t *const yFrame, Memory &yFrameTransposedMemory, const unsigned int width, const unsigned int height, const unsigned int yFramePaddingElements, unsigned int &yFrameTransposedMemoryPaddingElements, const EdgeDetector &edgeDetector, FiniteLines2 &detectedLines, const ScanDirection scanDirection, const unsigned int threshold=50u, int16_t *reusableResponseBuffer=nullptr, const unsigned int minimalLength=20u, const float maximalStraightLineDistance=1.6f, EdgeTypes *types=nullptr)
Detects lines by applying a given edge detector for an image in horizontal and vertical direction.
static unsigned int followEdgeVertical(T *data, const unsigned int width, const unsigned int height, const unsigned int x, const unsigned int y, const T &threshold, unsigned int *pixelPositionsX, const unsigned int paddingElements)
Follows an edge in vertical direction while applying a horizontal search radius with one pixel (-1,...
Definition: LineDetectorULF.h:1086
static unsigned int followEdgeVerticalBranchFree(T *data, const unsigned int width, const unsigned int height, const unsigned int x, const unsigned int y, const T &threshold, unsigned int *pixelPositionsX, const unsigned int paddingElements)
Follows an edge in vertical direction while applying a horizontal search radius with one pixel (-1,...
Definition: LineDetectorULF.h:1234
static void extractHorizontalLines(T *const responses, const unsigned int width, const unsigned int height, const unsigned int paddingElements, FiniteLines2 &lines, const unsigned int minimalStartThreshold, const unsigned int minimalIntermediateThreshold, const unsigned int minimalLength=20u, const float maximalStraightLineDistance=1.6f, EdgeTypes *types=nullptr)
Extracts straight horizontal (+/- 45 degree) finite lines from a given frame with edge responses.
Definition: LineDetectorULF.h:1014
static EdgeDetectors defaultEdgeDetectors(const unsigned int window=4u)
Returns ULF's two default edge detectors.
Definition: LineDetectorULF.h:931
std::vector< std::shared_ptr< EdgeDetector > > EdgeDetectors
Definition of a vector holding edge detectors.
Definition: LineDetectorULF.h:223
This class implements an object able to allocate memory.
Definition: base/Memory.h:22
void * data()
Returns the pointer to the writable memory which is allocated by this object.
Definition: base/Memory.h:303
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition: FiniteLine2.h:57
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15