Extract the values of the data elements (in ECC 200: ``modules'') inside a bar code region (``Data Matrix symbol'').
get_2d_bar_code extracts the 2D bar code from a candidate symbol region given in BarCodeRegion and the corresponding image given in Image. BarCodeDescr contains a descriptor of the expected bar code class, which is created with the help of the operator gen_2d_bar_code_descr. CodeRegDescr contains further information regarding the candidate region. This descriptor is created by the operator find_2d_bar_code.
If BarCodeRegion contains a 2D bar code, its data, i.e. the bits of the matrix, are written line by line into a tuple and returned in the parameter BarCodeData. Positive values stand for a logical one, negative values for a logical zero. A value of zero signals that the data element could not be classified unambiguously.
The size of the data field is returned in the parameter BarCodeDimension. The first two entries specify the width and the height of the data field, the third contains a so-called symbol index which also describes its size. The size of the data field is not to be confused with the size of the symbol which in turn encompasses additional finder and alignment patterns.
If no 2D bar code could be extracted the operator returns a corresponding error code.
In difficult cases, the user can influence image processing with the help of the (optional) generic parameters GenParamNames and GenParamValues. The width of a module in pixels ('module_width') does not need to be specified, it is part of the region descriptor CodeRegDescr. As in the case of the operator find_2d_bar_code, for the different printing methods different image processing steps are applied, leading to different parameters.
As a short overview, image processing falls into the following parts: First, the region BarCodeRegion is divided into a dark and a light region by applying a thresholding operator. Because there must be a ``silent'' area around each 2D bar code, this area can be examined to determine whether the bar code is printed black-on-white or vice versa. With this information, the dark and the light region can be assigned to the logical data values. Next, BarCodeRegion is approximated by a rectangle. Then, the special finder patterns that each each symbol must contain are searched for in the border areas of the rectangle. From the finder pattern, the size of the data matrix and the size and the position of the modules (data elements) can be determined. Finally, the value of the modules is determined.
Parameters controlling the classification of modules as being dark or light:
'module_rad_ratio' Part of the module that is to be used for its classification.
This parameter controls which part of the module area (in percent, measured
from the center) is used to determine its value.
With a 'module_rad_ratio' of 1.0, the whole area of the module will be
examined. With very small 'module_rad_ratio', only one point in the middle
will be examined.
GenParamValues: 0 < 'module_rad_ratio' <= 1
default: printing method 'printed': 0.3
printing method 'engraved_lightfield': 0.3
printing method 'engraved_darkfield': 0.7
'use_grayvals' Method for the classification of modules (Selectable only for the printing
method 'printed' and 'engraved_lightfield'; for the
printing method 'engraved_darkfield', the gray-value-based method
is always used!).
The parameter 'use_grayvals' controls by which method the modules are
classified. If 'use_grayvals' is set to 'no', the module's value
is determined by examining whether the part of the module specified by
'module_rad_ratio' is part of the region that has been assigned the
value 1. If more than half of the module is part of this region,
the module is interpreted as a logical one.
In the case 'use_grayvals' is set to 'yes', the gray values inside
'module_rad_ratio' are examined. For this, the known border parts of
the symbol are used to create classificators with the features ``minimum
gray value'', ``maximum gray value'', and ``range of gray values''.
A feature will be automatically excluded if it cannot separate the known dark
and light regions. It can also be excluded manually with the help of the
parameters below.
The value of the modules is then determined by applying the trained
classificators. In case of ambiguous results, the majority decision is
adopted.
If none of the gray value features can separate the test regions, the operator
switches automatically to the region-based method in case the printing method
is set to 'printed'. This can be detected by examining the data
values returned in BarCodeData: The region-based method yields
multiples of 4, the gray-value-based method values between -3 and +3.
If separation fails when the printing method is 'engraved_darkfield',
an error code is returned. Note, that classification performance can be
enhanced by chosing a suitable value for 'module_rad_ratio'.
GenParamValues: 'yes', 'no'
default: 'yes'
'use_grayval_min' Use the feature ``gray value minimum'' for classifying module values.
GenParamValues: 'yes', 'no'
default: 'yes'
'use_grayval_max' Use the feature ``gray value maximum'' for classifying module values.
GenParamValues: 'yes', 'no'
default: 'printed', 'engraved_lightfield': 'yes'
'engraved_darkfield': 'no'
'use_grayval_range' Use the feature ``gray value range'' for classifying module values.
GenParamValues: 'yes', 'no'
default: 'yes'
Parameters for the printing methods 'printed' and 'engraved_lightfield':
'enlarge_region_rad' Enlarge the symbol region.
GenParamValues: > 0 (<= 0: enlargment prohibited)
default: 2.5
'thresh_percent' Area of the histogram in which to look for an optimal threshold.
The threshold for separating dark and light regions will be searched for in
the middle 'thresh_percent' percent of the gray value histogram. If
'thresh_percent' is set to 0, a threshold exactly in the middle of the
histogram is selected. If 'thresh_percent' is set to 100, the whole histogram
will be searched. Note, that the threshold influences not only the size of
the data region, but also the position of the surrounding rectangle and with
it, slightly, the positionof the modules.
GenParamValues: 0...100
default: 50
'thresh_step_width' Step width for the search of the optimal threshold.
The histogram area specified in the parameter 'thresh_percent' will be
stepped through using 'thresh_step_width' until an optimal separation of dark
and light regions is reached. The optimum is declared to be found when the
number of individual regions is at its maximum. The smaller
'thresh_step_width' is, the better a threshold can be determined, however at
the cost of rising computing time, of course.
GenParamValues: > 0
default: 10
'smooth_cont' Parameter for approximating the region by a polygon (rectangle).
The parameter 'smooth_cont' controls to which degree the contour is smoothed
before approximating it with a polygon (see operator segment_contours_xld).
GenParamValues: 0,3,5,7,9,...
default: 5
'max_line_dist1', Distance between the contour and its approximation.
'max_line_dist2'
The parameters 'max_line_dist1' and 'max_line_dist2' control the maximal
distance between the contour and its approximation (see operator
segment_contours_xld).
GenParamValues: >= 0
default: 4
'min_cont_len' Minimum length of the contour elements in pixel.
Contour elements shorter than 'min_cont_len' will be ignored when
approximating the region by a rectangle. In the case of small symbols or low
resolution, it can be helpful to decrease this parameter.
GenParamValues: > 0
default: 50
'border_width_min' Minimum width of the border search area.
The border area of the symbol region must contain the so-called finder
patterns (ECC 200: two lines with the value 1, two with alternating
values). To find these patterns, a search region is constructed along the
sides of the rectangle. Starting with 'border_width_min', the width of the
seach region isincreased until the finder patterns have been detected, or
until 'border_width_max' has been reached.
GenParamValues: > 0
default: 2
'border_width_max' Maximum width of the border search area.
GenParamValues: > 'border_width_min'
default: 5
'border_width' Exact width of the border search area.
Alternatively, the exact width of this search area can be specified in the
parameter 'border_width'. This automatically sets 'border_width_min'
and 'border_width_max'.
GenParamValues: > 0
default: -
Parameters for the printing method 'engraved_darkfield':
'median_mask_rad' Mask size for the initial median filtering (see operator median_image).
GenParamValues: 3,5,7,...,501
default: 'module_width'*0.1 + 0.5
'gray_erosion_size' Mask size for the subsequent gray value erosion (see operator
gray_erosion_rect).
GenParamValues: 3,5,7,...,511
default: 'module_width'*0.18 + 3.5
'measure_sigma' Parameter for the extraction of linear edge segment pairs (see operator
measure_pairs).
GenParamValues: 0.4...100
default: 'module_width' < 20: 0.7
'module_width' >= 20: 1.4
'measure_thresh' Parameter for the extraction of linear edge segment pairs (see operator
measure_pairs).
GenParamValues: 1...255
default: 2.0
The operator get_2d_bar_code returns error codes to signal that the candidate region did not contain a valid 2D bar code. As the region candidates extracted by the operator find_2d_bar_code can perfectly well encompass regions without a bar code, every call to get_2d_bar_code should be surrounded by error handling code (see example).
|
BarCodeRegion (input_object) |
region -> object |
| Region that might contain a 2D bar code. | |
|
Image (input_object) |
image -> object : byte |
| Corresponding image. | |
|
BarCodeDescr (input_control) |
barcode_2d-array -> string / integer / real |
| Description of the bar code class. | |
|
CodeRegDescr (input_control) |
string-array -> string / integer / real |
| Additional parameters describing the bar code region. They can be used for extracting the data | |
|
GenParamNames (input_control) |
string-array -> string |
| List of names of (optional) generic control parameters. | |
| Default value: '[]' | |
| List of values: 'module_rad_ratio', 'use_grayvals', 'use_grayval_min', 'use_grayval_max', 'use_grayval_range', 'enlarge_region_rad', 'thresh_percent', 'thresh_step_width', 'smooth_cont', 'max_line_dist1', 'max_line_dist2', 'min_cont_len', 'border_width_min', 'border_width_max', 'border_width', 'median_mask_rad', 'gray_erosion_size', 'measure_sigma', 'measure_thresh' | |
|
GenParamValues (input_control) |
number-array -> real / integer |
| List of values of the generic parameters. | |
| Default value: '[]' | |
| Suggested values: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 'yes', 'no', -1, 1.5, 2.5, 3.5, 4.5, 5.5, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 30, 40, 50 | |
|
BarCodeDimension (output_control) |
integer-array -> integer |
| Tuple with the dimension of the extracted symbol. In the case of ECC 200: data field width, height, symbol index. | |
|
BarCodeData (output_control) |
integer-array -> integer |
| Tuple with the data values of the extracted symbol. value > 0: logical 1, value < 0: logical 0, value = 0: module could not be classified. | |
dev_error_var (ErrorCode, 1)
gen_2d_bar_code_descr ('Data Matrix ECC 200', ['mode'], ['printed'],
BarCodeDescr)
read_image (Image, 'bar2d.tif')
find_2d_bar_code (Image, CodeRegion, BarCodeDescr,
['module_width'], [10], CodeRegDescr)
SymbolNum := |CodeRegion|
for i := 1 to SymbolNum by 1
ObjectSelected := CodeRegion[i]
dev_set_check ('~give_error')
get_2d_bar_code (ObjectSelected, Image, BarCodeDescr, CodeRegDescr,
[], [], BarCodeDimension, BarCodeData)
err := ErrorCode
dev_set_check ('give_error')
if (err = 2)
decode_2d_bar_code (BarCodeDescr, BarCodeDimension, BarCodeData,
SymbolCharacters, CorrSymbolData, DecodedData,
DecodingError, StructuredAppend)
if (|DecodedData|)
tuple_chrt (DecodedData, String)
endif
endif
endfor
The return value can signal incorrect parameters as well as the failure to extract a 2D bar code. Such a failure can be due to different causes: If no surrounding rectangle was found, the operator returns the error code 8808. Error code 8807 signals that the rectangle does not lie completely inside the image. If no finder pattern was detected inside the border search area, the error code 8810 is returned. If the two continuous lines forming the 'L' of the finder pattern could not be found, the error code 8809 is returned. In the case of the printing method 'engraved_darkfield', the error code 8811 signals that none of the gray value features can separate the test regions, i.e. that modules cannot be classified.
get_2d_bar_code is reentrant and processed without parallelization.
Barcode reader