Ocean
Loading...
Searching...
No Matches
BarcodeDetector2D.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#pragma once
9
12
13#include "ocean/base/DataType.h"
14#include "ocean/base/Worker.h"
15
17
19#include "ocean/math/Line2.h"
20
21namespace Ocean
22{
23
24namespace CV
25{
26
27namespace Detector
28{
29
30namespace Barcodes
31{
32
33/**
34 * This class converts raw pixel data into binary segments.
35 *
36 * The process starts by searching for an intensity jump from background intensity to foreground intensity values.
37 * Once a transition has been found, it will determine a gray value that's used to threshold the following pixels.
38 * When requested, the segmenter can prepare the N segments in advance. Once done, the segmenter will advance to
39 * the next intensity jump. This process continues until all raw pixels have been processed.
40 *
41 * Suggested use:
42 * <pre>
43 * const bool isNormalReflectance = ...;
44 * const uint8_t gradientThreshold = 20u;
45 * const uint8_t* buffer = ...;
46 * const size_t bufferSize = ...;
47 *
48 * RowSegmenter rowSegmenter(buffer, bufferSize, gradientThreshold, isNormalReflectance);
49 *
50 * while (rowSegmenter.findNextTransitionToForeground())
51 * {
52 * rowSegmenter.prepareSegments(maxNumberRequiredSegments);
53 *
54 * if (rowSegmenter.size() < minNumberRequiredSegments)
55 * {
56 * // There aren't enough segments.
57 * continue;
58 * }
59 *
60 * // work with the segments ...
61 * }
62 * </pre>
63 * @ingroup cvdetectorbarcodes
64 * @tparam TPixel The type of the raw pixels that will be processed, e.g. `uint8_t`.
65 */
66template <typename TPixel>
68{
69 public:
70
71 // The type that is used for the image gradient.
73
74 protected:
75
76 /**
77 * This class implements a simple history for previous pixel transitions (a sliding window of pixel transitions).
78 */
80 {
81 public:
82
83 /**
84 * Creates a new history object.
85 */
86 TransitionHistory() = default;
87
88 /**
89 * Returns the history with window size N.
90 * @return The sum of the most recent delta
91 */
92 inline TGradient history1();
93
94 /**
95 * Returns the history with window size N.
96 * @return The sum of the most recent delta
97 */
98 inline TGradient history2();
99
100 /**
101 * Returns the history with window size N.
102 * @return The sum of the most recent delta
103 */
104 inline TGradient history3();
105
106 /**
107 * Adds a new delta object as most recent history.
108 * Existing history objects will be moved by one pixel.
109 * @param newDelta The new delta object to be added
110 */
111 inline void push(const TGradient newDelta);
112
113 /**
114 * Resets the history object.
115 */
116 inline void reset();
117
118 protected:
119
120 /// The most recent deltas.
121 TGradient deltas_[3] = {0, 0, 0};
122 };
123
124 /// Definition of a function pointer for function that determine intensity transitions between back- and foreground pixels.
125 typedef bool (*IsTransitionFunc)(const TPixel*, const TGradient, TransitionHistory&);
126
127 public:
128
129 /**
130 * Creates a segmenter object for a buffer of raw pixel data.
131 * @param pixelData The pointer to the raw pixel data that will be processed, must be valid
132 * @param pixelDataSize The size of the raw pixel data, range: [1, infinity)
133 * @param minimumGradient The minimum value of the pixel gradient required to count as a transition, range: (-infinity, infinity)
134 * @param isNormalReflectance Indicates whether the segmenter should look for transitions with normal or inverted reflectance
135 */
136 RowSegmenter(const TPixel* pixelData, const size_t pixelDataSize, const TGradient minimumGradient, const bool isNormalReflectance);
137
138 /**
139 * Returns if this segmenter is valid
140 * @return True if this segmenter is valid, otherwise false
141 */
142 bool isValid() const;
143
144 /**
145 * Finds the next transition from background to foreground in the raw pixel data
146 * @return True if a transition has been found, otherwise false
147 */
149
150 /**
151 * Prepares a batch of segments
152 * @note: Calling this function without having `findNextTransitionToForeground()` first (with `true` as return value) results in undefined behavior!
153 * @param numberSegments The number of segments that should be prepared, range: (1, infinity)
154 * @return True if the number of requested segments are available, otherwise false
155 */
156 bool prepareSegments(const size_t numberSegments);
157
158 /**
159 * Returns the current segment data
160 * @return The current segment data
161 */
162 const SegmentData& segmentData() const;
163
164 /**
165 * Returns the size of the raw pixel data that is handled by this object
166 * @return The size of the raw pixel data in elements
167 */
168 size_t size() const;
169
170 /**
171 * Returns the current position of the segmenter in the raw pixel data
172 * @return The current position
173 */
174 size_t position() const;
175
176 /**
177 * Sets the position of the segmenter in the raw pixel data
178 * @param position The index position to where the segmenter should be set, range: [0, size())
179 */
180 bool setPosition(const size_t position);
181
182 protected:
183
184 /**
185 * Checks if the specified pixel is a transition from light to dark pixels
186 * @param pixel The pointer to the pixel that will be checked, must be valid
187 * @param minimumGradient The minimum value of the pixel gradient that must be exceed for it count as a intensity transition, range: (-infinity, infinity)
188 * @param history The object holding the recent pixel history, must be valid
189 */
190 static bool isTransitionLightToDark(const TPixel* pixel, const TGradient minimumGradient, TransitionHistory& history);
191
192 /**
193 * Checks if the specified pixel is a transition from dark to light pixels
194 * @param pixel The pointer to the pixel that will be checked, must be valid
195 * @param minimumGradient The minimum value of the pixel gradient that must be exceed for it count as a intensity transition, range: (-infinity, infinity)
196 * @param history The object holding the recent pixel history, must be valid
197 */
198 static bool isTransitionDarkToLight(const TPixel* pixel, const TGradient minimumGradient, TransitionHistory& history);
199
200 protected:
201
202 /// A pointer to the function that checks if there is a transition from background to foreground (this depends on the reflectance type)
204
205 /// A pointer to the function that checks if there is a transition from foreground to background (this depends on the reflectance type)
207
208 /// The pointer to the raw pixel data that will be processed by this object.
209 const TPixel* pixelData_ = nullptr;
210
211 /// The size of the raw pixel data in elements.
212 size_t size_ = 0;
213
214 /// The minimum value of the pixel gradient that must be exceed for it count as a intensity transition.
216
217 /// The current position of the segmenter in the raw pixel data.
218 size_t position_ = 0;
219
220 /// The position of the segmenter in the raw pixel data when creating new segments (thresholding), this is `segmentPosition_ = position_ + X`
222
223 /// The memory holding the current segments
225
226 /// The object that holds the recent pixel history.
228};
229
230template <typename TPixel>
235
236template <typename TPixel>
238{
239 return deltas_[0] + deltas_[1];
240}
241
242template <typename TPixel>
244{
245 return deltas_[0] + deltas_[1] + deltas_[2];
246}
247
248template <typename TPixel>
250{
251 deltas_[2] = deltas_[1];
252 deltas_[1] = deltas_[0];
253 deltas_[0] = newDelta;
254}
255
256template <typename TPixel>
258{
259 deltas_[0] = 0;
260 deltas_[1] = 0;
261 deltas_[2] = 0;
262}
263
264template <typename TPixel>
265RowSegmenter<TPixel>::RowSegmenter(const TPixel* pixelData, const size_t pixelDataSize, const TGradient minimumGradient, const bool isNormalReflectance) :
266 pixelData_(pixelData),
267 size_(pixelDataSize),
268 minimumGradient_(minimumGradient)
269{
270 if (isNormalReflectance)
271 {
274 }
275 else
276 {
279 }
280
281 ocean_assert(isValid());
282}
283
284template <typename TPixel>
286{
287 return pixelData_ != nullptr && size_ != 0 && minimumGradient_ > TGradient(0) && isTransitionToForeground_ != nullptr && isTransitionToBackground_ != nullptr;
288}
289
290template <typename TPixel>
292{
293 if (!isValid())
294 {
295 return false;
296 }
297
298 // Delete any previous segments
299 segmentData_.clear();
300
301 transitionHistory_.reset();
302 ++position_;
303
304 ocean_assert(position_ != 0);
305
306 while (position_ < size_ && !isTransitionToForeground_(pixelData_ + position_, minimumGradient_, transitionHistory_))
307 {
308 ++position_;
309 }
310
311 if (position_ < size_)
312 {
313 segmentPosition_ = position_;
314
315 return true;
316 }
317
318 return false;
319}
320
321template <typename TPixel>
322bool RowSegmenter<TPixel>::prepareSegments(const size_t numberSegments)
323{
324 if (!isValid())
325 {
326 return false;
327 }
328
329 if (numberSegments <= segmentData_.size())
330 {
331 // There are sufficient segments already, no need to find additional ones
332 return true;
333 }
334
335#if 1
336 // Use a gray threshold to determine the next segments.
337
338 // Use the midpoint between the previous (background) and the current (foreground) pixel as gray threshold.
339 const TPixel grayThreshold_ = (pixelData_[position_ - 1] + pixelData_[position_]) / 2u;
340
341 while (segmentPosition_ < size_ && numberSegments > segmentData_.size())
342 {
343 const bool atForeground = segmentData_.size() % 2 == 0;
344
345 size_t nextSegmentPosition = segmentPosition_ + 1;
346
347 if (atForeground)
348 {
349 while (nextSegmentPosition < size_ && pixelData_[nextSegmentPosition] < grayThreshold_)
350 {
351 nextSegmentPosition++;
352 }
353 }
354 else
355 {
356 while (nextSegmentPosition < size_ && pixelData_[nextSegmentPosition] >= grayThreshold_)
357 {
358 nextSegmentPosition++;
359 }
360 }
361
362 ocean_assert(nextSegmentPosition >= segmentPosition_);
363 const uint32_t segmentSize = uint32_t(nextSegmentPosition - segmentPosition_); // nextSegmentPosition is the first element of the next segment, so no +1 necessary
364
365 if (segmentSize == 0)
366 {
367 return false;
368 }
369
370 segmentData_.emplace_back(segmentSize);
371 segmentPosition_ = nextSegmentPosition;
372 }
373#else
374 // Determine the next segments by searching for intensity transitions, i.e. locations where the gradient exceeds a certain threshold.
375
376 // Note: after experimentation, this seems to be easily affected by pixel noise. Using a longer transition history (smoothing) to reduce noise increases the minimum number of pixels per module.
377
378 while (segmentPosition_ < pixelDataSize_ && numberSegments > segmentData_.size())
379 {
380 // Segment data alternates between foreground and background data. The first element is a foreground segment.
381 const bool atForeground = segmentData_.size() % 2 == 0;
382
383 IsTransitionFunc isNextTransition = nullptr;
384
385 if (atForeground)
386 {
387 isNextTransition = isTransitionToBackground_;
388 }
389 else
390 {
391 isNextTransition = isTransitionToForeground_;
392 }
393
394 size_t nextSegmentPosition = segmentPosition_ + 1u;
395
396 while (nextSegmentPosition < pixelDataSize_ && !isNextTransition(pixelData_ + nextSegmentPosition, minimumGradient_, transitionHistory_))
397 {
398 ++nextSegmentPosition;
399 }
400
401 ocean_assert(nextSegmentPosition >= segmentPosition_);
402 const uint32_t segmentSize = uint32_t(nextSegmentPosition - segmentPosition_); // nextSegmentPosition is the first element of the next segment, so no +1 necessary
403
404 if (segmentSize == 0)
405 {
406 return false;
407 }
408
409 segmentData_.emplace_back(segmentSize);
410 segmentPosition_ = nextSegmentPosition;
411 }
412#endif
413
414 if (numberSegments <= segmentData_.size())
415 {
416 return true;
417 }
418
419 return false;
420}
421
422/**
423 * This class implements a detector for barcodes.
424 * @ingroup cvdetectorbarcodes
425 */
426class OCEAN_CV_DETECTOR_BARCODES_EXPORT BarcodeDetector2D
427{
428 public:
429
430 /**
431 * Definition of optional detection features.
432 * @note Enabling additional features will reduce the runtime performance of the detector.
433 */
434 enum DetectionFeatures : uint32_t
435 {
436 /// Standard features that should be sufficient for most cases (excluding all the cases below).
437 DF_STANDARD = 0u,
438 /// Enables additional scan line directions, i.e. besides horizontal lines, there will also be scan lines at 45, 90, and 135 degrees around the image center.
439 DF_ENABLE_MULTIPLE_SCANLINE_DIRECTIONS = 1u << 0u,
440 /// Enables the search for barcodes that use inverted reflectance.
441 DF_ENABLE_INVERTED_REFLECTANCE = 1u << 1u,
442 /// Enables the detection of barcodes which are mirrored (e.g. when held up-side-down).
443 DF_ENABLE_SCANLINE_MIRRORING = 1u << 2u,
444 /// Enable the detection of multiple codes, otherwise the detection will stop after the first detected barcode.
445 DF_ENABLE_MULTI_CODE_DETECTION = 1u << 3u,
446 /// Enable the detection of duplicate codes; this will also enable the detection of multiple codes.
447 DF_ENABLE_MULTI_CODE_DETECTION_WITH_DUPLICATES = 1u << 4u | DF_ENABLE_MULTI_CODE_DETECTION,
448 /// Enable all of the available extra features.
449 DF_ENABLE_EVERYTHING = 0xFFFFFFFFu
450 };
451
452 /**
453 * Definition of an observation of a barcode in 2D.
454 */
455 class OCEAN_CV_DETECTOR_BARCODES_EXPORT Observation
456 {
457 public:
458
459 /**
460 * Creates an invalid observation.
461 */
462 Observation() = default;
463
464 /**
465 * Create an observation from points.
466 */
467 Observation(const Vector2& startPoint, const Vector2& endPoint);
468
469 /**
470 * Returns the location of the observation.
471 * @return The location of the observation.
472 */
473 const FiniteLine2& location() const;
474
475 protected:
476
477 /// The location of the observation.
479 };
480
481 /// Definition of a vector of observations.
482 typedef std::vector<Observation> Observations;
483
484 /// Definition of a function pointer for parser functions which detect the actual barcodes.
485 typedef bool (*ParserFunction)(const uint32_t* segmentData, const size_t size, Barcode& barcode, IndexPair32& xCoordinates);
486
487 /// Definition of a set of parser functions.
488 typedef std::unordered_set<ParserFunction> ParserFunctionSet;
489
490 public:
491
492 /**
493 * Detects barcodes in an 8-bit grayscale image.
494 * @param yFrame The frame in which barcodes will be detected, must be valid, have its origin in the upper left corner, and have a pixel format that is compatible with Y8, minimum size is 70 x 70 pixels.
495 * @param detectionFeatures Optional flag to enable certain additional detection features.
496 * @param enabledBarcodeTypes A set of barcode types that will be detected; if empty, every supported barcode will be detected.
497 * @param scanlineSpacing The spacing between parallel scan lines in pixels, range: [1, infinity).
498 * @param observations Optional observations of the detected barcodes that will be returned, will be ignored if `nullptr`.
499 * @param scanlines Optionally resulting scan lines that were used during the detection, will be ignored if `nullptr`.
500 * @return The list of detected barcodes.
501 */
502 static Barcodes detectBarcodes(const Frame& yFrame, const uint32_t detectionFeatures = DF_STANDARD, const BarcodeTypeSet& enabledBarcodeTypes = BarcodeTypeSet(), const unsigned int scanlineSpacing = 25u, Observations* observations = nullptr, FiniteLines2* scanlines = nullptr);
503
504 protected:
505
506 /**
507 * Computes a vector pointing at a specific angle on a unit circle.
508 * @param angle The angle on the unit circle for which a corresponding vector is computed, range: [0, 2*PI].
509 * @param length The length that the resulting vector will have, range: (0, infinity).
510 * @return The vector
511 */
512 static Vector2 computeDirectionVector(const Scalar angle, const Scalar length = Scalar(1));
513
514 /**
515 * Computes the intersection points of a frame and an intersecting infinite line.
516 * @param frameWidth The width of the frame that is intersected by the infinite line, range: [1, infinity).
517 * @param frameHeight The height of the frame that is intersected by the infinite line, range: [1, infinity).
518 * @param frameBorder The border on the inside of the frame that should be enforced between the frame and the intersection points, range: [0, min(frameWidth, frameHeight) / 2).
519 * @param line The infinite line to intersect with the frame, must be valid.
520 * @param point0 The resulting first intersection point.
521 * @param point1 The resulting second intersection point.
522 * @return True if an intersection has been found, otherwise false.
523 */
524 static bool computeFrameIntersection(const unsigned int frameWidth, const unsigned frameHeight, const unsigned int frameBorder, const Line2& line, CV::PixelPositionI& point0, CV::PixelPositionI& point1);
525
526 /**
527 * Computes the locations of the scan lines for a given direction.
528 * The first scan line will intersect the frame center. All other scan lines will then be added alternatingly above and below the first scan line with increasing distance (`scanlineSpacing`) until they are outside the frame or below a minimum size.
529 * @param frameWidth The width of the frame that is intersected by the infinite line, range: [1, infinity).
530 * @param frameHeight The height of the frame that is intersected by the infinite line, range: [1, infinity).
531 * @param scanlineDirection The direction for which scan lines should be extracted, must be valid.
532 * @param scanlineSpacing The spacing between parallel scan lines in pixels, range: [1, infinity).
533 * @param frameBorder The border on the inside of the frame that should be enforced between the frame and the intersection points, range: [0, min(frameWidth, frameHeight) / 2).
534 * @param minimumScanlineLength The minimum length of scan lines that will be accepted, range: [1, infinity).
535 * @return The locations of the scan lines in the image, each defined by its end points in pixel coordinates.
536 */
537 static FiniteLines2 computeScanlines(const unsigned int frameWidth, const unsigned frameHeight, const Vector2& scanlineDirection, const unsigned int scanlineSpacing, const unsigned int frameBorder, const unsigned int minimumScanlineLength);
538
539 /**
540 * Extracts the data of scan line specified by two points.
541 * Uses the Bresenham algorithm to extract the data between two points (scan line).
542 * @param yFrame The frame from which a scan line will be extracted, must be valid, have its origin in the upper left corner, and have a pixel format that is compatible with Y8.
543 * @param scanline The scan line for which image data will be extracted, must be inside the image boundary.
544 * @param scanlineData The resulting scan line data; it is suggested to reserve its memory before calling this function.
545 * @param scanlinePositions The resulting pixel positions of the elements of the scan line, will have the same size as `scanline`.
546 * @param minimumScanlineLength An optional minimum value of the size of the scan line; scan lines with fewer elements will be discarded and the function will return false; will be ignored if set to 0.
547 * @return True if a scan line has been successfully extracted and it has at least the minimum number of elements, otherwise false.
548 */
549 static bool extractScanlineData(const Frame& yFrame, const FiniteLine2& scanline, ScanlineData& scanlineData, CV::PixelPositionsI& scanlinePositions, const unsigned int minimumScanlineLength = 0u);
550
551 /**
552 * Checks if a given pixel is a foreground pixel.
553 * @param pixelValue The pixel value that will be checked.
554 * @param grayThreshold The value of the gray threshold that is used to determine if the pixel is a foreground pixel.
555 * @return True if the pixel a is a foreground pixel, otherwise false.
556 * @tparam tIsNormalReflectance Indicates whether to consider foreground for normal or inverted reflectance.
557 */
558 template <bool tIsNormalReflectance>
559 static bool isForegroundPixel(const uint8_t pixelValue, const uint8_t grayThreshold);
560
561 /**
562 * Returns the set of all available parser function pointers.
563 * @return The set of all available parser function pointers.
564 */
566};
567
568template <typename TPixel>
570{
571 return segmentData_;
572}
573
574template <typename TPixel>
576{
577 return size_;
578}
579
580template <typename TPixel>
582{
583 return position_;
584}
585
586template <typename TPixel>
587bool RowSegmenter<TPixel>::setPosition(const size_t position)
588{
589 if (position >= size_)
590 {
591 ocean_assert(false && "Invalid position value");
592 return false;
593 }
594
595 position_ = position;
596 segmentPosition_ = position_;
597 transitionHistory_.reset();
598
599 return true;
600}
601
602template <typename TPixel>
603bool RowSegmenter<TPixel>::isTransitionLightToDark(const TPixel* pixel, const TGradient gradientThreshold, TransitionHistory& history)
604{
605 ocean_assert(pixel != nullptr);
606 ocean_assert(gradientThreshold > TGradient(0));
607
608 const TGradient gradient = TGradient(*pixel) - TGradient(*(pixel - 1));
609
610 bool isTransition = false;
611
612 if (gradient < -gradientThreshold)
613 {
614 isTransition = true;
615 }
616 else
617 {
618 if (gradient + history.history1() < -gradientThreshold ||
619 gradient + history.history2() < -(gradientThreshold * 5 / 4)||
620 gradient + history.history3() < -(gradientThreshold * 6 / 4))
621 {
622 isTransition = true;
623 }
624 }
625
626 history.push(gradient);
627
628 return isTransition;
629}
630
631template <typename TPixel>
632bool RowSegmenter<TPixel>::isTransitionDarkToLight(const TPixel* pixel, const TGradient gradientThreshold, TransitionHistory& history)
633{
634 ocean_assert(pixel != nullptr);
635 ocean_assert(gradientThreshold > TGradient(0));
636
637 const TGradient gradient = TGradient(*pixel) - TGradient(*(pixel - 1));
638
639 bool isTransition = false;
640
641 if (gradient > gradientThreshold)
642 {
643 isTransition = true;
644 }
645 else
646 {
647 if (gradient + history.history1() > gradientThreshold ||
648 gradient + history.history2() > (gradientThreshold * 5 / 4)||
649 gradient + history.history3() > (gradientThreshold * 6 / 4))
650 {
651 isTransition = true;
652 }
653 }
654
655 history.push(gradient);
656
657 return isTransition;
658}
659
660} // namespace Barcodes
661
662} // namespace Detector
663
664} // namespace CV
665
666} // namespace Ocean
Definition of an observation of a barcode in 2D.
Definition BarcodeDetector2D.h:456
Observation()=default
Creates an invalid observation.
const FiniteLine2 & location() const
Returns the location of the observation.
FiniteLine2 location_
The location of the observation.
Definition BarcodeDetector2D.h:478
Observation(const Vector2 &startPoint, const Vector2 &endPoint)
Create an observation from points.
This class implements a detector for barcodes.
Definition BarcodeDetector2D.h:427
static FiniteLines2 computeScanlines(const unsigned int frameWidth, const unsigned frameHeight, const Vector2 &scanlineDirection, const unsigned int scanlineSpacing, const unsigned int frameBorder, const unsigned int minimumScanlineLength)
Computes the locations of the scan lines for a given direction.
static Vector2 computeDirectionVector(const Scalar angle, const Scalar length=Scalar(1))
Computes a vector pointing at a specific angle on a unit circle.
std::vector< Observation > Observations
Definition of a vector of observations.
Definition BarcodeDetector2D.h:482
static bool isForegroundPixel(const uint8_t pixelValue, const uint8_t grayThreshold)
Checks if a given pixel is a foreground pixel.
static ParserFunctionSet getParserFunctions(const BarcodeTypeSet &barcodeTypeSet)
Returns the set of all available parser function pointers.
static Barcodes detectBarcodes(const Frame &yFrame, const uint32_t detectionFeatures=DF_STANDARD, const BarcodeTypeSet &enabledBarcodeTypes=BarcodeTypeSet(), const unsigned int scanlineSpacing=25u, Observations *observations=nullptr, FiniteLines2 *scanlines=nullptr)
Detects barcodes in an 8-bit grayscale image.
std::unordered_set< ParserFunction > ParserFunctionSet
Definition of a set of parser functions.
Definition BarcodeDetector2D.h:488
static bool extractScanlineData(const Frame &yFrame, const FiniteLine2 &scanline, ScanlineData &scanlineData, CV::PixelPositionsI &scanlinePositions, const unsigned int minimumScanlineLength=0u)
Extracts the data of scan line specified by two points.
DetectionFeatures
Definition of optional detection features.
Definition BarcodeDetector2D.h:435
static bool computeFrameIntersection(const unsigned int frameWidth, const unsigned frameHeight, const unsigned int frameBorder, const Line2 &line, CV::PixelPositionI &point0, CV::PixelPositionI &point1)
Computes the intersection points of a frame and an intersecting infinite line.
Definition of a barcode.
Definition Barcode.h:52
This class implements a simple history for previous pixel transitions (a sliding window of pixel tran...
Definition BarcodeDetector2D.h:80
TGradient history2()
Returns the history with window size N.
Definition BarcodeDetector2D.h:237
TGradient history3()
Returns the history with window size N.
Definition BarcodeDetector2D.h:243
TGradient history1()
Returns the history with window size N.
Definition BarcodeDetector2D.h:231
void reset()
Resets the history object.
Definition BarcodeDetector2D.h:257
TransitionHistory()=default
Creates a new history object.
void push(const TGradient newDelta)
Adds a new delta object as most recent history.
Definition BarcodeDetector2D.h:249
TGradient deltas_[3]
The most recent deltas.
Definition BarcodeDetector2D.h:121
This class converts raw pixel data into binary segments.
Definition BarcodeDetector2D.h:68
RowSegmenter(const TPixel *pixelData, const size_t pixelDataSize, const TGradient minimumGradient, const bool isNormalReflectance)
Creates a segmenter object for a buffer of raw pixel data.
Definition BarcodeDetector2D.h:265
size_t size_
The size of the raw pixel data in elements.
Definition BarcodeDetector2D.h:212
static bool isTransitionLightToDark(const TPixel *pixel, const TGradient minimumGradient, TransitionHistory &history)
Checks if the specified pixel is a transition from light to dark pixels.
Definition BarcodeDetector2D.h:603
bool prepareSegments(const size_t numberSegments)
Prepares a batch of segments.
Definition BarcodeDetector2D.h:322
bool isValid() const
Returns if this segmenter is valid.
Definition BarcodeDetector2D.h:285
TransitionHistory transitionHistory_
The object that holds the recent pixel history.
Definition BarcodeDetector2D.h:227
DifferenceValueTyper< TPixel >::Type TGradient
Definition BarcodeDetector2D.h:72
size_t size() const
Returns the size of the raw pixel data that is handled by this object.
Definition BarcodeDetector2D.h:575
const TPixel * pixelData_
The pointer to the raw pixel data that will be processed by this object.
Definition BarcodeDetector2D.h:209
SegmentData segmentData_
The memory holding the current segments.
Definition BarcodeDetector2D.h:224
bool(* IsTransitionFunc)(const TPixel *, const TGradient, TransitionHistory &)
Definition of a function pointer for function that determine intensity transitions between back- and ...
Definition BarcodeDetector2D.h:125
bool findNextTransitionToForeground()
Finds the next transition from background to foreground in the raw pixel data.
Definition BarcodeDetector2D.h:291
IsTransitionFunc isTransitionToBackground_
A pointer to the function that checks if there is a transition from foreground to background (this de...
Definition BarcodeDetector2D.h:206
size_t position_
The current position of the segmenter in the raw pixel data.
Definition BarcodeDetector2D.h:218
bool setPosition(const size_t position)
Sets the position of the segmenter in the raw pixel data.
Definition BarcodeDetector2D.h:587
static bool isTransitionDarkToLight(const TPixel *pixel, const TGradient minimumGradient, TransitionHistory &history)
Checks if the specified pixel is a transition from dark to light pixels.
Definition BarcodeDetector2D.h:632
size_t position() const
Returns the current position of the segmenter in the raw pixel data.
Definition BarcodeDetector2D.h:581
size_t segmentPosition_
The position of the segmenter in the raw pixel data when creating new segments (thresholding),...
Definition BarcodeDetector2D.h:221
IsTransitionFunc isTransitionToForeground_
A pointer to the function that checks if there is a transition from background to foreground (this de...
Definition BarcodeDetector2D.h:203
const SegmentData & segmentData() const
Returns the current segment data.
Definition BarcodeDetector2D.h:569
TGradient minimumGradient_
The minimum value of the pixel gradient that must be exceed for it count as a intensity transition.
Definition BarcodeDetector2D.h:215
This class implements a 2D pixel position with pixel precision.
Definition PixelPosition.h:65
T Type
Definition of the data type for the signed difference value.
Definition DataType.h:176
This class implements Ocean's image class.
Definition Frame.h:1808
This class implements an infinite line in 2D space.
Definition Line2.h:83
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition Base.h:138
std::vector< PixelPositionI > PixelPositionsI
Definition of a vector holding pixel positions (with positive and negative coordinate values).
Definition PixelPosition.h:55
std::vector< uint32_t > SegmentData
Definition of segment data, i.e., a sequence of lengths of binary, alternating foreground and backgro...
Definition Barcodes.h:65
std::vector< uint8_t > ScanlineData
Definition of scan line data, i.e., a sequence of raw pixel data.
Definition Barcodes.h:59
float Scalar
Definition of a scalar type.
Definition Math.h:129
std::vector< FiniteLine2 > FiniteLines2
Definition of a vector holding FiniteLine2 objects.
Definition FiniteLine2.h:57
std::unordered_set< BarcodeType > BarcodeTypeSet
Definition of a set of barcode types.
Definition Barcode.h:45
std::vector< Barcode > Barcodes
Definition of a vector of barcodes.
Definition Barcode.h:28
The namespace covering the entire Ocean framework.
Definition Accessor.h:15