На машиностроительном производстве расчет стоимости детали начинается с чертежа. Входящий запрос выглядит так: PDF и строчка «нужно 50 штук». Чтобы назвать цену, технолог открывает чертеж и вручную снимает параметры: тип детали, габариты, квалитеты, шероховатости, резьбы, материал, массу. Один чертеж — от 5 до 15 минут. При потоке в несколько десятков запросов в день это основная нагрузка на технолога.


Мы разобрали, из чего эта нагрузка состоит. Технолог последовательно делает девять операций:
Определяет тип детали — тело вращения (вал, втулка) или призматика (плита, корпус): от этого зависит, токарный нужен станок или фрезерный;
Снимает габаритные размеры — они определяют заготовку и оборудование;
Считает общее число размеров — влияет на трудоёмкость;
Находит квалитет самого точного размера: IT6 — шлифовка, IT14 — черновое фрезерование, разница в цене может быть пятикратной;
Определяет минимальную шероховатость: Ra 0.8 и Ra 12.5 требуют разных операций;
Считает резьбы — каждая резьба это отдельный переход;
Извлекает материал из штампа — сталь 45 и титан ВТ-6 обрабатываются по‑разному;
Берёт массу детали;
Фиксирует наличие и количество сечений — по ним судят о внутренней геометрии.
Все эти параметры нужны расчётной системе на входе. Задача была автоматизировать их извлечение из PDF‑чертежа.
Как устроен пайплайн
На вход система получает PDF с чертежом — это может быть экспорт из CAD или скан бумажного оригинала. Дальше: растеризация, детекция областей, размеров и символов, контуров, OCR, технический анализ — на выходе JSON. Схема выглядит линейно, но за каждым шагом своя механика.
Детекция — это шесть отдельных YOLO‑моделей, не одна. OCR кастомный, обученный на инженерных шрифтах по ГОСТ. Контуры извлекаются через разделение линий по толщине. Габариты определяются через стрелочную логику, а не прямым чтением чисел. Постобработка — несколько слоёв регулярных выражений.
Регулярки в итоге заняли примерно столько же кода, сколько вся детекция. Это не план — так получилось, когда начали разбирать реальные чертежи.
Проблема масштаба: чертеж А1 не влезает в YOLO
Чертеж А1 при растеризации в 288 DPI даёт картинку 5000×7000 пикселей. YOLO обучена на 640×640 пикселях. Простое уменьшение убивает мелкие размеры и символы. Нарезка на фрагменты — стандартный путь, но объекты на границах фрагментов детектируются плохо.
Вместо этого — детекция на нескольких масштабах параллельно. Чертеж прогоняется на DPI 10, 20, 50, 70. На DPI 10 весь А1 — это ~170×240 пикселей: штамп, который на полном разрешении занимает 3% площади, на этом масштабе детектируется стабильно. Координаты масштабируются обратно к оригиналу. Каждый следующий масштаб добавляет только то, чего не нашли на предыдущем — дедупликация через IoU.

