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 using IsTransitionFunc = bool (*)(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 ocean_assert(position_ > 0u);
340
341 if (position_ == 0u)
342 {
343 return false;
344 }
345
346 const TPixel grayThreshold_ = (pixelData_[position_ - 1] + pixelData_[position_]) / 2u;
347
348 while (segmentPosition_ < size_ && numberSegments > segmentData_.size())
349 {
350 const bool atForeground = segmentData_.size() % 2 == 0;
351
352 size_t nextSegmentPosition = segmentPosition_ + 1;
353
354 if (atForeground)
355 {
356 while (nextSegmentPosition < size_ && pixelData_[nextSegmentPosition] < grayThreshold_)
357 {
358 nextSegmentPosition++;
359 }
360 }
361 else
362 {
363 while (nextSegmentPosition < size_ && pixelData_[nextSegmentPosition] >= grayThreshold_)
364 {
365 nextSegmentPosition++;
366 }
367 }
368
369 ocean_assert(nextSegmentPosition >= segmentPosition_);
370 const uint32_t segmentSize = uint32_t(nextSegmentPosition - segmentPosition_); // nextSegmentPosition is the first element of the next segment, so no +1 necessary
371
372 if (segmentSize == 0)
373 {
374 return false;
375 }
376
377 segmentData_.emplace_back(segmentSize);
378 segmentPosition_ = nextSegmentPosition;
379 }
380#else
381 // Determine the next segments by searching for intensity transitions, i.e. locations where the gradient exceeds a certain threshold.
382
383 // 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.
384
385 while (segmentPosition_ < size_ && numberSegments > segmentData_.size())
386 {
387 // Segment data alternates between foreground and background data. The first element is a foreground segment.
388 const bool atForeground = segmentData_.size() % 2 == 0;
389
390 IsTransitionFunc isNextTransition = nullptr;
391
392 if (atForeground)
393 {
394 isNextTransition = isTransitionToBackground_;
395 }
396 else
397 {
398 isNextTransition = isTransitionToForeground_;
399 }
400
401 size_t nextSegmentPosition = segmentPosition_ + 1u;
402
403 while (nextSegmentPosition < size_ && !isNextTransition(pixelData_ + nextSegmentPosition, minimumGradient_, transitionHistory_))
404 {
405 ++nextSegmentPosition;
406 }
407
408 ocean_assert(nextSegmentPosition >= segmentPosition_);
409 const uint32_t segmentSize = uint32_t(nextSegmentPosition - segmentPosition_); // nextSegmentPosition is the first element of the next segment, so no +1 necessary
410
411 if (segmentSize == 0)
412 {
413 return false;
414 }
415
416 segmentData_.emplace_back(segmentSize);
417 segmentPosition_ = nextSegmentPosition;
418 }
419#endif
420
421 if (numberSegments <= segmentData_.size())
422 {
423 return true;
424 }
425
426 return false;
427}
428
429/**
430 * This class implements a detector for barcodes.
431 * @ingroup cvdetectorbarcodes
432 */
433class OCEAN_CV_DETECTOR_BARCODES_EXPORT BarcodeDetector2D
434{
435 public:
436
437 /**
438 * Definition of optional detection features.
439 * @note Enabling additional features will reduce the runtime performance of the detector.
440 */
441 enum DetectionFeatures : uint32_t
442 {
443 /// Standard features that should be sufficient for most cases (excluding all the cases below).
444 DF_STANDARD = 0u,
445 /// 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.
446 DF_ENABLE_MULTIPLE_SCANLINE_DIRECTIONS = 1u << 0u,
447 /// Enables the search for barcodes that use inverted reflectance.
448 DF_ENABLE_INVERTED_REFLECTANCE = 1u << 1u,
449 /// Enables the detection of barcodes which are mirrored (e.g. when held up-side-down).
450 DF_ENABLE_SCANLINE_MIRRORING = 1u << 2u,
451 /// Enable the detection of multiple codes, otherwise the detection will stop after the first detected barcode.
452 DF_ENABLE_MULTI_CODE_DETECTION = 1u << 3u,
453 /// Enable the detection of duplicate codes; this will also enable the detection of multiple codes.
454 DF_ENABLE_MULTI_CODE_DETECTION_WITH_DUPLICATES = 1u << 4u | DF_ENABLE_MULTI_CODE_DETECTION,
455 /// Enable all of the available extra features.
456 DF_ENABLE_EVERYTHING = 0xFFFFFFFFu
457 };
458
459 /**
460 * Definition of an observation of a barcode in 2D.
461 */
462 class OCEAN_CV_DETECTOR_BARCODES_EXPORT Observation
463 {
464 public:
465
466 /**
467 * Creates an invalid observation.
468 */
469 Observation() = default;
470
471 /**
472 * Create an observation from points.
473 */
474 Observation(const Vector2& startPoint, const Vector2& endPoint);
475
476 /**
477 * Returns the location of the observation.
478 * @return The location of the observation.
479 */
480 const FiniteLine2& location() const;
481
482 protected:
483
484 /// The location of the observation.
486 };
487
488 /// Definition of a vector of observations.
489 using Observations = std::vector<Observation>;
490
491 /// Definition of a function pointer for parser functions which detect the actual barcodes.
492 using ParserFunction = bool (*)(const uint32_t* segmentData, const size_t size, Barcode& barcode, IndexPair32& xCoordinates);
493
494 /// Definition of a set of parser functions.
495 using ParserFunctionSet = std::unordered_set<ParserFunction>;
496
497 public:
498
499 /**
500 * Detects barcodes in an 8-bit grayscale image.
501 * @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.
502 * @param detectionFeatures Optional flag to enable certain additional detection features.
503 * @param enabledBarcodeTypes A set of barcode types that will be detected; if empty, every supported barcode will be detected.
504 * @param scanlineSpacing The spacing between parallel scan lines in pixels, range: [1, infinity).
505 * @param observations Optional observations of the detected barcodes that will be returned, will be ignored if `nullptr`.
506 * @param scanlines Optionally resulting scan lines that were used during the detection, will be ignored if `nullptr`.
507 * @return The list of detected barcodes.
508 */
509 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);
510
511 protected:
512
513 /**
514 * Computes a vector pointing at a specific angle on a unit circle.
515 * @param angle The angle on the unit circle for which a corresponding vector is computed, range: [0, 2*PI].
516 * @param length The length that the resulting vector will have, range: (0, infinity).
517 * @return The vector
518 */
519 static Vector2 computeDirectionVector(const Scalar angle, const Scalar length = Scalar(1));
520
521 /**
522 * Computes the intersection points of a frame and an intersecting infinite line.
523 * @param frameWidth The width of the frame that is intersected by the infinite line, range: [1, infinity).
524 * @param frameHeight The height of the frame that is intersected by the infinite line, range: [1, infinity).
525 * @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).
526 * @param line The infinite line to intersect with the frame, must be valid.
527 * @param point0 The resulting first intersection point.
528 * @param point1 The resulting second intersection point.
529 * @return True if an intersection has been found, otherwise false.
530 */
531 static bool computeFrameIntersection(const unsigned int frameWidth, const unsigned frameHeight, const unsigned int frameBorder, const Line2& line, CV::PixelPositionI& point0, CV::PixelPositionI& point1);
532
533 /**
534 * Computes the locations of the scan lines for a given direction.
535 * 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.
536 * @param frameWidth The width of the frame that is intersected by the infinite line, range: [1, infinity).
537 * @param frameHeight The height of the frame that is intersected by the infinite line, range: [1, infinity).
538 * @param scanlineDirection The direction for which scan lines should be extracted, must be valid.
539 * @param scanlineSpacing The spacing between parallel scan lines in pixels, range: [1, infinity).
540 * @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).
541 * @param minimumScanlineLength The minimum length of scan lines that will be accepted, range: [1, infinity).
542 * @return The locations of the scan lines in the image, each defined by its end points in pixel coordinates.
543 */
544 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);
545
546 /**
547 * Extracts the data of scan line specified by two points.
548 * Uses the Bresenham algorithm to extract the data between two points (scan line).
549 * @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.
550 * @param scanline The scan line for which image data will be extracted, must be inside the image boundary.
551 * @param scanlineData The resulting scan line data; it is suggested to reserve its memory before calling this function.
552 * @param scanlinePositions The resulting pixel positions of the elements of the scan line, will have the same size as `scanline`.
553 * @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.
554 * @return True if a scan line has been successfully extracted and it has at least the minimum number of elements, otherwise false.
555 */
556 static bool extractScanlineData(const Frame& yFrame, const FiniteLine2& scanline, ScanlineData& scanlineData, CV::PixelPositionsI& scanlinePositions, const unsigned int minimumScanlineLength = 0u);
557
558 /**
559 * Checks if a given pixel is a foreground pixel.
560 * @param pixelValue The pixel value that will be checked.
561 * @param grayThreshold The value of the gray threshold that is used to determine if the pixel is a foreground pixel.
562 * @return True if the pixel a is a foreground pixel, otherwise false.
563 * @tparam tIsNormalReflectance Indicates whether to consider foreground for normal or inverted reflectance.
564 */
565 template <bool tIsNormalReflectance>
566 static bool isForegroundPixel(const uint8_t pixelValue, const uint8_t grayThreshold);
567
568 /**
569 * Returns the set of all available parser function pointers.
570 * @return The set of all available parser function pointers.
571 */
573};
574
575template <typename TPixel>
577{
578 return segmentData_;
579}
580
581template <typename TPixel>
583{
584 return size_;
585}
586
587template <typename TPixel>
589{
590 return position_;
591}
592
593template <typename TPixel>
594bool RowSegmenter<TPixel>::setPosition(const size_t position)
595{
596 if (position >= size_)
597 {
598 ocean_assert(false && "Invalid position value");
599 return false;
600 }
601
602 position_ = position;
603 segmentPosition_ = position_;
604 transitionHistory_.reset();
605
606 return true;
607}
608
609template <typename TPixel>
610bool RowSegmenter<TPixel>::isTransitionLightToDark(const TPixel* pixel, const TGradient gradientThreshold, TransitionHistory& history)
611{
612 ocean_assert(pixel != nullptr);
613 ocean_assert(gradientThreshold > TGradient(0));
614
615 const TGradient gradient = TGradient(*pixel) - TGradient(*(pixel - 1));
616
617 bool isTransition = false;
618
619 if (gradient < -gradientThreshold)
620 {
621 isTransition = true;
622 }
623 else
624 {
625 if (gradient + history.history1() < -gradientThreshold ||
626 gradient + history.history2() < -(gradientThreshold * 5 / 4)||
627 gradient + history.history3() < -(gradientThreshold * 6 / 4))
628 {
629 isTransition = true;
630 }
631 }
632
633 history.push(gradient);
634
635 return isTransition;
636}
637
638template <typename TPixel>
639bool RowSegmenter<TPixel>::isTransitionDarkToLight(const TPixel* pixel, const TGradient gradientThreshold, TransitionHistory& history)
640{
641 ocean_assert(pixel != nullptr);
642 ocean_assert(gradientThreshold > TGradient(0));
643
644 const TGradient gradient = TGradient(*pixel) - TGradient(*(pixel - 1));
645
646 bool isTransition = false;
647
648 if (gradient > gradientThreshold)
649 {
650 isTransition = true;
651 }
652 else
653 {
654 if (gradient + history.history1() > gradientThreshold ||
655 gradient + history.history2() > (gradientThreshold * 5 / 4)||
656 gradient + history.history3() > (gradientThreshold * 6 / 4))
657 {
658 isTransition = true;
659 }
660 }
661
662 history.push(gradient);
663
664 return isTransition;
665}
666
667} // namespace Barcodes
668
669} // namespace Detector
670
671} // namespace CV
672
673} // namespace Ocean
Definition of an observation of a barcode in 2D.
Definition BarcodeDetector2D.h:463
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:485
Observation(const Vector2 &startPoint, const Vector2 &endPoint)
Create an observation from points.
This class implements a detector for barcodes.
Definition BarcodeDetector2D.h:434
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.
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:495
std::vector< Observation > Observations
Definition of a vector of observations.
Definition BarcodeDetector2D.h:489
bool(*)(const uint32_t *segmentData, const size_t size, Barcode &barcode, IndexPair32 &xCoordinates) ParserFunction
Definition of a function pointer for parser functions which detect the actual barcodes.
Definition BarcodeDetector2D.h:492
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:442
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:610
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
size_t size() const
Returns the size of the raw pixel data that is handled by this object.
Definition BarcodeDetector2D.h:582
bool(*)(const TPixel *, const TGradient, TransitionHistory &) IsTransitionFunc
Definition of a function pointer for function that determine intensity transitions between back- and ...
Definition BarcodeDetector2D.h:125
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
typename DifferenceValueTyper< TPixel >::Type TGradient
Definition BarcodeDetector2D.h:72
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:594
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:639
size_t position() const
Returns the current position of the segmenter in the raw pixel data.
Definition BarcodeDetector2D.h:588
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:576
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:63
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:1879
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:53
std::vector< uint8_t > ScanlineData
Definition of scan line data, i.e., a sequence of raw pixel data.
Definition Barcodes.h:59
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
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