Ocean
ParserEan13Upca.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 namespace Ocean
14 {
15 
16 namespace CV
17 {
18 
19 namespace Detector
20 {
21 
22 namespace Barcodes
23 {
24 
25 /**
26  * A parser for EAN-13 and UPC-A barcodes.
27  * @ingroup cvdetectorbarcodes
28  */
29 class OCEAN_CV_DETECTOR_BARCODES_EXPORT ParserEan13Upca
30 {
31  protected:
32 
33  /// Definition of a digit pattern, i.e. any digit is encoded by the widths of two light and dark bars
34  typedef std::array<uint32_t, 4> DigitPattern;
35 
36  public:
37 
38  /**
39  * Parses segment data for an EAN-13 or UPC-A barcode
40  * @param segmentData The pointer to the segment data, must be valid
41  * @param size The size of the segment data in elements, range: [59, infinity)
42  * @param barcode The resulting barcode if one has been found
43  * @param xCoordinates The resulting start and end x-coordinates of the detected barcode, the end is inclusive
44  * @return True if a barcode has been detected, otherwise false
45  * @tparam tReportUpcASeparately True to report UPC-A codes separately, otherwise UPC-A will be reported as EAN-13 (of which it is a sub-type)
46  */
47  template <bool tReportUpcASeparately = true>
48  static bool parse(const uint32_t* segmentData, const size_t size, Barcode& barcode, IndexPair32& xCoordinates);
49 
50  protected:
51 
52  /**
53  * Returns if the given segment data is the start of the left guard of a barcode
54  * @param segmentData The pointer to the segment data, must be valid
55  * @param size The size of the segment data in elements, range: [59, infinity)
56  * @param moduleSize The estimated module size in pixels, range: [1, infinity)
57  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, moduleSize
58  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [moduleSize, infinity)
59  * @return True if the given segment data is the start of the left guard of a barcode, otherwise false
60  */
61  static bool isLeftGuard(const uint32_t* segmentData, const size_t size, uint32_t& moduleSize, uint32_t& minModuleSize, uint32_t& maxModuleSize);
62 
63  /**
64  * Returns if the given segment data is the start of the middle guard of a barcode
65  * @param segmentData The pointer to the segment data, must be valid
66  * @param size The size of the segment data in elements, range: [59, infinity)
67  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, maxModuleSize
68  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [minModuleSize, infinity)
69  * @return True if the given segment data is the start of the middle guard of a barcode, otherwise false
70  */
71  static bool isMiddleGuard(const uint32_t* segmentData, const size_t size, const uint32_t& minModuleSize, const uint32_t& maxModuleSize);
72 
73  /**
74  * Returns if the given segment data is the start of the right guard of a barcode
75  * @param segmentData The pointer to the segment data, must be valid
76  * @param size The size of the segment data in elements, range: [59, infinity)
77  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, maxModuleSize
78  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [minModuleSize, infinity)
79  * @return True if the given segment data is the start of the right guard of a barcode, otherwise false
80  */
81  static bool isRightGuard(const uint32_t* segmentData, const size_t size, const uint32_t& minModuleSize, const uint32_t& maxModuleSize);
82 
83  /**
84  * Decodes the left and right digits of a barcode given their respective start segments
85  * @param leftDigitsSegmentData The pointer to the first element of the segment data where the left block of digits starts, must be valid
86  * @param rightDigitsSegmentData The pointer to the first element of the segment data where the right block of digits start, must be valid
87  * @param moduleSize The estimated module size in pixels, range: [1, infinity)
88  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, moduleSize
89  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [moduleSize, infinity)
90  * @param decodedDigits The resulting, decoded digits in the order as they appear under the barcode (if printed)
91  * @return True if the digits have been decoded successfully, otherwise false
92  */
93  static bool decodeDigits(const uint32_t* leftDigitsSegmentData, const uint32_t* rightDigitsSegmentData, const uint32_t moduleSize, const uint32_t& minModuleSize, const uint32_t& maxModuleSize, std::vector<uint8_t>& decodedDigits);
94 
95  /**
96  * Decodes a single digit given its segment data
97  * @param digitSegmentData The pointer to the first element of the segment data where the digits starts, must be valid
98  * @param moduleSize The estimated module size in pixels, range: [1, infinity)
99  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, moduleSize
100  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [moduleSize, infinity)
101  * @param decodedDigit The resulting decoded digit
102  * @param parityBit The parity bit of the decoded digit from the underlying alphabet (required to decode the first digit in case of EAN-13 from the parity of the left digit block).
103  * @tparam tUseCodesLAndG Indicates the alphabet that should be used to decode this digit (left block: `true`, right block: `false`)
104  */
105  template <bool tUseCodesLAndG>
106  static bool decodeDigit(const uint32_t* digitSegmentData, const uint32_t moduleSize, const uint32_t& minModuleSize, const uint32_t& maxModuleSize, uint8_t& decodedDigit, unsigned int& parityBit);
107 
108  /**
109  * Computes a score for digit pattern
110  * The score indicates how well a certain digit pattern fits with a pre-defined pattern from one of the alphabets; the lower the score, the better (range: [0, infinity))
111  * @param digitSegmentData The pointer to the first element of the segment data where the digits starts, must be valid, TODO This should be a DigitPattern at some point
112  * @param digitPattern The pattern against which the segment above will be scored, must be valid
113  * @param moduleSize The estimated module size in pixels, range: [1, infinity)
114  * @param minModuleSize The minimum size of what can be accepted as a single module, range: [1, moduleSize
115  * @param maxModuleSize The maximum size of what can be accepted as a single module, range: [moduleSize, infinity)
116  * @return The value of the score
117  */
118  static uint32_t computePatternScore(const uint32_t* digitSegmentData, const DigitPattern& digitPattern, const uint32_t moduleSize, const uint32_t& minModuleSize, const uint32_t& maxModuleSize);
119 
120  /**
121  * Checks the verification digits of a barcode
122  * @param barcodeDigits The pointer to the decoded digits of a barcode, must be valid
123  * @param numberDigits The number of digits provided, range: [12, 13]
124  * @return True if the verification was successful, otherwise false
125  */
126  static bool verifyCheckDigit(const uint8_t* barcodeDigits, const size_t numberDigits);
127 };
128 
129 } // namespace Barcodes
130 
131 } // namespace Detector
132 
133 } // namespace CV
134 
135 } // namespace Ocean
Definition of a barcode.
Definition: Barcode.h:52
A parser for EAN-13 and UPC-A barcodes.
Definition: ParserEan13Upca.h:30
static bool isLeftGuard(const uint32_t *segmentData, const size_t size, uint32_t &moduleSize, uint32_t &minModuleSize, uint32_t &maxModuleSize)
Returns if the given segment data is the start of the left guard of a barcode.
static bool verifyCheckDigit(const uint8_t *barcodeDigits, const size_t numberDigits)
Checks the verification digits of a barcode.
static bool parse(const uint32_t *segmentData, const size_t size, Barcode &barcode, IndexPair32 &xCoordinates)
Parses segment data for an EAN-13 or UPC-A barcode.
static bool decodeDigits(const uint32_t *leftDigitsSegmentData, const uint32_t *rightDigitsSegmentData, const uint32_t moduleSize, const uint32_t &minModuleSize, const uint32_t &maxModuleSize, std::vector< uint8_t > &decodedDigits)
Decodes the left and right digits of a barcode given their respective start segments.
static bool isMiddleGuard(const uint32_t *segmentData, const size_t size, const uint32_t &minModuleSize, const uint32_t &maxModuleSize)
Returns if the given segment data is the start of the middle guard of a barcode.
static bool isRightGuard(const uint32_t *segmentData, const size_t size, const uint32_t &minModuleSize, const uint32_t &maxModuleSize)
Returns if the given segment data is the start of the right guard of a barcode.
static uint32_t computePatternScore(const uint32_t *digitSegmentData, const DigitPattern &digitPattern, const uint32_t moduleSize, const uint32_t &minModuleSize, const uint32_t &maxModuleSize)
Computes a score for digit pattern The score indicates how well a certain digit pattern fits with a p...
std::array< uint32_t, 4 > DigitPattern
Definition of a digit pattern, i.e. any digit is encoded by the widths of two light and dark bars.
Definition: ParserEan13Upca.h:34
static bool decodeDigit(const uint32_t *digitSegmentData, const uint32_t moduleSize, const uint32_t &minModuleSize, const uint32_t &maxModuleSize, uint8_t &decodedDigit, unsigned int &parityBit)
Decodes a single digit given its segment data.
std::pair< Index32, Index32 > IndexPair32
Definition of a pair holding 32 bit indices.
Definition: Base.h:138
std::vector< Barcode > Barcodes
Definition of a vector of barcodes.
Definition: Barcode.h:25
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15