О насБлогКонтакты
ИИ и машинное обучение5 апреля 2013 г. 3 мин 139Обновлено: 22 июня 2026 г.

Компьютерное зрение: первые попытки OCR в мобильных приложениях

AunimedaAunimeda
📋 Содержание

В начале 2013 года концепция была разумной: сотрудники подают авансовые отчёты, фотографируя чеки телефоном. Приложение читает чек, извлекает сумму, дату и продавца, автозаполняет форму расходов.

Реализация потребовала более глубокого понимания Optical Character Recognition, чем мы ожидали.


Tesseract OCR: open-source стандарт

Tesseract разрабатывался в Hewlett-Packard в 1980-х, выпущен в open-source в 2005, принят Google в 2006. К 2013 году Tesseract 3.02 был наиболее точным доступным OCR-движком с открытым исходным кодом.

Мы компилировали его под iOS:

#import "Tesseract.h"

@implementation ReceiptOCRProcessor

- (NSString *)extractTextFromImage:(UIImage *)image {
    Tesseract *tesseract = [[Tesseract alloc] initWithLanguage:@"eng"];
    
    // Режим сегментации страницы 6 = один блок текста (хорошо для чеков)
    [tesseract setVariableValue:@"6" forKey:@"tessedit_pageseg_mode"];
    
    // Белый список символов улучшает точность
    [tesseract setVariableValue:@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.,/$:-()" 
                        forKey:@"tessedit_char_whitelist"];
    
    [tesseract setImage:image];
    [tesseract recognize];
    return [tesseract recognizedText];
}
@end

Сырой результат на реальном фото чека (камера iPhone 5):

МАГАЗИН №1823
ГЛ. УЛ. 15

МОЛОКО 2.5% 1Л     85.00
ХЛЕБ ПШЕНИЧНЫЙ    45.00
ЯЙЦА С1 10ШТ       95.00

ИТОГО:           225.О0   ← '0' вместо '0'
НАЛИЧНЫЕ:        300.00
СДАЧА:            75.00

«225.О0» вместо «225.00» - буква О вместо цифры ноль. 68% точность символов на 20 тестовых чеках. Примерно 1 из 3 символов был неправильным или пропущенным. Нельзя использовать как сырой вывод.


Пайплайн предобработки

OCR сильно зависит от качества изображения. Tesseract разрабатывался для отсканированных документов - горизонтальных, высокого разрешения, равномерного освещения. Фотографии чеков с камеры телефона не были никакими из этих: перекошенные, низкоконтрастные, переменное освещение.

Мы построили пайплайн предобработки в OpenCV:

- (UIImage *)preprocessForOCR:(UIImage *)inputImage {
    cv::Mat gray;
    cv::cvtColor(mat, gray, cv::COLOR_RGB2GRAY);
    
    // Увеличить разрешение если слишком маленькое
    if (gray.cols < 1000) {
        double scale = 1000.0 / gray.cols;
        cv::resize(gray, gray, cv::Size(), scale, scale, cv::INTER_CUBIC);
    }
    
    // Исправление перекоса
    gray = [self deskewImage:gray];
    
    // Адаптивная пороговая обработка - обрабатывает неравномерное освещение
    cv::Mat thresh;
    cv::adaptiveThreshold(gray, thresh, 255,
        cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY,
        11, 2);
    
    // Удаление шума
    cv::Mat denoised;
    cv::medianBlur(thresh, denoised, 3);
    
    return MatToUIImage(denoised);
}

После предобработки точность символов выросла с 68% до 81%.


Извлечение структурированных данных