Шесть моделей на один чертеж
Штрихпунктирная ось и индекс допуска высотой 10 пикселей — слишком разные объекты по масштабу и контексту, чтобы одна модель одинаково хорошо видела оба. Детекция разбита на шесть специализированных YOLO:
Области — проекции (виды детали) и штамп с метаданными; это первый шаг, без него непонятно, где искать все остальное
Размеры — числовые значения размеров, верхние и нижние индексы допусков
Метаданные — четыре поля штампа: название детали, код, материал, масса
Оси вращения — штрихпунктирные линии через центр тел вращения; порог уверенности намеренно низкий — 0.1, потому что штрихпунктир слабо контрастен на любом DPI
Шероховатости — символы Ra; отдельная модель, потому что символ Ra визуально не похож ни на размер, ни на текст штампа
Сечения — различает одиночную букву на линии разреза (А) и заголовок сечения (А‑А); нужно для определения главного вида
Стрелки — размерные линии; по ним определяются габаритные размеры через стрелочную логику
Толстая линия против тонкой
Задача: внутри проекции выделить контур детали и отсечь размерные линии, выносные линии и текст. Без этого непонятно, какая стрелка идёт снаружи детали, а какая проходит через неё.
По ГОСТ контур детали — толстая линия (0.5–1.4 мм), размерные и выносные — тонкая (0.25–0.7 мм). Разница в толщине — единственный машиночитаемый признак, по которому их можно разделить:
Бинаризация изображения.
Distance transform — расстояние от каждого пикселя линии до ближайшего фона. В центре толстой линии оно больше.
Скелетизация по Zhang‑Suen — все линии к толщине 1 пиксель.
Значения distance transform на скелете дают полутолщину каждой линии.
Порог Otsu по этим значениям разделяет два кластера толщин.
После отсечения тонких линий берётся наибольшая непрерывная область — это контур детали.
На 288 DPI толстая и тонкая линия отличаются на 1–2 пикселя — порог Otsu там нестабилен. Поэтому контуры извлекаются на 1200 DPI, где толстая линия — 5–7 пикселей, тонкая — 2–3. Каждая проекция обрабатывается отдельно в ThreadPoolExecutor, resize с GPU при наличии CUDA.
Стрелки: как найти габаритный размер
Габаритная стрелка на чертеже всегда идёт снаружи контура детали. Стрелки внутренних размеров — через него. Это и есть способ их различить.
Для цилиндрической детали: находим ось на главном виде, ищем стрелку параллельную оси, которая не пересекается с контуром и по длине близка к нему. Найденная стрелка сопоставляется с ближайшим числовым значением размера.
Для прямоугольной: горизонтальная и вертикальная стрелки с длиной, совпадающей с шириной и высотой контура. Третий габарит — с соседней проекции.
Если подходящая стрелка не найдена, запускается цепочка запасных сценариев: поиск на связанном сечении → максимальный размер параллельный оси → максимальный на главном виде → максимальный на любой проекции. Каждый следующий шаг менее точен. Без этой цепочки часть чертежей выпадала из обработки целиком.
OCR: семь попыток на каждый текст
Взяли PaddleOCR с кастомной моделью на инженерных шрифтах по ГОСТ.
Стандартная модель не справлялась: текст на чертеже стоит под 0°, 90°, 270° и промежуточными углами, индексы допусков — 10–15 пикселей высотой, символы ∅, ±, °, Ra, линии проходят вплотную к тексту или через него. Каждый блок прогоняется под семью углами: −90°, −45°, 0°, 45°, 90°, 180°, 270°.
Совпадающие результаты получают бонус, угол 0° — небольшой дополнительный: горизонтальный текст встречается чаще всего.
Индексы допусков и значения Ra перед распознаванием масштабируются до 64 пикселей по высоте. На исходном размере OCR на них ошибается.
Отдельная проблема: индекс допуска стоит вплотную к размеру. OCR читает «∅50+0.025−0.016» как одну строку вместо «∅50». Перед распознаванием основного размера индексы закрашиваются цветом фона.
Сечения: А и А‑А — не одно и то же
На чертеже сечение обозначается парой: одиночные буквы (А...А) на линии разреза главного вида и заголовок А‑А над проекцией‑сечением. Модель различает два класса — одиночная буква и двойная. Заголовок А‑А должен находиться в верхних 7% проекции или непосредственно над ней — по этому условию они связываются.
Зачем это нужно: сечения исключаются при определении главного вида. Главный вид — проекция с максимальным числом размеров среди не‑сечений. При равном количестве — приоритет у проекции выше и левее: по ГОСТ главный вид в верхнем левом углу.
OCR на буквах сечений стабильно путает кириллицу с латиницей: А/A, В/B, С/C. Добавили таблицу нормализации — не совсем красиво, но это был оптимальный вариант из возможных на тот момент.
Извлечение метаданных из таблицы
Штамп содержит четыре поля: название детали, код, материал, масса. YOLO находит боксы этих полей, PaddleOCR распознаёт все текстовые блоки в области штампа. Дальше нужно связать одно с другим — через IoU между боксом поля и текстовыми блоками.
Порог IoU намеренно низкий: текст может частично выходить за границы бокса, особенно если название разбито на две строки.
Поле материала разваливается чаще остальных — длинный текст, часто многострочный, с номером ГОСТ. Для него три запасных сценария, последний — поиск по слову «ГОСТ» среди всех текстов штампа. Плюс нормализация типовых OCR‑ошибок: «ГСТАЛЬ» → «СТАЛЬ», «ГСПЛАВ» → «СПЛАВ».
Технический анализ
Все, что нашли детекторы и OCR, собирается в структурированный результат.
Тип детали определяется в три шага. Сначала ищем ключевые слова в названии и материале: «труба», «вал», «втулка», «фланец» — цилиндрическое. Если ключевых слов нет — проверяем, есть ли ось вращения на главном виде, пересекающая его пополам. Нет оси — прямоугольное по умолчанию. Три уровня, каждый страхует предыдущий.
Подсчет размеров нетривиальный.
Текст «4 отв. M6×1» — это четыре отверстия, а не одно. Множители из таких записей разбираются регулярками, остальное считается как есть. При этом Ra, маркеры резьб и аннотации в счёт не идут — иначе цифра раздувается. Два перекрывающихся бокса с IoU больше 50% объединяются в один: размер, попавший в два бокса, должен считаться один раз.
Шероховатость — место, где ошибка OCR напрямую меняет стоимость детали. «Ra 1.6» и «Ra 16» — это разные операции и разная цена. Все значения проверяются по стандартному ряду ГОСТ: 0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.3, 12.5, 25, 50, 100. Типовые ошибки исправляются автоматически: 16 → 1.6, 32 → 3.2 — потерялась точка, 6.35 → 6.3 — лишний знак от OCR.
Шероховатости собираются из трёх мест одновременно: YOLO‑модель для символов Ra, текстовый поиск паттерна «Ra + число» в размерных блоках и отдельная детекция в правом верхнем углу листа — там по ГОСТ ставится общая шероховатость для всего чертежа. Результаты трёх источников объединяются с дедупликацией через IoU, чтобы одна шероховатость не попала в итоговый список дважды.
Что получилось по цифрам
Результат работы всего пайплайна — JSON с параметрами детали. Из одного чертежа система извлекает:
общее число размеров
шероховатости с количеством вхождений каждого значения
квалитет самого точного размера
количество резьб
все диаметры
название, код, материал, масса из штампа
тип детали: цилиндрическое, прямоугольное, труба, шестигранник
габаритные размеры: длина, ширина, высота
наличие оси вращения
количество и метки сечений
Этот JSON идет в калькулятор стоимости. Там он разворачивается в цену: материал по весу и марке, станко‑часы по квалитету и шероховатости, отдельные операции по резьбам и сечениям. Технолог получает цифру, не открывая чертеж.
Стек
YOLO (Ultralytics) — 6 моделей детекции для разных типов объектов
PaddleOCR — детекция текста + кастомная модель распознавания
OpenCV (с CUDA) — предобработка, контурный анализ, морфология
Python — пайплайн, постпроцессинг
Вместо заключения
Пайплайн, который мы описали, — результат сотен экспериментов на реальных чертежах.
Все это проверялось на реальных производственных чертежах — от простых валов до корпусных деталей с десятками сечений. Пороги, запасные сценарии, решения про DPI и углы OCR — не из головы, а из конкретных ошибок на конкретных чертежах.
Система работает в производственном потоке. Нестандартные штампы, кривые сканы, карандашные правки поверх печати — всё это до сих пор требует ручной проверки, и мы это не скрываем.
Если делали что‑то похожее или есть вопросы по реализации — пишите в комментариях.

