DEV Community

Xiao Ling
Xiao Ling

Posted on • Originally published at dynamsoft.com

AI-Powered Model Revolutionizes Barcode and MRZ Recognition in Dynamsoft Capture Vision 3.2.1000

On October 14, 2025, Dynamsoft unveiled its most significant leap in computer vision yet — the AI-powered Dynamsoft Capture Vision (DCV) 3.2.1000. This release introduces groundbreaking deep learning models that transform how 1D barcodes and MRZs are detected and decoded, pushing the boundaries of accuracy, performance, and real-world reliability. In this article, we will walk through the process of evaluating these new capabilities using publicly available datasets and a Python-based comparison tool we previously developed.

Demo Video

  • Blurred 1D Barcode Recognition

  • MRZ Recognition

Prerequisites

AI-Powered Barcode and MRZ Detection

The core highlights of this release include:

  • Barcode: Deep neural network–based localization and decoding models designed to handle blurred, low-resolution, or partially damaged barcodes.
  • MRZ: A specialized deep learning model that delivers 42.7% faster processing with improved region detection accuracy for passport and ID recognition workflows.

Updating the Comparison Tool for MRZ

We previously developed a comparison tool to benchmark barcode recognition performance.

To extend this tool for MRZ evaluation, we made the following updates.

1. Add a Dropdown Button to Switch Between Barcode and MRZ Modes

mode_label = QLabel("Detection Mode:")
toolbar_layout.addWidget(mode_label)

self.detection_mode_combo = QComboBox()
self.detection_mode_combo.addItems(["Barcode", "MRZ"])
self.detection_mode_combo.setCurrentText("Barcode")
self.detection_mode_combo.currentTextChanged.connect(self.on_detection_mode_changed)
toolbar_layout.addWidget(self.detection_mode_combo)

def on_detection_mode_changed(self, mode: str):
    self.current_detection_mode = mode
    self.status_bar.showMessage(f"Detection mode changed to: {mode}")

    if hasattr(self, 'processing_thread') and self.processing_thread and self.processing_thread.isRunning():
        self.processing_thread.terminate()
        self.processing_thread.wait(1000)
        self.processing_thread = None

    self.progress_bar.setVisible(False)

    self.results.clear()
    self.results_table.setRowCount(0)
    self.image_files.clear()
    self.file_list.clear()
    self.new_files = []
    self.image_comparison.sdk1_scene.clear()
    self.image_comparison.sdk2_scene.clear()
    self.image_comparison.summary_label.setText(f"Detection mode: {mode} - Add images to begin comparison")
    self.image_comparison.sdk1_results_text.clear()
    self.image_comparison.sdk2_results_text.clear()

    if mode == "Barcode":
        self.results_table.setHorizontalHeaderLabels(["Image", "SDK 1", "SDK 2", "Barcode Δ", "Speed Δ"])
    elif mode == "MRZ":
        self.results_table.setHorizontalHeaderLabels(["Image", "SDK 1", "SDK 2", "MRZ Δ", "Speed Δ"])

Enter fullscreen mode Exit fullscreen mode

2. Update the Python Script to Handle MRZ Mode in the Subprocess

