Barcode and QR Code Recognition from Images

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
Barcode and QR Code Recognition from Images
Simple
from 1 business day to 3 business days
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823
  • image_logo-aider_0.jpg
    AIDER company logo development
    762
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    848

Реализация распознавания штрихкодов и QR-кодов с изображений

Распознавание штрихкодов и QR-кодов — задача, которую в большинстве случаев решают специализированные библиотеки без глубокого обучения. ML-компонент добавляется для детекции кода на изображении при плохом качестве или нестандартных условиях съёмки.

Стандартная интеграция через ZXing и ZBar

import cv2
import numpy as np
from pyzbar.pyzbar import decode
from pyzbar.pyzbar import ZBarSymbol

class BarcodeScanner:
    def __init__(self):
        pass

    def decode_all(self, image: np.ndarray) -> list[dict]:
        """Декодирование всех кодов на изображении"""
        # pyzbar работает с PIL или numpy array
        decoded_objects = decode(image)

        results = []
        for obj in decoded_objects:
            results.append({
                'type': obj.type,
                'data': obj.data.decode('utf-8', errors='replace'),
                'polygon': [(p.x, p.y) for p in obj.polygon],
                'rect': {
                    'left': obj.rect.left,
                    'top': obj.rect.top,
                    'width': obj.rect.width,
                    'height': obj.rect.height
                }
            })

        return results

    def decode_qr_only(self, image: np.ndarray) -> list[dict]:
        return [r for r in self.decode_all(image) if r['type'] == 'QRCODE']

    def decode_barcodes_only(self, image: np.ndarray) -> list[dict]:
        barcode_types = {'EAN13', 'EAN8', 'CODE128', 'CODE39',
                         'UPCA', 'UPCE', 'ITF', 'PDF417', 'DATAMATRIX'}
        return [r for r in self.decode_all(image)
                if r['type'] in barcode_types]

Поддерживаемые форматы

Формат Применение
QR Code URL, vCard, мобильные платежи
EAN-13 / EAN-8 Товары в рознице
Code 128 Логистика, авиабилеты
PDF417 Права, паспорта, посадочные талоны
Data Matrix Медицинские препараты, электроника
Aztec Транспортные билеты
Code 39 Промышленность
ITF-14 Групповая упаковка

Предобработка для улучшения распознавания

def preprocess_for_barcode(image: np.ndarray) -> list[np.ndarray]:
    """Несколько вариантов предобработки для повышения шансов декодирования"""
    variants = []

    # Оригинал
    variants.append(image)

    # Grayscale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    variants.append(gray)

    # Повышение контраста
    clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
    enhanced = clahe.apply(gray)
    variants.append(enhanced)

    # Адаптивная бинаризация
    binary = cv2.adaptiveThreshold(gray, 255,
                                    cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                    cv2.THRESH_BINARY, 51, 2)
    variants.append(binary)

    # Масштабирование (для маленьких штрихкодов)
    if image.shape[0] < 300:
        scale_factor = 300 / image.shape[0]
        big = cv2.resize(image, None, fx=scale_factor, fy=scale_factor,
                          interpolation=cv2.INTER_CUBIC)
        variants.append(big)

    return variants

def robust_decode(image: np.ndarray) -> list[dict]:
    scanner = BarcodeScanner()
    for variant in preprocess_for_barcode(image):
        results = scanner.decode_all(variant)
        if results:
            return results
    return []

ML-детекция для сложных случаев

Когда стандартные библиотеки не справляются (повреждённые коды, сильное искажение перспективы, низкое разрешение) — добавляем ML-детектор:

from ultralytics import YOLO

# YOLOv8, дообученный на датасете штрихкодов
barcode_detector = YOLO('barcode_detector.pt')

def detect_and_decode(image: np.ndarray) -> list[dict]:
    # Детектируем регионы с кодами
    detections = barcode_detector(image, conf=0.4)

    results = []
    for box in detections[0].boxes.xyxy:
        x1, y1, x2, y2 = map(int, box)
        # Небольшой отступ
        pad = 5
        crop = image[max(0,y1-pad):y2+pad, max(0,x1-pad):x2+pad]

        # Исправление перспективы кропа
        corrected = correct_perspective(crop)

        # Попытка декодирования
        decoded = robust_decode(corrected)
        results.extend(decoded)

    return results

Video stream сканирование

def scan_video_stream(camera_id: int = 0, callback=None):
    cap = cv2.VideoCapture(camera_id)
    scanner = BarcodeScanner()
    last_results = set()

    while True:
        ret, frame = cap.read()
        if not ret:
            break

        results = scanner.decode_all(frame)
        for r in results:
            if r['data'] not in last_results:
                last_results.add(r['data'])
                if callback:
                    callback(r)
Задача Срок
Базовое сканирование через pyzbar 3–5 дней
Робастный декодер с предобработкой 1–2 недели
ML-детекция + декодирование поврежденных кодов 3–5 недель