import re # Маппинг латиница → кириллица для российских номеров LATIN_TO_CYRILLIC = { 'A': 'А', 'B': 'В', 'E': 'Е', 'K': 'К', 'M': 'М', 'H': 'Н', 'O': 'О', 'P': 'Р', 'C': 'С', 'T': 'Т', 'Y': 'У', 'X': 'Х' } # Исправление ошибок OCR OCR_CORRECTIONS = { '0': 'О', 'Q': 'О', 'D': 'О', # Нули → О 'I': '1', 'l': '1', '|': '1', # I → 1 'S': '5', 'Z': '2', 'B': '8', # Похожие } def normalize_russian_plate(text): """ Нормализация российского номера Формат: К181КК123 (1 буква, 3 цифры, 2 буквы, 2-3 цифры региона) """ text = text.upper().replace(' ', '').replace('-', '').replace('_', '') result = [] for i, char in enumerate(text): # Позиция 0: буква if i == 0: if char.isdigit() and char in OCR_CORRECTIONS: char = OCR_CORRECTIONS[char] if char in LATIN_TO_CYRILLIC: char = LATIN_TO_CYRILLIC[char] # Позиции 1-3: цифры elif 1 <= i <= 3: if not char.isdigit(): for ocr_char, correction in OCR_CORRECTIONS.items(): if char == correction and ocr_char.isdigit(): char = ocr_char break # Позиции 4-5: буквы серии elif 4 <= i <= 5: if char.isdigit() and char in OCR_CORRECTIONS: char = OCR_CORRECTIONS[char] if char in LATIN_TO_CYRILLIC: char = LATIN_TO_CYRILLIC[char] result.append(char) return ''.join(result) def is_valid_russian_plate(text): """Проверка формата российского номера""" patterns = [ r'^[АВЕКМНОРСТУХ]\d{3}[АВЕКМНОРСТУХ]{2}\d{2,3}$', # К181КК123 r'^[АВЕКМНОРСТУХ]{2}\d{5,6}$', # Такси r'^\d{4}[АВЕКМНОРСТУХ]{2}\d{2,3}$', # Прицепы ] for pattern in patterns: if re.match(pattern, text): return True if 8 <= len(text) <= 9: has_letters = any(c.isalpha() for c in text) has_digits = any(c.isdigit() for c in text) return has_letters and has_digits return False def enhance_plate_for_russian(label, confidence): """ Улучшение результата для российского номера Возвращает (normalized_label, adjusted_confidence, is_russian) """ if not label: return label, confidence, False # Логируем исходный текст print(f"🔍 ALPR: OCR вернул: '{label}' (confidence: {confidence:.3f})") # Нормализация normalized = normalize_russian_plate(label) print(f"🔄 ALPR: После нормализации: '{normalized}'") # Проверка валидности is_russian = is_valid_russian_plate(normalized) print(f"✓ ALPR: Валидный формат: {is_russian}") # Корректировка уверенности if is_russian: adjusted_conf = min(confidence * 1.1, 1.0) print(f"📈 ALPR: Confidence: {confidence:.3f} → {adjusted_conf:.3f}") else: adjusted_conf = confidence * 0.7 print(f"📉 ALPR: Confidence понижен: {confidence:.3f} → {adjusted_conf:.3f}") return normalized, adjusted_conf, is_russian