script_content = f'''#!/usr/bin/env python3
import sys
import json
import time
import os
from dynamsoft_capture_vision_bundle import *

LICENSE_KEY = "LICENSE-KEY"

def process_image(image_path, detection_mode):


    # Initialize license
    error_code, error_message = LicenseManager.init_license(LICENSE_KEY)
    if error_code not in [EnumErrorCode.EC_OK, EnumErrorCode.EC_LICENSE_CACHE_USED]:
        return {{"success": False, "error": f"License error: {{error_message}}", "detection_mode": detection_mode}}

    # Process image
    cvr = CaptureVisionRouter()

    # Select template based on detection mode
    if detection_mode == "Barcode":
        template = EnumPresetTemplate.PT_READ_BARCODES.value
    elif detection_mode == "Document":
        template = EnumPresetTemplate.PT_DETECT_AND_NORMALIZE_DOCUMENT.value
    elif detection_mode == "MRZ":
        template = "ReadPassportAndId"
    else:
        template = EnumPresetTemplate.PT_READ_BARCODES.value  # Default

    try:
        cvr.capture(image_path, template) # Trigger model loading the first time
    except Exception as e:
        pass  # Ignore first capture errors for model loading

    start_time = time.time()
    result = cvr.capture(image_path, template)
    processing_time = time.time() - start_time

    error_code = result.get_error_code()
    items = result.get_items()

    # Error -10005 often just means "no results found" for any detection mode
    # This is not necessarily a failure, just empty results
    if error_code != EnumErrorCode.EC_OK:
        if error_code == -10005:
            # No results found - return empty results but success
            pass  # Continue with empty items list
        else:
            return {{"success": False, "error": f"Capture error: {{error_code}}", "detection_mode": detection_mode}}

    # Initialize result containers
    barcodes = []
    mrz_results = []
    document_results = []

    # Process items based on detection mode  
    for item in items:
        item_type = item.get_type()

        if detection_mode == "Barcode" and item_type == 2:  # Barcode item (CRIT_BARCODE = 2)
            barcode_data = {{
                "text": item.get_text(),
                "format": item.get_format_string(),
                "confidence": getattr(item, 'get_confidence', lambda: 0.0)()
            }}

            # Get location points
            try:
                location = item.get_location()
                if location and hasattr(location, 'points'):
                    barcode_data["points"] = [
                        [int(location.points[0].x), int(location.points[0].y)],
                        [int(location.points[1].x), int(location.points[1].y)],
                        [int(location.points[2].x), int(location.points[2].y)],
                        [int(location.points[3].x), int(location.points[3].y)]
                    ]
                else:
                    barcode_data["points"] = []
            except:
                barcode_data["points"] = []

            barcodes.append(barcode_data)

        elif detection_mode == "MRZ" and item_type == 4:  # Text line item (CRIT_TEXT_LINE = 4)
            text = item.get_text()
            mrz_data = {{
                "text": text,
                "parsed_info": {{}},  # Could be expanded to parse MRZ fields
                "points": []
            }}

            # Get location points
            try:
                location = item.get_location()
                if location and hasattr(location, 'points'):
                    mrz_data["points"] = [
                        [int(location.points[0].x), int(location.points[0].y)],
                        [int(location.points[1].x), int(location.points[1].y)],
                        [int(location.points[2].x), int(location.points[2].y)],
                        [int(location.points[3].x), int(location.points[3].y)]
                    ]
            except:
                mrz_data["points"] = []

            mrz_results.append(mrz_data)

    return {{
        "success": True,
        "detection_mode": detection_mode,
        "processing_time": processing_time,
        "barcodes": barcodes,
        "mrz_results": mrz_results,
    }}

if __name__ == "__main__":
    detection_mode = sys.argv[2] if len(sys.argv) > 2 else "Barcode"
    result = process_image(sys.argv[1], detection_mode)
    print(json.dumps(result))
'''
Enter fullscreen mode Exit fullscreen mode

Note: The first call to cvr.capture() triggers AI model loading. To measure true image-processing time, the script calls cvr.capture() twice.

Dataset Preparation and Testing

To evaluate the new AI-powered models, we used two public datasets:

Barcode dataset

Barcodes200909

We used the Dataset3 folder (images at 1152×864 resolution, taken with an older Nokia 7610 phone lacking autofocus) to benchmark 1D barcode recognition.

Detect 1D barcodes with AI models

MRZ dataset

L3i MRZ Dataset

Reference

K.B. Bulatov, E.V. Emelianova, D.V. Tropin, N.S. Skoryukina, Y.S. Chernyshova, A.V. Sheshkus, S.A. Usilin, Z. Ming, J.-C. Burie, M. M. Luqman, V.V. Arlazarov: “MIDV-2020: A Comprehensive Benchmark Dataset for Identity Document Analysis”, Computer Optics (submitted), 2021.

We used the aze_passport folder for MRZ recognition benchmarking.

Recognize MRZ with AI models

Source Code

https://github.com/yushulx/python-barcode-qrcode-sdk/edit/main/examples/official/comparison_tool

Top comments (0)