Barcode Detection
Note
This API requires a valid software license.
The barcode detection API allows you to detect and decode barcodes in a 2D image.
Barcodes are a visual, machine-readable representation of data, typically in a pattern of parallel lines, spaces or shapes that encode information such as product numbers. Zivid SDK supports the following linear (1D) and matrix (2D) barcode formats:
Linear: EAN-13, EAN-8, Code 128, Code 93, Code 39, UPC-A [1], UPC-E, ITF
Matrix: QR Code, Data Matrix
Examples of supported barcode formats.
Barcodes may come in various sizes, where the width of the smallest bar or space is the main sizing parameter. This smallest feature is called the module size (or X-dimension), and it is commonly expressed in mils, where one mil is 1/1000 inch (0.0254 mm). For example, standard retail linear barcodes typically vary between 7 mil (0.178 mm) and 13 mil (0.330 mm). Smaller barcodes require higher resolution to be detected and decoded reliably.
Examples of different Code 128 barcode sizes captured from the same distance.
Barcode Detection API
Start by initializing the barcode detector. Note that this should only be done once and not for every capture.
Then specify which of the supported barcode formats to detect, rather than looking for all formats. This will speed up detection and make decoding more robust. In this example we generalize and select all supported formats for simplicity.
// Select your specific barcode formats for optimal performance
const auto linearFormatFilter = LinearBarcodeFormat::code128 | LinearBarcodeFormat::code93
| LinearBarcodeFormat::code39 | LinearBarcodeFormat::ean13
| LinearBarcodeFormat::ean8 | LinearBarcodeFormat::upcA
| LinearBarcodeFormat::upcE | LinearBarcodeFormat::itf;
const auto matrixFormatFilter = MatrixBarcodeFormat::qrcode | MatrixBarcodeFormat::dataMatrix;
# Select your specific barcode formats for optimal performance
linear_format_filter = {
LinearBarcodeFormat.code128,
LinearBarcodeFormat.code93,
LinearBarcodeFormat.code39,
LinearBarcodeFormat.ean13,
LinearBarcodeFormat.ean8,
LinearBarcodeFormat.upcA,
LinearBarcodeFormat.upcE,
LinearBarcodeFormat.itf,
}
matrix_format_filter = {MatrixBarcodeFormat.qrcode, MatrixBarcodeFormat.dataMatrix}
Successfully detecting and decoding barcodes depends heavily on a sharp and well-exposed 2D image. Use the suggested 2D settings from the barcode detector and capture a 2D frame.
Linear barcodes are detected and decoded in two steps. Detection identifies candidate regions in the image that are likely to contain a barcode. Since decoding has not yet been attempted, the list may include false positives. These are regions that resemble a barcode but are not. Decoding reads the actual code from each candidate. If a candidate could not be decoded, the corresponding result is empty.
Note
For a simpler one-call alternative, use readLinearCodes, which combines detection and decoding into a single function call.
The two-phase approach gives you explicit access to candidate regions and their bounding boxes before decoding.
Detect linear barcode candidate regions:
Then decode the detected candidates:
Print the candidates alongside their decoded results. Each detection candidate exposes its bounding box, and each decoded result exposes the code, format, and its own bounding box:
if(!detectionResults.empty())
{
std::cout << "Detected " << detectionResults.size() << " linear barcode candidates:" << std::endl;
for(size_t i = 0; i < detectionResults.size(); ++i)
{
std::cout << "-- Candidate " << (i + 1) << ":" << std::endl;
std::cout << " Bounding box: " << detectionResults[i].boundingBox() << std::endl;
const auto &decodingResult = decodingResults[i];
if(decodingResult.has_value())
{
const auto &decoded = decodingResult.value();
std::cout << " Code: " << decoded.code() << std::endl;
std::cout << " Format: " << toString(decoded.codeFormat()) << std::endl;
std::cout << " Bounding box: " << decoded.boundingBox() << std::endl;
}
else
{
std::cout << " Failed to decode" << std::endl;
}
}
}
else
{
std::cout << "No linear barcode candidates detected" << std::endl;
}
if detection_results:
print(f"Detected {len(detection_results)} linear barcode candidates:")
for i, (candidate, decoded) in enumerate(zip(detection_results, decoding_results, strict=False)):
print(f"-- Candidate {i + 1}:")
print(f" Bounding box: {candidate.bounding_box()}")
if decoded is not None:
print(f" Code: {decoded.code()}")
print(f" Format: {decoded.code_format()}")
print(f" Bounding box: {decoded.bounding_box()}")
else:
print(" Failed to decode")
else:
print("No linear barcode candidates detected")
Matrix barcodes do not have a two-phase API.
Use readMatrixCodes to detect and decode in a single call:
Print the decoded matrix barcodes with their bounding boxes:
if(!matrixBarcodeResults.empty())
{
std::cout << "Detected " << matrixBarcodeResults.size() << " matrix barcodes:" << std::endl;
for(const auto &result : matrixBarcodeResults)
{
std::cout << "-- Code: " << result.code() << std::endl;
std::cout << " Format: " << toString(result.codeFormat()) << std::endl;
std::cout << " Bounding box: " << result.boundingBox() << std::endl;
}
}
else
{
std::cout << "No matrix barcodes detected" << std::endl;
}
Barcode Detection in Zivid Studio
Tip
Barcode detection in Zivid Studio does not require a software license.
You can easily test barcode detection using Zivid Studio. Connect to a camera and perform a 2D capture of a scene containing barcodes by selecting the barcode preset. Then click on View → Show barcodes to visualize decoded barcodes in the image.
Detected barcodes visualized in Zivid Studio.
You can speed up the detection by selecting your specific barcode format in View → Configure barcodes to detect.
Barcode Detection Performance
The performance of detection and decoding depends on multiple factors, including:
Barcode size
Distance to barcode
Image resolution
Image focus
Horizontal and vertical FOV
These factors effectively make up the spatial resolution on the barcode surface, which is important to maximize for reliable detection and decoding.
Image resolution and focus can be controlled by the camera settings, where we recommend BarcodeDetector::suggestSettings(camera) for optimal capture settings.
The camera’s horizontal and vertical FOV are fixed for each camera model, where larger FOVs lead to lower spatial resolution.
Distance to the barcode can be controlled by the application within some constraints, but is also limited by the camera’s working range.
The recommended cameras for barcode detection are therefore Zivid 2+ MR130 and MR60, as these provide sufficient spatial resolution within their working ranges. Below are some benchmarks for a variety of static barcodes qualified at different distances, orientations and placements within the FOV.
Tip
Stay within the green area for reliable decoding results.
Version History
SDK |
Changes |
|---|---|
2.18.0 |
Linear barcode detection and decoding are now separated into two steps.
|
2.17.0 |
Barcode detection API is added. |