Горнодобывающее предприятие поставило задачу, которая на первый взгляд выглядит просто: камера над лентой конвейера должна в режиме реального времени определять долю оранжевой фракции руды. Цвет здесь — косвенный признак химического состава, по которому технолог оценивает качество партии. До автоматизации эту работу делал геолог: смотрел на ленту и записывал в журнал что-то вроде «80% оранжевой, 10% серой, 10% розовой». Если на смене работало несколько геологов, их оценки усредняли, что снижало точность. Ночная смена с 22:00 до 06:00 нередко не давала цифр вообще — журнал оставался пустым.

Первой попыткой автоматизации стала пороговая фильтрация по цветовому пространству HSV. На статичных снимках с равномерной подсветкой метод давал читаемые маски, но на реальном конвейере не работал: поверхность кусков неоднородная, оттенки классов пересекаются, загрязнённая серо-белая фракция по пикселю неотличима от пыли на оранжевом камне. Кроме того, задача требовала instance segmentation — разделения отдельных объектов, а не просто окраски пикселей по классу. Один крупный камень и пять мелких той же суммарной площади дают одинаковую пиксельную долю, но это разный гранулометрический состав с разным поведением при обогащении.

ПодходВремя на кадрКачество границ
Ручная разметка полигонами~1 часВысокое, но трудоёмко
CVAT AI-assisted30–40 минутНизкое, камни слипаются
SAM2 предразметка + ручная коррекция15–20 минутВысокое, SAM2 точно выделяет камни

Главным препятствием оказалась разметка. Один кадр содержит от 100 до 900 камней неправильной формы, часто лежащих вплотную или с перекрытием. Полностью ручная полигональная разметка одного кадра занимала около часа. Для датасета из 500+ кадров это означало 500+ часов работы разметчика — за пределами бюджета. Встроенные ИИ-инструменты CVAT (Magic Wand, Intelligent Scissors) давали только геометрию контура без классов: на острых гранях контур уходил в сторону, соседние камни без зазора стягивались в один полигон.

SAM2 в режиме автосегментации сократил время разметки одного кадра с 60 до 15–20 минут.

Решением стал SAM2 (Segment Anything Model 2) в режиме автоматической сегментации. Модель проходит по всему кадру и выдаёт маски всех найденных объектов без предварительного обучения — в zero-shot-режиме. Классов она не знает, но качество границ пиксельное. Пайплайн разметки выглядел так: SAM2 прогоняли по кадру в everything-режиме, маски конвертировали в полигоны и импортировали в CVAT, после чего разметчик вручную присваивал классы, удалял лишнее и склеивал разорванные маски. Время на кадр сократилось до 15–20 минут.

Попытка автоматически фильтровать выход SAM2 — отбрасывать маски ниже минимальной площади — была отклонена сознательно. На конвейере присутствует мелкая фракция: куски 5–10 мм, пыль, крошка. Это та же руда, и в общем составе она учитывается. Фильтр по площади выбрасывал бы её целиком, смещая доли классов. Весь «шум» от SAM2 уходил к разметчику, который вручную убирал только реальный фон — линии ленты, грязь на оптике, тени от прожекторов.

Дисбаланс классов в датасете оказался серьёзной проблемой. На первых ~200 кадрах розовая фракция занимала менее 5% объектов. Модель либо пропускала розовые камни, либо относила их к оранжевым — на границе оттенков они близки, и при таком дисбалансе сети выгоднее всегда ставить оранжевый класс. Проблему решили нестандартно: конвейер останавливали, на чистую ленту партиями выкладывали отобранную розовую руду, запускали ленту и снимали той же камерой при той же подсветке. Доля розовой во вторичной выборке поднялась примерно до 25%. Дополнительно «розовому» классу подняли вес в функции потерь — штраф за пропущенный розовый камень стал выше. Recall по розовому вырос, но на переходных оттенках сеть начала смещаться в его сторону.

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

Финальная модель — YOLO-seg, обученная на датасете из 600–800 размеченных кадров. Маски YOLO грубее, чем у SAM2: углы скруглены, мелкие выступы пропускаются. Для пиксельной точности этого недостаточно, но для подсчёта долей по классам — достаточно: итоговая метрика интегрирует по большому числу объектов в кадре, и грубость контура отдельной маски почти не влияет на агрегат. Инференс занимает около 10 мс на кадр при batch=1 на GPU. Камера даёт 25 fps — обработка успевает с тройным запасом. Edge-инференс на конвейере не понадобился: поток идёт на сервер по локальной сети.