A code, once printed on a physical medium (such as a labeling sticker, a bag, or package), should be read and validated to ensure that there were no errors in the print process. This ensures that the code is readable by most types of imagers (such as, bar code scanners) that support your code type. For this purpose, the industry has created a set of standard print quality specifications (ISO standards). These standards can be used in two distinct phases: one to prepare the physical environment in which to best validate your code so that you test the printed code and not the setup in which it is read (such as lighting, code angle, quality of the code reader), and the other to validate the code that is being read.
You can use McodeGrade() for both phases. You can use it to help set up a code verification system according to the relevant ISO standards, as well as use it to grade the quality of printed codes. Depending on the type of code and the attribute being tested, most tests are graded from 0.0 to 4.0 (F to A), or given a pass or fail mark. Use McodeGetResult() or McodeGetResultSingle() to retrieve these results.
Note that McodeGrade() is not supported for 4-state, Pharmacode, Postnet, and Planet 1D code types or Aztec 2D code types with an encoding of Aztec Rune.
You can grade a single code or multiple codes with each call to McodeGrade(), depending upon your requirements. In addition, by default McodeGrade() performs a read operation before performing the grading operation. However, to speed up the process, you can perform the read operation using McodeRead() and pass the code result read to McodeGrade().
This section will guide you through the steps in using the MIL Code module to prepare your code setup for verification, as well as provide additional details for understanding the grading results from the MIL Code module.
Before you can validate that there were no errors in the printing of a code, you must configure your setup so that you are analyzing the printed code and not how well the code can be read in the current environment. The general ISO standard, ISO/IEC 15415, provides only general guidelines for configuring your setup for code verification. The following procedure is designed to assist in modifying your setup until near-perfect conditions are obtained. A grabbed image of a near-perfect code is used since you know the grade of a perfect code should be A, as long as the setup is not influencing the grade.
In the environment in which you will eventually be grading your codes, grab an image of a perfectly printed sample code, using MdigGrab() (for example, a standards card for your code type).
Evaluate the grabbed code using McodeGrade(). Then, return the overall grade using McodeGetResult() with M_OVERALL_SYMBOL_GRADE.
If the resulting grade is not an "A", then as necessary, adjust the image setup to:
Maximize the contrast and minimize noise in the image.
Avoid pixel saturation.
Have a cell size of at least 3. A smaller cell size results in a less robust result.
Have a uniform foreground and background grayscale level (that is, there should be no glare or dark spots present in the image).
Repeat steps 1-3 until the resulting grade is an "A" (or the best possible grade given the surface on which the code is printed).
For 2D code types, get the minimum and maximum reflectance values, using McodeGetResult() with M_R_MIN and M_R_MAX, respectively. These values will be used as the minimum calibrated reflectance and the maximum calibrated reflectance, respectively.
For 1D code types, get the recommended aperture size, using McodeGetResult() with M_RECOMMENDED_APERTURE_SIZE.
Smooth the image using multiple calls to MimConvolve() with M_SMOOTH. MimConvolve() should be called at least once and at most a number of times equal to the following: (Recommended Aperture size + 0.5)/2.
Find the minimum and maximum pixel values in the smoothed image using MimFindExtreme() with M_MIN_VALUE + M_MAX_VALUE. These values will be used as the minimum calibrated reflectance and the maximum calibrated reflectance, respectively.
Set the minimum and maximum calibrated reflectance to the values previously determined in step 5 or 6, using McodeControl() with M_MINIMUM_CALIBRATED_REFLECTANCE and M_MAXIMUM_CALIBRATED_REFLECTANCE, respectively.
Once the minimum and maximum calibrated reflectance is set, you are ready to grab and grade your codes. It is important to not modify the setup for the remainder of the grading process.
The following table lists the common code attributes that can be graded, including the attributes of the scan reflectance profiles, using MIL. To determine which of the following attributes can be graded for codes of a specific family of code types, refer to the Results by code type section later in this chapter.
Attribute |
Notes |
|
Axial nonuniformity |
This attribute is a measure of how spacing between sampling points differs between the X- and Y-axis (width to height). |
|
Contrast |
This attribute is a measure of the contrast in the cells of the code or the entire code itself. The higher the contrast, the better it is for scanning purposes and the better the grade. |
|
Decode |
This attribute is a measure of the success or failure of the decoding algorithm and is used to determine if the code is readable. |
|
Defects |
This attribute is a measure of the defects, or local deviations, in the scan reflectance profiles of the code. |
|
Fixed-pattern damage |
This attribute is used to grade the damage relating to the finder pattern and/or clock pattern of a 2D Data Matrix code. |
|
Grid nonuniformity |
This attribute is calculated as the amount of deviation of the code's actual grid from an ideal grid. |
|
Minimum edge contrast |
This attribute is calculated as the contrast between two adjacent regions (for example, a bar and an adjacent space). |
|
Print growth |
This attribute is a measure of the extent in which the boundaries of the black and white markings of the code are within their cell's boundaries. |
|
Start/stop pattern |
This attribute is used to verify the quality of the pattern that marks the end points of the code. |
|
Unused Error Correction |
This is a measure of the extent in which regional or spot damage in the code has eroded the reading safety margin that error correction provides. |
Note that an overall symbol grade can also be returned, using McodeGetResult() with M_OVERALL_SYMBOL_GRADE. For 2D codes, this is a measure of the worst grade for the results of a specific code. For 1D codes, it is a measure of the average grade for the results of a specific code.
Other code attributes can also be evaluated with the grading operation, but they return a value as opposed to a grade.
To analyze whether a given cell is considered part of the foreground or the background, you can grade its modulation and/or reflectance margin. Both modulation and reflectance margin rely on your code's threshold. When reading a 2D code, if the grayscale value of a cell (also called its reflectance value) is above the threshold value, it is considered light. Values close to the threshold are considered ambiguous, while values further away are considered unambiguous. For example, consider a given 2D matrix code that has a symbol contrast of 255 and a computed threshold of 128. In this case, if a cell has a grayscale value of 255, it is a light cell. This is considered unambiguous since 255 is very far from 128. If a cell's grayscale value is 132, however, the cell is still considered light (since it is over the computed threshold), but the difference between the grayscale value of the cell and the threshold is low enough that the result is considered ambiguous by most grading specifications. In the following image, the circled cells are examples within the code that are considered ambiguous because those cells are closer to the threshold value than an unambiguous dark cell.
The modulation of a code is based on the difference between the computed threshold and the grayscale value of each cell (its reflectance), divided by the symbol contrast. A greater difference results in a greater modulation. The modulation can be calculated for each cell in the code and uses the following calculation:
The modulation is computed without regards to whether any cell should be light or dark. Instead, the modulation relies on the difference between the grayscale value of each cell and the code's threshold value. The greater this difference, the greater the modulation, and by association, the unambiguous claim that a cell should be either light or dark, respectively.
The following is a list of the different parts of the code for which you can retrieve the modulation grade:
To retrieve the modulation of the code, as a grade calculated using the ISO standard, use M_MODULATION_GRADE.
To retrieve the modulation of a code calculated using the ISO/IEC TR 29158:2011 standard, use M_CELL_MODULATION_GRADE.
To retrieve the modulation of each codeword as a grade, use M_CODEWORD_MODULATION_GRADE.
To retrieve the modulation of the start/stop patterns of 2D cross-row and composite code types, as a grade, use M_SCAN_MODULATION_GRADE.
The reflectance margin is similar to the modulation in that it is calculated using the threshold value and the grayscale value of the cell. The difference is that when any cell is supposed to be light and its grayscale value is below the threshold value, its reflectance margin is 0. The reflectance margin takes the expected state of any cell (that is, whether it is supposed to be light or dark) into account.
The following is a list of the different parts of the code for which you can retrieve the cell's grayscale value (its reflectance) and its reflectance margin grade:
To retrieve the reflectance margin grade of the code, use M_REFLECTANCE_MARGIN_GRADE.
To retrieve the minimum reflectance (grayscale value of the cell in the code), use M_MINIMUM_REFLECTANCE_GRADE.
To retrieve the reflectance margin of each codeword, use M_CODEWORD_REFLECTANCE_MARGIN_GRADE.
Note that, the reflectance of other code attributes can also be evaluated with the grading operation, but they return a value as opposed to a grade.
You can retrieve a measure of the decodability using M_DECODABILITY_GRADE. Decodability is a measure of how well the MIL Code module can read the code presented. By contrast, the decode grade is a grade denoting the success or failure of the decoding operation (A or F). You can retrieve the decode grade using M_DECODE_GRADE.
The range of decodability can sometimes result in a relatively low decodability that still results in a passing decode grade, or the opposite (a relatively high decodability that results in a failing decode grade). For example, with Code93 code types, each letter is represented by a specific number of bars and spaces, each of a predetermined width. If the code has a very low decodability grade, this should result in a failing decode grade (although a string might be decoded or partially decoded, depending on the success or failure of the related error checks). However, sometimes a passing decode grade is obtained while the decodability is relatively low. In such cases, the decodability of other parts of the code should be examined (such as the decodabiliy of the scan profile or codewords).
The following is a list of the different parts of the code for which you can retrieve the decodability grade:
To retrieve decodability grade of the entire code, use M_DECODABILITY_GRADE.
To retrieve the decodability grade of the scan reflectance profile, use M_SCAN_DECODABILITY_GRADE.
To retrieve the decodability grade for each codeword, use M_CODEWORD_DECODABILITY_GRADE.
To retrieve the decodability grade of the start/stop patterns of your code, use M_SCAN_DECODABILITY_GRADE.
The following is a list of control types in McodeControl() that you should typically set (if your code differs from the expected defaults) before grading a code:
Control type |
Notes |
Specifies the foreground color of the code. This control type must be set if the foreground color is not black; the code will not be graded if the foreground value is not correctly set. |
|
Specifies the type of encoding scheme for the code. This control type must be set if the default encoding scheme for your code's type differs from the one used by your code or if M_ANY is not supported. |
|
Specifies the type of error correction for the code. This control type must be set if the default error correction scheme for your code's type differs from the one used by your code or if M_ANY is not supported. |
|
Specifies the maximum and minimum size of the string (number of characters) encoded in each code. These control types must be set if M_STRING_SIZE_MIN and/or M_STRING_SIZE_MAX cannot be set to M_ANY. |
|
Specifies the nominal search angle and angular search range. These control types must be set if the code is at an angle greater or less than 0.0 ±5 degrees. |
The aperture is the diameter of the circular smoothing filter used by the code grade operation to avoid minor defects that might influence the grading of the code. Ideally, the aperture size is set large enough so that the smoothing effect eliminates insignificant defects and is set small enough so that the contrast between the foreground and the background remains strong. If the aperture is not set correctly, the grading results will not be accurate.
There are two ways to set the aperture for your MIL code:
Absolute aperture setting. To set your aperture size as a fixed value, use M_APERTURE_MODE set to M_ABSOLUTE.
MIL calculated aperture setting. To have MIL calculate the aperture size as a multiplicative factor of the cell size, use M_APERTURE_MODE set to M_RELATIVE.
The aperture size can be set for all code types.
To set the aperture size to a fixed value (so that it will not change regardless of the cell size of your code), first set the aperture mode to absolute, using M_APERTURE_MODE set to M_ABSOLUTE. Then, set the absolute aperture size to a fixed value, using M_ABSOLUTE_APERTURE_SIZE. The aperture size is set in units specified by M_ABSOLUTE_APERTURE_SIZE_INPUT_UNITS.
Setting the aperture mode to relative allows MIL to calculate the aperture size based on available data.
Data to use |
Calculation used |
||
Use standardized factors without specifying pixel size. |
Aperture Factor x M_CELL_SIZE , where Aperture Factor is a range from 0.15 to 0.8, depending on the code type and applicable standard. |
||
Use standardized factors and specify the pixel size. |
M_AUTO |
Pixel size in mm 1 |
For EAN/UPC code types, 0.15 / M_PIXEL_SIZE_IN_MM . For all other codes, Reference number/ M_PIXEL_SIZE_IN_MM , where Reference number is a range from 0.075 to 0.5, and is based on the cell size in millimeters (M_CELL_SIZE x M_PIXEL_SIZE_IN_MM) and the ISO 15416 specification. Note that, if the cell size in millimeters is less than 0.1 millimeters, the following formula is used: 0.5 x M_CELL_SIZE for 1D codes, and the aperture size is 0.8 x M_CELL_SIZE for matrix codes. |
Use the specified aperture factor and the pixel size. |
Aperture factor |
Pixel size in mm 1 |
1 Note that, specifying the aperture factor with a pixel size in mm is typically used when configuring your aperture to be calculated according to the exact guideline from the ISO industry-standardized print-quality specification.
To assist MIL in calculating your aperture setting, specify the pixel size of your code in millimeters. To determine the pixel size of your code in millimeters (M_PIXEL_SIZE_IN_MM), perform the following:
Physically measure the entire code with a ruler. Note that this result must be in millimeters.
Read the code from a typical image of the code, using McodeRead().
Determine the length of the code in pixels. This can be done in three different ways:
For Data Matrix and QR codes, multiply the cell size (McodeGetResult() with M_CELL_SIZE) by the number of cells across the code, as defined by the specification for your code type.
For 1D codes, use McodeGetResult() with M_SIZE_X, making sure that M_RESULT_OUTPUT_UNITS is set to M_PIXEL if the image was calibrated.
Use the MIL Measurement module to set two point markers to identify the start and end of your code, using MmeasSetMarker() with M_POSITION. Then, calculate the distance between two markers using MmeasCalculate().
Use an interactive tool, such as the MIL Code Reader Interactive Utility.
Divide the measurement in millimeters by the length of the code in pixels.
Set M_PIXEL_SIZE_IN_MM to this result.
Note that if the setup for acquiring the image of the code is significantly changed (making the acquired code either significantly larger or smaller than the code used to perform the pixels in millimeters calculation), the calculation should be performed again and M_PIXEL_SIZE_IN_MM set to the new value.
When grading Aztec, Data Matrix, QR code, or Micro QR code types, there are two verification standards to choose from: the direct part marking (DPM) standard, ISO/IEC TR 29158:2011, and the more general ISO standard, ISO/IEC 15415. The selected grading standard affects the implementation of some control types, and can cause different results when verifying the same code. The ISO/IEC TR 29158:2011 standard is an extension of the ISO/IEC 15415 standard and is intended for codes that are etched directly on a surface. The light and dark elements of these codes are determined by physically altered surface conditions, for example scratched and not scratched.
The ISO/IEC TR 29158:2011 standard is implemented in two phases: the reflectance calibration phase and the target verification phase. Each phase establishes the settings of the environmental factors that result in an acceptable image of a perfect reference code or a target code, respectively. The values of each phase are compared to produce the grades associated with the target code. Although the target code must be a Data Matrix code, QR code, or Micro QR code, the reference code can also be a 1D code.
During the reflectance calibration phase, you fine tune the location, camera, and/or lighting setup to ensure that the image of a good reference code has its mean light within a given range, because in this given range, the image has an acceptable reflectance. Note that the specification recommends using a test card (like the GS1 Data Matrix calibrated conformance standard test card or the NIST-traceable EAN/UPC calibrated conformance test card). The reflectance calibration phase will work regardless of the quality of reference code used. If grading the code according to the DPM specification, however, should initially be done using a standardized test card.
To begin, set the lighting according to the ISO/IEC TR 29158:2011 standard, and set the aperture to the recommended aperture for the reference code (typically, you use McodeControl() with M_APERTURE_MODE set to M_RELATIVE and M_RELATIVE_APERTURE_FACTOR set to M_AUTO); see the Setting the aperture subsection of this section for more information on setting the aperture. Next, take an image of the reference code, call McodeGrade(), and then retrieve the mean intensity of the white elements using McodeGetResult() with M_MEAN_LIGHT_CALIBRATION. Using this information, determine the mean light ratio (mean intensity/maximum grayscale value). If the mean light ratio is not within 70% and 86%, adjust your environmental factors and repeat the process until the mean light is acceptable.
You must then establish the System Response value (SRcal) for the reflectance calibration phase. The System Response value is a user-defined aggregate of environmental factors that you used to create the conditions for an acceptable code. For example, you could set the System Response value to be Exposure time + Gain factor.
To begin the target verification phase, you must set the verification standard to ISO/IEC TR 29158:2011 using McodeControl() with M_GRADING_STANDARD set to M_AIMDPM_GRADING. Once this is done, load the reflectance, mean light, and System Response values derived during the reflectance calibration phase, into the code context of the target code. Set the mean light and reflectance values using McodeControl() with M_AIMDPM_CALIBRATION_RESULTS. Alternatively, you can separately obtain the reflectance and mean light values from the result buffer used during the reflectance calibration phase, and set the values into the code context of the target code using McodeControl() with M_REFLECTANCE_CALIBRATION and M_MEAN_LIGHT_CALIBRATION, respectively. Then, set the System Response value derived from the reflectance calibration phase (SRcal) using McodeControl() with M_SYSTEM_RESPONSE_CALIBRATION.
After loading these values into the target code's context, acquire an image of the target code, such that all environmental factors are the same as the reflectance calibration phase, and set the System Response value for the target grading phase (using McodeControl() with M_SYSTEM_RESPONSE_TARGET). To set the System Response value, use the same formula as the one used during the reflectance calibration phase, mentioned previously. For example, if you set the System Response value for the reflectance calibration phase to the sum of the exposure time and gain factor, set the System Response value for the target grading phase to the sum of the exposure time and gain factor.
Once you set the System Response value and call McodeGrade(), test the mean light ratio using the same procedure used during the reflectance calibration phase, except use McodeGetResult() with M_MEAN_LIGHT_TARGET in place of M_MEAN_LIGHT_CALIBRATION. If the mean light ratio is not within the acceptable range of 70% to 86%, repeat the following process: fine tune the environmental factors that define the System Response value, re-acquire an image of the target code, re-calculate and set the System Response value, call McodeGrade(), and test the mean light ratio to ensure that it is within range. During the target grading phase, you should not alter any environmental factors other than those used to calculate the System Response value. If you are able to get the mean light within range, you can access the code's grades and results associated with ISO/IEC TR 29158:2011, such as M_OVERALL_SYMBOL_GRADE, M_CELL_CONTRAST_GRADE, and M_GRID_NONUNIFORMITY_GRADE, using McodeGetResult().
For more information, especially regarding the guidelines for lighting environments and reflectance calibration configurations, refer to the ISO/IEC TR 29158:2011 specification.
The following example contains an example of the reflectance calibration, target grading, and code grading for a Data Matrix based on ISO/IEC TR 29158:2011 specification.