Привет. Меня зовут Алексей. Помогаю внедрять Ai решения. Рассказываю о бизнесе, факапах, личных вызовах и путешествиях. Мой тг-канал: https://t.me/roslyakovgo
На заводах ИИ мы внедрять умеем, а нормального кота сгенерить не смогли. Штош
Комментариев под прошлым постом было много, ответить каждому мы физически не успеем. Но ответить хочется. Поэтому короткий инженерный разбор: с цифрами, фактами и долей самоиронии.
Про “чёрный короб”
Да, идея хорошая и часто действительно спасает. Но у нас было три метра конвейера, по которому летят зеркальные листы со скоростью 2 м/с. А пыль, тепло, вибрации и необходимость обслуживать оптику делают «чёрный ящик» скорее лабораторным решением, чем промышленным.
Про поляризацию и металл
«Поляризаторы на металле не работают!» — писали вы. И вы… почти правы. На идеально зеркальной поверхности эффект действительно слабый. Но на загрязнённых, частично матовых и неидеальных листах он даёт до 15–20 dB подавления бликов. Не магия — просто физика, немного геометрии и много проб и ошибок.
Про “дешёвого человека с глазами”
Мы тоже любим людей с глазами. И даже работаем вместе.
Система не заменяет оператора — она отсекает рутину, где глаз устаёт, а блик обманывает. Раньше контролёр тратил на проверку одного листа около 6–8 секунд и при этом пропускал до 10–12% микродефектов.
Теперь камера справляется за 1.2 секунды, а доля спорных случаев, которые уходят на ручную проверку, не превышает 3–5%. Вместо бесконечного «вглядывания в зеркало» оператор теперь проверяет только то, где нейросеть не уверена — и делает это в разы быстрее.
Так что не «человек против машины», а человек + машина против скуки и брака.
Про “азов фотографии”
Да, теперь мы знаем про них чуть больше, чем хотели 😅 Но инженерка в цехе — это не студия с софтбоксом. Там дрожит пол, летит пыль, мигает строб, а под ногами едет металл. Так что каждый миллиметр света, поляризации и выдержки был добыт потом и кофеином.
Про “всё равно не автономно”
Справедливое замечание. Промышленное CV пока действительно не живёт без инженеров — но и не должно. Как и любая сложная система, оно развивается итерационно: данные → обучение → адаптация → стабильность. Главное, что теперь инженеры на линии решают не “почему камера не видит”, а “как улучшить метрики”.
На сладкое
Теперь точно знаем, что идеальных данных не бывает, что FTP живёт дольше всех, и что на заводе «хорошее освещение» — это инженерное чудо, а не кнопка в настройках.
Спасибо всем, кто спорил, шутил и предлагал решения — ваши комменты были лучшим продолжением истории, чем любой отчёт по внедрению❤️
Больше живых кейсов моя команда разбирает в новом ТГ-канале https://t.me/brains2up Подписывайтесь, если хотите чаще читать про настоящий ИИ.
Всем привет! Меня зовут Алексей, я руковожу компанией, которая занимается разработкой с применением ИИ-технологий. Сам я тоже погружен в разработку, но больше доверяю это своей команде – нам удалось собрать команду классных профи. Истории из нашей совместной работы я и планирую рассказывать в своем блоге.
Cегодня делюсь историей одного из наших разработчиков – о внедрении компьютерного зрения на реальном производстве.
Первый день на линии выглядел почти комично. Стоим втроём в касках, над конвейером — новая промышленная камера с глобальным затвором (5 Мп, FOV ~0,6 м), а под ней со скоростью 2 м/с уезжают листы с зеркальным блеском. Оператор рядом фыркает:
— «Ну и где твои умные нейросети? Вон же царапина!»
На экране вместо царапины — пересвеченный до насыщения белый блик: без перекрёстной поляризации и со слишком длинной выдержкой он превращается в «идеальный» объект для детектора. Алгоритм радостно машет флажком: «дефект!». Таких ложных срабатываний за смену набегало сотни; настоящие микротрещины и сколы тонули в засветках и смазе.
С этого момента стало ясно: впереди не «проект на пару недель», а марафон, где придётся бороться не только с кодом, но и с реальностью цеха — вибрациями, пылью, бликами и древним MES, говорящим по OPC/Modbus.
Зачем всё это
Один крупный производственный заказчик (линия резки листового материала: зеркальная поверхность, скорость ~2 м/с) решил автоматизировать контроль дефектов.
Раньше инспекция была ручной — оператор просматривал каждый лист.
На старте задача выглядела так:
Ставим камеру над линией: Basler ace2, 5 Мп, глобальный затвор; C‑mount 12 мм; FOV ≈ 600 мм; аппаратный триггер от энкодера; экспозиция 30–50 мкс; импульсный LED 630 нм с перекрёстной поляризацией.
Режем изображение на тайлы: 1024×1024 px с overlap 20%; deskew по кромке листа; маска бликов.
Возвращаем результаты в MES/SCADA: JSON → XML/FTP (атомарный rename) с переходом на OPC UA; координаты дефектов в мм, sheet_id, статус OK/NOK.
Спойлер: из этого получился трёхмесячный марафон — свет, крепёж, синхронизация и интеграции заставили сервера дрожать, а нас — прокачать инженерный дзен.
Сюрприз №1: Светит, но не туда
Проблема: освещение и блики
На раннем этапе мы выяснили, что камера стабильно видит… блики, а не дефекты. Промышленное освещение оказалось агрессивным: холодные направленные прожекторы, паразитные отражения от оборудования и зеркальная поверхность листов. Сенсор клиппился по яркости, и каждый пересвеченный блик принимался за дефект. На старте ловили до 32% ложноположительных срабатываний.
Что сделали
Свет и поляризация: заменили направленные прожекторы на диффузный купольный/низкоугловой свет под ~45°; поставили линейные поляризаторы на источник и анализатор на объектив под 90° (подавление бликов до ~15–20 dB). Перешли на узкополосные LED 625–660 нм.
Экспозиция и синхронизация: включили строб с импульсом 30–50 мкс под триггер энкодера; глобальный затвор, постоянный токовый драйвер без 50/60 Гц мерцания. Отключили автоэкспозицию/автогейн/автобаланс; гамма = 1.0, фиксированный gain.
Экраны и окклюзии: установили матовые чёрные экраны по бортам и над камерой, убрали паразитные отражения от рам и кромок.
Онлайн-мониторинг яркости: ввели контроль доли насыщенных пикселей (P255) и динамического диапазона; кадры с P255 > 0.5% автоматически помечаются и не идут в инференс; гистограммы логируются.
Вывод: оптика и свет — не «поправим в коде». Схему освещения, поляризацию, строб и крепёж нужно закладывать до начала разработки модели — это даёт порядок выигрыша по качеству сразу.
Сюрприз №2: Камера не дружит с резкостью
Проблема: микровибрации и автофокус
Камера стояла над станком, всё казалось стабильным. Но каждые 30–40 секунд появлялась дрожь, тонкие дефекты «смазывались». Причина — микровибрации от привода/роликов (≈25–35 Гц) и отсутствие автофокуса при фиксированном рабочем расстоянии.
Что сделали
Механика/крепёж: вынесли камеру на жёсткий кронштейн с виброизоляторами (fₙ ≈ 9–12 Гц, демпферы Shore A 30–40), отвязали от корпуса станка, добавили массу и развязку кабелей. Резонансные пики выше 60 Гц подавлены, передача вибраций < 0.3.
Фокус: настроили фикс‑фокус на рабочее расстояние по slanted‑edge (MTF50 вырос с ~0.28 до ~0.36 cyc/px), зафиксировали кольцо (lock‑screw) и метки положения; регламент пересмотра при смене температуры/света.
Экспозиция: привязали экспозицию к стробу 30–50 мкс — при 2 м/с смаз ≤ 0.1 мм.
IMU‑контроль: поставили 6DoF‑датчик (1 кГц); логируем события при |ω|RMS > 0.8°/с или Δугла > 0.05° за 200 мс; при срабатывании помечаем кадры и уведомляем оператора.
Онлайн‑метрика резкости: Tenengrad/Laplacian в ROI; кадры ниже τ исключаются из инференса или запрашивается повтор.
Вывод: стабильная механика и фикс‑фокус столь же критичны, как и модель. Развязка вибраций, короткая экспозиция и онлайн‑контроль резкости делают детектор предсказуемым
Сюрприз №3: один тайл — два дефекта и половина чужого листа
Ожидали: лист идёт ровно и по центру. Реальность: заезд под углом, частичное перекрытие соседним листом, дрейф по диагонали. В итоге один тайл нередко содержит две кромки разных листов — модель «плывёт» в предсказаниях.
Что сделали
Маркеры и привязка к движению: наклеили ретрорефлективные метки по краям ленты; считывание в NIR (850 нм) с аппаратным триггером от энкодера (5k PPR). Детектируем leading edge и боковые кромки; дрожание меток < 0.5 мм.
Лидар + фотодатчики: ToF-лидар 1 кГц для контроля lateral offset, три фотошторки по ширине для детекта перекрытия/наличия листа. События уходят в PLC и в CV-пайплайн; допуск смещения ±3 мм, время реакции < 5 мс.
вычисляем гомографию и выполняем deskew; сетка тайлов якорится к кромке, а не к «сырому» кадру;
при перекрытии строим маску «серой зоны» вдоль шва (15–25 px): увеличиваем overlap, нежёстко понижаем вес предсказаний в NMS, логику объединения делаем по sheet_id;
Слежение за листом: sheet_id по импульсам энкодера; пересборка карты дефектов в координатах линии, чтобы MES получал стабильные ROI.
Вывод: физическое позиционирование нужно дублировать алгоритмами CV. У «железа» иногда свои планы, поэтому привязка к энкодеру, маркеры, лидар и дескью — обязательны для стабильного тайлинга и корректной агрегации предсказаний.
Сюрприз №4: Модель любит однотипные дефекты, а у нас каждый раз сюрприз
Проблема: разнообразие артефактов
Обучались на 15 классах дефектов. В проде всплыли неожиданные: пятна клея, отпечатки перчаток, стружка, насекомые, следы чистки и др. За первый месяц зафиксировали 37 новых типов, отсутствовавших в трейне.
Что сделали
Активное выявление «неизвестных» (OOD): отправляем в разметку тайлы при низкой уверенности (conf < τ), высокой энтропии, а также при расхождении ансамбля и классического CV; дополнили energy-score по логитам и расстоянием Махаланобиса в признаковом пространстве.
Еженедельная разметка и инкрементальное обучение: выгружаем 8–12k «неопознанных» тайлов/нед. в LabelStudio (κ ≥ 0.82), дообучаем с rehearsal (30% старых данных), частично замораживаем backbone, применяем дистилляцию знаний и калибровку температурой.
Управление таксономией: «прочее/ nuisance» как буферный класс; промоутим в полноценный класс при ≥200 размеченных примеров и precision ≥ 0.7 на валидации. Зоны с низкой уверенностью помечаем в UI для ручной проверки.
Вывод: CV — это не «обучил и забыл», а непрерывный цикл. Активный OOD-поток, регулярная разметка и инкрементальное обучение с гибридными эвристиками дают управляемость при появлении новых артефактов без деградации по базовым дефектам.
Сюрприз №5: API-интеграция с MES — это уже не про CV, но боль
Проблема: древняя MES-система
Документации нет. REST/GraphQL нет. Только XML-файлы по FTP, которые MES опрашивает раз в несколько секунд. Частые проблемы: частичные чтения, дубликаты, «зависшие» файлы, непредсказуемые задержки.
Что сделали
Прокси-адаптер JSON→XML + надёжная файловая шина
CV выдаёт JSON с sheet_id, ts, speed, списком дефектов (bbox в мм, класс, уверенность).
Адаптер формирует XML по согласованной схеме, пишет атомарно: сначала в outbox/*.xml.part, затем rename в *.xml; после чтения MES кладёт *.ack.
Каталоги: outbox/ → processing/ → done/, ошибки в error/ с ретраем (экспоненциальная задержка, максимум 5 попыток), дедуп по sheet_id.
Кодировка UTF‑8 (без BOM), CRLF по требованию MES. Имя файла: INS_L1_20250912T101532Z_123456.xml.
Мониторинг и SLA для FTP-интеграции
Тайм-аут чтения: если через 30 с нет *.ack — алерт (Prometheus/Alertmanager → Teams/Slack), автоперекладка файла в processing/ не повторяется до разборки инцидента.
Метрики: end-to-end задержка (CV→MES), число «подвисших» файлов, ретраи, доля дубликатов, размер очереди. Трассировка по sheet_id.
Безопасность: при возможности SFTP; иначе FTPS (TLS), учётка с минимальными правами и chroot.
Узлы: ns=2;s=estralin/Sheet/{sheet_id}/Result, .../Defects (массив структур с bbox в мм и классом). Семплирование 100–200 мс, очередь 128, подтверждение обработкой статуса.
Фолбэк: при недоступности OPC UA — автоматический возврат на файловую шину, чтобы не терять данные
Вывод: интеграции — это отдельный проект. Согласуйте протоколы/схемы и SLA с IT-заказчика до старта, закладывайте атомарность, дедуп, мониторинг и фолбэк-канал; при возможности переходите на OPC UA с шифрованием.
Технологии и стек
Камера: Basler ace2 (GigE, mono, global shutter, 5 MP @ 60 fps), C‑mount фикс-объектив 12 мм (F/4), FOV ≈ 600 мм, масштаб ≈ 0.20 мм/пкс. Аппаратный триггер от энкодера 5k PPR, экспозиция 30–50 мкс, строб узкополосного LED 630 нм с перекрёстной поляризацией; гамма 1.0, фиксированный gain.
Модели: YOLOv5m (тайлы 1024×1024, overlap 20%), препроцессинг OpenCV (deskew по Sobel/Hough, CLAHE, маска бликов). Инференс ONNX Runtime CUDA/FP16; p50 7.8 мс/тайл, p95 11.2 мс/тайл (RTX A2000). Итог по листу p95 < 90 мс при 2 м/с. Качество: mAP50 0.96, F1 0.91, FPR 3.1% на холдауте.
Разметка: LabelStudio, экспорт COCO/YOLO; двойная валидация, κ=0.84; гайдлайны по классам/границам; класс «nuisance/прочее» для OOD до промоушена.
Интеграция: Python FastAPI (/infer, /healthz) → JSON; адаптер JSON→XML с атомарным rename и *.ack для legacy-FTP; основная шина — OPC UA (SecurityMode=SignAndEncrypt, Basic256Sha256), узлы ns=2;s=estralin/Sheet/{id}/Defects. Фолбэк на файловый канал.
Мониторинг: Prometheus + Grafana. Метрики: p95/p99 инференса, очередь, GPU util/mem, доля клиппинга (P255), FPR/recall по сменам, OOD rate, задержка CV→MES/OPC. Алерты по таймаутам ACK (>30 с), росту FPR, падению FPS/энкодера.
Деплой: On‑prem, Docker (Compose), NVIDIA Container Toolkit, закрепление версий драйверов/библиотек, healthchecks, автоперезапуск, локальный inference (latency‑critical), офлайн‑буферизация результатов и ретраи.
Финальные цифры
Хотелось показать таблицей, поэтому просто скриншот
Что мы поняли
Оглядываясь назад, понимаем: часть проблем мы могли предсказать. Вот несколько инсайтов, которые пригодятся тем, кто только собирается внедрять CV на производстве.
Не верить в «идеальные данные»
Пыль/блики/вибрации — норма. Введите авто‑контроль качества кадров: P255 ≤ 0.5%, средняя яркость в окне [90;160], резкость (Tenengrad) > τ, доля «горячих» пикселей ≤ 0.05%.
Мониторьте дрейф окружения: деградация света (−5…−8%/мес), смещение экспозиции, рост шума; алерты и напоминания на очистку оптики каждые 8 ч или при падении SNR < 24 dB.
Реплицируйте «грязную реальность» в данных: еженедельно добавляйте 5–10% свежих OOD‑тайлов, аугментации под бликами/смазом/пылью; калибровка порогов раз в смену.
Закладывать бюджет на «внезапности»
Резерв времени: +20–30% к срокам на интеграции/железо; бюджет: +10–15% на запасные части (камеры, БП, драйверы света, кабели).
Операционные SLO: p95 инференса < 100 мс/тайл, p95 CV→MES < 1.2 с, потери данных 0, дедуп по sheet_id, MTTR инцидента интеграции ≤ 15 мин.
Дежурство и плейбуки: on‑call 24/7 для линии, сценарии на «камера/энкодер/свет/OPC/FTP упал», фолбэк на файловую шину, офлайн‑буфер ≥ 24 ч.
Общаться с технарями на месте
Совместно с цехом: выбор света/крепежа/экранирования, допустимые окна простоя, точки триггера от энкодера, маршруты кабелей, HSE‑требования.
Формализовать SAT/UAT: чек‑листы по классам дефектов, выборки на 1–2 смены, критерии приёмки (precision/recall/FPR), график регламентных чисток и перекалибровок.
Напоследок
Компьютерное зрение в промышленности — меньше про «красоту модели» и больше про свет, крепёж, синхронизацию и протоколы. Если идёте в прод, готовьтесь к реальному миру — тому, где рядом со Stack Overflow открыта вкладка «как дернуть автофокус через Modbus» и список запасных кабелей на складе.