get_2d_bar_code — Extract the values of the data elements (in ECC 200: “modules”) inside a bar code region (“Data Matrix symbol”).
get_2d_bar_code is obsolete and is only provided for reasons of backward compatibility. New applications should use the functionality in the chapter Identification / Data Code for reading 2D data code symbologies instead (see create_data_code_2d_model).
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:
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', 'engraved_lightfield':||0.3|
|printing method 'engraved_darkfield':||0.7|
Method for the classification of modules (Selectable only for the printing methods '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 choosing a suitable value for 'module_rad_ratio'.
Use the feature “gray value minimum” for classifying module values.
Use the feature “gray value maximum” for classifying module values.
Use the feature “gray value range” for classifying module values.
Parameters for the printing methods 'printed' and 'engraved_lightfield':
Enlarge the symbol region.
|GenParamValues:||> 0 (<= 0: enlargement prohibited)|
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 position of the modules.
|GenParamValues:||0 ... 100|
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.
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).
Distance between the contour and its approximation. The parameters 'max_line_dist1' and 'max_line_dist2' control the maximal distance between the contour and its approximation (see operator segment_contours_xld).
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.
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 search region is increased until the finder patterns have been detected, or until 'border_width_max' has been reached.
Maximum width of the border search area.
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'.
Parameters for the printing method 'engraved_darkfield':
Mask size for the initial median filtering (see operator median_image).
|default:||'module_width'*0.1 + 0.5|
Mask size for the subsequent gray value erosion (see operator gray_erosion_rect).
|default:||'module_width'*0.18 + 3.5|
Parameter for the extraction of linear edge segment pairs (see operator measure_pairs).
|default:||'module_width' < 20:||0.7|
|'module_width' >= 20:||1.4|
Parameter for the extraction of linear edge segment pairs (see operator measure_pairs).
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).
Region that might contain a 2D bar code.
Description of the bar code class.
Additional parameters describing the bar code region. They can be used for extracting the data
List of names of (optional) generic control parameters.
Default value: 
List of values: 'border_width', 'border_width_max', 'border_width_min', 'enlarge_region_rad', 'gray_erosion_size', 'max_line_dist1', 'max_line_dist2', 'measure_sigma', 'measure_thresh', 'median_mask_rad', 'min_cont_len', 'module_rad_ratio', 'smooth_cont', 'thresh_percent', 'thresh_step_width', 'use_grayval_max', 'use_grayval_min', 'use_grayval_range', 'use_grayvals'
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
Tuple with the dimension of the extracted symbol. In the case of ECC 200: data field width, height, symbol index.
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'], , CodeRegDescr) count_obj (CodeRegion, SymbolNum) for i := 1 to SymbolNum by 1 select_obj (CodeRegion, ObjectSelected, 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.