def extract_receipt_data(ocr_text):
    result = {'vendor': None, 'date': None, 'total': None}
    lines = [l.strip() for l in ocr_text.split('\n') if l.strip()]
    
    if lines:
        result['vendor'] = lines[0]
    
    # Паттерны для суммы
    total_patterns = [
        r'(?:итого|итог|сумма)[:\s]+(\d+[\.,]\d{2})',
        r'(?:к оплате|к получению)[:\s]+(\d+[\.,]\d{2})',
    ]
    
    full_text = ' '.join(lines).lower()
    for pattern in total_patterns:
        match = re.search(pattern, full_text, re.IGNORECASE)
        if match:
            result['total'] = float(match.group(1).replace(',', '.'))
            break
    
    if not result['total']:
        # Если явной суммы нет - берём наибольшую сумму (обычно это итог)
        amounts = re.findall(r'\b(\d+\.\d{2})\b', full_text)
        if amounts:
            result['total'] = max(float(a) for a in amounts)
    
    return result

Слой исправления ошибок

81% точность на символах означала некоторые некорректные извлечения полей. Добавили шаг подтверждения пользователем:

- (void)showExtractionConfirmation:(NSDictionary *)extracted {
    // Предзаполняем форму извлечёнными данными
    self.vendorField.text = extracted[@"vendor"] ?: @"";
    self.amountField.text = extracted[@"total"] ? 
        [NSString stringWithFormat:@"%.2f", [extracted[@"total"] floatValue]] : @"";
    
    // Подсвечиваем поля с низкой уверенностью
    if (!extracted[@"total"]) {
        [self highlightFieldAsNeedsReview:self.amountField];
    }
    
    // Показываем оригинальное фото рядом для сверки
    self.receiptImageView.image = self.capturedImage;
}

Паттерн «машинное извлечение + подтверждение пользователем» повысил принятие. Пользователи доверяли приложению, потому что могли видеть фото и проверить извлечённые данные. Исправления стали обучающими данными для улучшения модели.


Что пришло после

К 2016 году Google Cloud Vision API и Amazon Textract сделали OCR чеков тривиальной задачей. Отправь фото на API - получи структурированный JSON с извлечённым текстом. Точность 95%+.

К 2020 году on-device модели ML (Core ML на iOS) запускали OCR чеков полностью офлайн с точностью, сравнимой с облачными API 2016 года.

Система 2013 года - Tesseract, предобработка OpenCV, regex-извлечение, подтверждение пользователем - была заменена одним API-вызовом.

Обучение не пропало. Понимание предобработки изображений показало: качество важнее алгоритма для задач компьютерного зрения. Понимание провалов Tesseract сделало нас грамотными пользователями API, пришедших на замену. «Мусор на входе - мусор на выходе» применимо к ML-системам любого уровня сложности.

Читайте также

Ранние NLP: строим чат-боты до эпохи LLMaunimeda
ИИ и машинное обучение

Ранние NLP: строим чат-боты до эпохи LLM

В 2013 мы построили бота поддержки клиентов с regex-паттернами, деревьями решений и классификатором Naive Bayes. Никаких нейросетей, никаких эмбеддингов. Вот как выглядело rule-based NLP на самом деле.

Предиктивная аналитика в e-commerce: как ранний ML генерировал «Товары, которые вам понравятся»aunimeda
ИИ и машинное обучение

Предиктивная аналитика в e-commerce: как ранний ML генерировал «Товары, которые вам понравятся»

У Amazon была система рекомендаций с 2003 года. В 2013 мы построили свою для регионального ритейлера. Коллаборативная фильтрация, сходство элементов и SQL-запросы, от которых потела БД.

DeepSeek и открытые ИИ-модели: что изменилось для бизнеса в Кыргызстане в 2026aunimeda
ИИ и машинное обучение

DeepSeek и открытые ИИ-модели: что изменилось для бизнеса в Кыргызстане в 2026

В январе 2025 DeepSeek R1 вышел с качеством GPT-4 и открытым кодом. К 2026 году открытые модели изменили стоимость AI-решений для малого бизнеса. Что это значит конкретно для бизнеса в Бишкеке?

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Кыргызстане. Бесплатная консультация.

Получить консультацию Все статьи