Привет хабр!
Мы разрабатываем приложение для управления линейным персоналом.
Хочу рассказать об одной из самых сложных наших разработок — динамического визуального кода, который должен считываться камерой обычного смартфона в реальном времени.
Внутри продукта эта технология называется MotionCode. Внешне всё выглядит довольно просто: панель воспроизводит последовательность визуальных элементов, камера телефона считывает их, а приложение восстанавливает код.
На практике путь от первого прототипа до стабильной работы оказался гораздо сложнее. Мы успели обучить модель для object detection, столкнуться с ограничениями мобильного железа, отказаться от нейросети и почти без опыта в компьютерном зрении построить собственный real-time-пайплайн обработки кадров.
Зачем нам понадобился динамический код
Одна из задач приложения — подтверждать фактическое присутствие сотрудника на рабочем объекте с помощью спцециализированой панели которая предоставляет визуальный код для считывания камерой.
Статический QR-код решает эту задачу только частично. Его можно сфотографировать, сохранить или переслать коллеге. Геолокация также не является универсальным решением: внутри помещений она работает нестабильно, а на некоторых объектах её использование ограничено технически или организационно.
Нам требовался код, который:
существует только в конкретный момент времени;
привязан к определённой панели и объекту;
постоянно меняется;
считывается обычной камерой телефона;
не требует специализированного терминала;
работает на устройствах разной производительности.
Так появилась идея MotionCode — визуальной последовательности, которую недостаточно один раз сфотографировать и сохранить.
Первая идея: поручить распознавание нейросети
Первую реализацию мы построили на object detection.
Мы подготовили набор изображений, разметили элементы MotionCode и обучили модель определять состояние нужных ячеек. В лабораторных условиях всё выглядело многообещающе: камера видела панель, модель находила элементы, а приложение собирало из них код.
На мощных устройствах прототип действительно работал.
Проблемы начались, когда мы перешли от демонстрации к реальным сценариям.
Панель могли сканировать:
недорогим Android-смартфоном;
устройством с небольшим объёмом оперативной памяти;
телефоном с медленным автофокусом;
перегретым после продолжительной работы устройством;
камерой при плохом освещении;
под углом;
с бликами или муаром от экрана.
Для object detection было недостаточно один раз обработать фотографию. MotionCode меняется во времени, поэтому модель должна работать постоянно и достаточно часто анализировать новые кадры.
Получался тяжёлый цикл:

На слабых устройствах обработка одного кадра занимала слишком много времени. Частота распознавания снижалась, интерфейс начинал дёргаться, телефон нагревался, а код иногда успевал изменить состояние раньше, чем приложение заканчивало анализ предыдущих кадров.
Можно было уменьшить модель, снизить разрешение, пропускать больше кадров или применить более агрессивную оптимизацию. Но каждое улучшение производительности одновременно ухудшало качество распознавания.
В какой-то момент мы поняли: модель решает гораздо более общую задачу, чем нам требуется.
Нам не нужно находить произвольные объекты в неизвестной сцене. Мы заранее знаем структуру панели, расположение ячеек и возможные состояния каждой из них.
Значит, нейросеть здесь была не единственным и, как выяснилось, не самым подходящим инструментом.
Решение, которое сначала казалось шагом назад
Отказаться от модели было непросто. В object detection уже вложили много времени: собирали и размечали данные, обучали модель, тестировали её и интегрировали в мобильное приложение.
При этом серьёзного опыта разработки собственных алгоритмов компьютерного зрения у нас не было.
Но у классического CV было важное преимущество: мы могли контролировать стоимость каждой операции и выполнять только ту работу, которая действительно необходима.
Новый пайплайн в упрощённом виде стал выглядеть так:

Вместо вопроса «какие объекты находятся на изображении?» мы стали задавать гораздо более конкретный вопрос:
Какие из заранее известных ячеек активны на этом кадре?
Это существенно уменьшило объём вычислений.
Сначала найти панель, затем перестать искать её заново
Обрабатывать весь кадр камеры на каждом проходе невыгодно. Большая часть изображения вообще не относится к нашему коду.
Поэтому первым этапом стала область интереса — ROI. Сканер ищет характерную геометрию панели внутри ограниченной зоны, после чего сохраняет найденные координаты и отслеживает их на следующих кадрах.
Пока положение телефона существенно не меняется, повторный полный поиск не требуется. Алгоритм работает преимущественно внутри уже найденной области.
Но ROI нельзя просто зафиксировать навсегда. Руки пользователя двигаются, автофокус меняет изображение, а панель может ненадолго исчезнуть из кадра. Поэтому область поиска постепенно корректируется и сбрасывается только после нескольких неудачных кадров.
Так мы избавились от постоянного повторения одной из наиболее дорогих операций.
Ячейка — это не просто светлый пиксель
На первый взгляд состояние ячейки можно определить по средней яркости. Если область светлая — ячейка активна, если тёмная — неактивна.
В реальности такой подход быстро ломается.
На результат влияют:
яркость экрана панели;
автоматическая экспозиция камеры;
блики;
тени;
угол съёмки;
цветовая температура;
мерцание дисплея;
муар;
соседние активные элементы.
Поэтому мы оцениваем не отдельный пиксель, а несколько характеристик области вокруг ожидаемого центра ячейки. В частности, сравниваем внутреннюю часть элемента с окружающей областью.
Это помогает отличить действительно активную ячейку от блика или общего повышения яркости кадра.
Дополнительно алгоритм проверяет обе возможные полярности изображения. В одних условиях активная ячейка выглядит светлее фона, в других из-за экспозиции и особенностей экрана устойчивее определяется обратное соотношение.
Для каждого кандидата рассчитывается условная уверенность, после чего выбирается наиболее согласованная комбинация.
Почему одного удачного кадра недостаточно
Даже хороший алгоритм иногда ошибается на отдельном кадре. Причиной может стать движение телефона, кратковременный расфокус или момент обновления изображения на панели.
Поэтому сканер не доверяет единичному результату.
Он собирает наблюдения во времени и проверяет, что найденные состояния:
повторяются на нескольких кадрах;
появляются в ожидаемой последовательности;
имеют достаточную уверенность;
не противоречат соседним состояниям;
укладываются в допустимые временные интервалы.
Временная составляющая оказалась не менее важна, чем анализ отдельного изображения.
MotionCode — это не статичная картинка, а процесс. Поэтому и распознавать его нужно как процесс.
Долгие часы калибровок
После создания базового алгоритма началась, пожалуй, самая долгая часть работы — калибровка.
Нужно было подобрать размеры областей выборки, допустимые отклонения координат, пороги яркости, коэффициенты уверенности, скорость обновления ROI и количество подтверждающих кадров.
Параметры, идеально работавшие на одном телефоне, могли давать ошибки на другом. Настройки для яркого монитора плохо переносились на тёмный экран планшета. Увеличение устойчивости к бликам иногда снижало чувствительность при слабом освещении.
Отдельной задачей стала согласованность iOS и Android. Камеры этих платформ по-разному передают кадры, управляют экспозицией и представляют данные изображения. Поэтому полностью общей реализации оказалось недостаточно: высокоуровневая логика совпадает, но низкоуровневая обработка адаптирована под каждую платформу.
Большая часть работы выглядела примерно так:
Запустить панель.
Навести конкретный телефон.
Получить ошибочное состояние.
Сохранить диагностические данные.
Изменить один параметр.
Повторить тест при другом освещении.
Обнаружить, что исправление сломало предыдущий сценарий.
Вернуться на несколько шагов назад.
И так много раз.
На этом этапе стало понятно, что разработка компьютерного зрения — это не только выбор алгоритма. Это ещё и систематическая работа с большим количеством пограничных условий.
К счастью, к моменту, когда мы дошли до этого этапа, появились достаточно сильные AI-модели, способные работать не только с текстом, но и с кодом, изображениями и диагностическими данными. Они не смогли выполнить калибровку полностью самостоятельно, но заметно ускорили процесс: помогали анализировать неудачные кадры, находить зависимости между параметрами, предлагать изменения алгоритма и автоматизировать перебор некоторых значений.
По сути, AI стал для нас дополнительным инженерным инструментом. Модель формулировала гипотезы и помогала быстрее готовить эксперименты, а мы проверяли их на реальных устройствах, при разном освещении и под разными углами. Это не избавило нас от ручного тестирования, но сократило количество слепых итераций и позволило сделать калибровку более системной.
Получился любопытный поворот: от нейросети внутри мобильного сканера мы отказались из-за требований к производительности, но AI всё равно сыграл заметную роль — уже не во время работы приложения, а в процессе разработки технологии.
Что происходит между сервером, панелью и сканером
Мы не будем подробно раскрывать всю внутреннюю архитектуру, но общую идею можно описать.
Сервер создаёт временный числовой код и отдельную матрицу соответствий. Исходное число не отправляется на панель в открытом виде.
Вместо него панель получает последовательность позиций — ячеек, которые необходимо воспроизвести. Пользователь видит на экране только меняющуюся визуальную комбинацию.
Сканер считывает состояния ячеек и собирает последовательность индексов. Затем приложение получает от бэкенда матрицу, относящуюся к конкретной короткоживущей сессии, и восстанавливает исходное значение.
Упрощённо обмен выглядит так:

На сервере хранится не только матрица, но и проверочное представление кода. Сессия живёт ограниченное время, а успешное считывание связывается с конкретной панелью и пользователем.
За счёт этого скриншот или запись старой последовательности быстро теряют практический смысл.
Почему классический CV в итоге победил
Главным преимуществом нового подхода стала предсказуемость.
Мы знаем:
сколько ячеек нужно проверить;
где примерно они должны находиться;
какие состояния допустимы;
какая последовательность считается корректной;
сколько вычислений выполняется на каждом кадре.
В object detection производительность в значительной степени зависела от модели, размера входного изображения и возможностей устройства. В классическом пайплайне мы можем отдельно оптимизировать каждый этап и пропускать ненужную работу.
Кроме того, для обновления логики больше не требуется собирать датасет, размечать новые изображения и переобучать модель. Многие проблемы теперь решаются изменением конкретного этапа обработки.
Это не означает, что классическое компьютерное зрение всегда лучше нейросетей. Если бы нам требовалось находить произвольные объекты в неизвестной сцене, модель была бы естественным выбором.
Но в задаче с заданной геометрией и ограниченным набором состояний специализированный алгоритм оказался быстрее, легче и управляемее.
Что получилось:

Что мы вынесли из этой разработки
Первый вывод — не каждая задача компьютерного зрения требует нейросети.
Object detection позволил быстро создать прототип и доказать, что сама идея работает. Но попытка превратить прототип в массовую мобильную функцию показала ограничения выбранного подхода.
Второй вывод — производительность нужно проверять на самых слабых целевых устройствах как можно раньше. Технология, работающая на флагманском смартфоне разработчика, ещё не является мобильной технологией.
Третий вывод — real-time-система должна учитывать время. Недостаточно хорошо распознать один кадр: нужно контролировать частоту анализа, устойчивость последовательности и смену состояний.
И наконец, отсутствие экспертизы в конкретной области не всегда означает, что от задачи нужно отказаться. Иногда это означает много документации, экспериментов, неудачных гипотез и часов калибровки.
Сейчас MotionCode работает без постоянного инференса тяжёлой модели и остаётся доступным для устройств, которые не справлялись с первой версией технологии.
В итоге технология получилась настолько удачной, что мы уже рассматриваем её не только как инструмент учёта рабочего времени. Следующим направлением развития MotionCode должна стать авторизация: динамический визуальный код можно использовать как дополнительный способ подтверждения входа в систему или доступа к отдельным корпоративным сценариям.
Идея остаётся прежней: вместо статичного секрета пользователь считывает короткоживущую визуальную последовательность, связанную с конкретной сессией и доверенной панелью. Пока это направление находится в планах, но сама архитектура MotionCode позволяет развивать технологию далеко за пределами первоначальной задачи.
А у нас осталось ещё немало историй: о внедрении AI в продукт, использовании AI в разработке, автоматизации тестирования и решениях, которые сначала казались удачными, но не пережили встречу с реальными пользователями.
Если такой формат окажется интересен, расскажем о них в следующих статьях.
Комментарии (4)

onuchin
05.08.2026 18:33В соседней ветке обсуждалась статья о склейке кадров микроскопа
https://habr.com/ru/articles/1067168/#comment_30302964
Я попросил Глубоко Больного Пациента прокомментировать Ваш текст со связкой с предыдущей статьей.
IMHO, получилось интересно.
Ничего личного.
------------------------------------
Отличная статья! Видно, что команда прошла через классический “ад энтузиаста” — от блестящего прототипа до продакшен-ада. Давайте разберём её под микроскопом (простите за каламбур), жёстко покритикуем инженерные решения и проведём параллели с предыдущей темой сшивки изображений.
Критика статьи и технических решений MotionCode
Проблема №1: Самоуспокоенность по поводу “Replay Attack” (Атака повторным воспроизведением)
В статье говорится: «Скриншот или запись старой последовательности быстро теряют практический смысл». Это опасное заблуждение. Если я запишу видео панели длительностью 5 секунд на другой телефон и просто покажу это видео камере целевого устройства, алгоритм CV увидит точно такую же динамику, временные интервалы и яркость. Если вы не добавили рандомный временной челлендж (например, смена состояния должна произойти строго после того, как камера моргнула, или с привязкой к текущей миллисекунде сервера), система уязвима. Ваш CV анализирует только геометрию и яркость — он не видит, что это запись с другого экрана.
Проблема №2: Отказ от нейросети — это победа, но вы потеряли контекст
Вы заменили детектор на поиск ROI и яркость. Однако классический CV слеп к частичным перекрытиям. Если палец пользователя перекроет половину ячейки, ваша яркостная метрика сломается. Более того, при съёмке под углом геометрические искажения делают центр ячейки совсем не там, где вы его ждёте. В статье не упомянута аффинная коррекция перспективы перед сравнением областей — а без неё при наклоне телефона > 30° точность резко падает.
Проблема №3: “Магия” калибровки и отсутствие нормализации
Вы пишете: «Параметры, работавшие на одном телефоне, ломались на другом». Это классическая ошибка — настройка абсолютных порогов яркости. Почему вы не использовали адаптивную нормализацию (например, CLAHE или локальный контраст) прямо в потоке? Вместо подбора 50 параметров вручную, можно было привести гистограмму любого кадра к эталонному распределению за 2 мс на CPU. А ещё проще — инвертировать анализ: искать не абсолютную яркость, а границы (edges) ячеек. Границы устойчивы к экспозиции, в отличие от уровня серого.
Проблема №4: Временная фильтрация “в лоб”
Вы накапливаете состояния кадров, чтобы подтвердить их. Это увеличивает задержку (латентность). Для авторизации это может быть ОК, но в сценарии учета времени (когда сотрудник стоит у панели 5 секунд) — ОК. Но вы упустили детекцию смены состояния (переход 0->1). Самый сложный момент — это именно граница переключения, потому что в этот момент на экране может быть артефакт (половина ячейки перерисовывается). Вы не упомянули, как обрабатываете переходные кадры — скорее всего, они у вас падают в фильтр и вызывают ложные срабатывания.
Жёсткая связь с предыдущей задачей (Сшивка микроскопа)
Читая MotionCode, я узнал ту же самую архитектурную драму, что была в микроскопии. Вот 4 точки пересечения:
Аспект Сшивка микроскопа (прошлая статья) MotionCode (текущая) Общий вывод Выбор подхода Отказались от глубоких нейросетей (детекторы точек) в пользу фазовой корреляции. Отказались от Object Detection в пользу классического CV (яркость + ROI). Золотое правило: В узких задачах с известной геометрией классика на CPU всегда побеждает тяжелые модели на GPU. Проблема времени (Sequence) Боролись с накоплением ошибок (дрейфом) при склейке. Использовали глобальную оптимизацию. Борются с ошибочными кадрами через накопление (фильтр большинством). Обе системы поняли, что один кадр — ничто. Только поток (время) дает истину. Однако в микроскопии вы делали глобальный пересчет (Bundle Adjustment), а здесь — простой подсчет голосов. Это слабее. Калибровка Вы мучились с подбором порогов для Phase Correlation и размеров патчей. Вы мучились с порогами яркости и временными окнами. Это проклятие классического CV. В микроскопии я предлагал гибрид с Mutual Information. Здесь я предлагаю авто-калибровку по первому кадру (захватить эталонную яркость пустой панели и активной). Online / Offline Мы разделили на быстрый Online-превью и тяжелый Offline-рендер. MotionCode — это чистый Online. Offline не предусмотрен. Упущение: Если в микроскопии мы могли пересчитать всё потом, то здесь вы теряете данные. Если сотрудник стоял криво, и код не считался — вы не можете пересчитать историю. Нужен Offline-режим, где по сохраненному видео можно пересчитать код на сервере другим (более тяжелым) алгоритмом.
Что я предлагаю (как связать это с прошлым обсуждением и усилить)
Помните наш гибрид Phase Correlation + Mutual Information? Здесь точно такая же история, но с другими компонентами. Применим ту же философию к MotionCode.
А. Гибрид “Яркость + Края” (аналог ФК + ВИ)
· Грубо (Яркость): Ваш текущий метод анализа центральных областей — быстрый, но ненадежный при свете. · Точно (Края / Гистограмма): Если уверенность упала (блик или тень), запускаем тяжелый, но точный метод — HOG (Histogram of Oriented Gradients) на маленьком патче ячейки + SVM (или просто сравнение распределений градиентов). Это устойчиво к экспозиции. Вызовем его только для 1 из 10 кадров для коррекции дрейфа — ровно как мы делали с Mutual Information в микроскопии.
Б. Введение “Offline-Арбитра” (аналог глобальной оптимизации)
Ваше приложение должно сохранять сырые кадры (или сжатые дескрипторы) в буфер на 5 секунд. Если пользователь получает ошибку “Код не распознан”, приложение должно отправить эти 5 секунд видео на бэкенд. На бэкенде (где нет ограничений по батарее) запускается медленный, но супер-точный алгоритм (например, Lucas-Kanade трекинг всех углов панели + проверка целостности последовательности). Это спасет сценарий, когда телефон нагрелся и просел FPS.
В. Безопасность через “Шум” (как у нас было с вращением)
В микроскопии мы игнорировали вращение, потому что оно было малым. Здесь вы игнорируете видео-повторы. Решение: Добавьте в код зависимость от времени сервера на уровне пикселей. Например, панель показывает не просто ячейки, а волну, бегущую слева направо, и сканер должен считывать фазу этой волны. Записать волну на видео можно, но подделать её фазу в реальном времени без синхронизации с сервером — невозможно. Это делает вашу систему устойчивой к replay.
Итоговая ретроспектива
В обеих историях прослеживается один и тот же путь героя:
Наивный старт: «Возьмем нейросеть/FFT, она всё решит».
Жестокая реальность: Мобильное железо/размытие/освещение убивают прототип.
Откат к классике: Инженеры пишут велосипед на порогах и ROI, получая выигрыш в производительности.
Ад калибровки: Бесконечные правки параметров под разные устройства.
Однако главный вывод, который ваша статья не сформулировала, а мы вынесли из микроскопии: Нельзя строить реальное время, игнорируя физику датчика. В микроскопии это была автокоррекция фокуса и дрейф столика. Здесь — автоэкспозиция камеры.
Советую вам на следующей итерации выключить автоэкспозицию камеры программно (фиксированный ISO и выдержка) или считывать её значение и динамически менять пороги. Это убьёт 90% вашей калибровочной боли — и тогда ваш MotionCode станет неубиваемым. И, пожалуйста, добавьте анти-реплей защиту через анализ мерцания экрана (частоты 60 Гц) — камера видит полосы ШИМ, а запись с другого телефона их не повторяет идеально. Это как раз ваш “Mutual Information” для безопасности.

onuchin
05.08.2026 18:33В соседней ветке обсуждалась статья о склейке кадров микроскопа
https://habr.com/ru/articles/1067168/#comment_30302964
Я попросил Глубоко Больного Пациента прокомментировать Ваш текст со связкой с предыдущей статьей.
IMHO, получилось интересно.
Ничего личного.
------------------------------------
Системный анализ, критика и рекомендации по улучшению архитектуры динамического кода
Введение
Статья описывает разработку системы MotionCode – динамического визуального кода для подтверждения присутствия сотрудников. Авторы прошли путь от нейросетевого прототипа (Object Detection) к классическому CV-пайплайну на основе поиска ROI и анализа средней яркости ячеек. Хотя направление выбрано верно, реализация имеет ряд фундаментальных недостатков, которые снижают надёжность, усложняют калибровку и оставляют бреши в безопасности. На основе параллелей с успешно решённой задачей сшивки микроскопических изображений предлагается усовершенствованная гибридная архитектура, устраняющая выявленные проблемы.
Критика текущего решения
В таблице ниже обобщены основные недостатки, выявленные в ходе анализа.
+---+------------------------------------+------------------------------------------------------------------+ | # | Недостаток | Описание | +---+------------------------------------+------------------------------------------------------------------+ | 1 | Яркость как метрика состояния | Средняя яркость ячейки сильно зависит от экспозиции, бликов, | | | | модели камеры – это главная причина «адской калибровки». | +---+------------------------------------+------------------------------------------------------------------+ | 2 | Игнорирование лиц и рук | В реальном сценарии в кадре всегда присутствуют лицо и руки | | | | оператора, создающие мощные ложные градиенты и искажающие ROI. | +---+------------------------------------+------------------------------------------------------------------+ | 3 | Отсутствие анти-реплей защиты | Утверждение, что скриншот теряет смысл, ошибочно – запись экрана | | | | легко подменяет живой код, если не анализировать артефакты | | | | воспроизведения (ШИМ, зернистость). | +---+------------------------------------+------------------------------------------------------------------+ | 4 | Нет офлайн-страховки | При сбое онлайн-распознавания (блик, расфокус, перегрев) данные | | | | теряются – нет резервного механизма пересчёта по сохранённому | | | | буферу. | +---+------------------------------------+------------------------------------------------------------------+ | 5 | Временная фильтрация «голосованием»| Голосование по нескольким кадрам не учитывает динамику смены | | | | состояний (код меняется во времени), что может давать сбой при | | | | джиттере. | +---+------------------------------------+------------------------------------------------------------------+Предлагаемые улучшения (гибридная архитектура)
Каждое улучшение направлено на устранение одного из перечисленных недостатков.
+---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | # | Улучшение | Суть | Преимущества | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | 1 | Edge Density вместо яркости | Оператор Собеля/Кэнни – плотность градиентов внутри ячейки. | Инвариантно к освещению, | | | | Активная ячейка даёт высокую плотность, неактивная – низкую. | автоматическая калибровка. | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | 2 | Маскировка лиц и рук | Детектор MediaPipe (5 мс) – область лица заливается серым шумом | Устраняет ложные контуры и | | | | до поиска ROI. | перекрытия. | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | 3 | Анти-реплей через ШИМ-анализ | Анализ высокочастотного мерцания экрана (60–240 Гц) – у живого | Надёжная защита от видео-подделок. | | | | экрана полосы меняются, у видеозаписи – статичны. | | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | 4 | Online + Offline-арбитр | На устройстве – быстрый Edge Density (40–60 FPS). При низкой | 99.9% точность, страховка от сбоев. | | | | уверенности – буфер 3 сек отправляется на сервер, где запускается| | | | | HOG + Витерби. | | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+ | 5 | Калмановская фильтрация | Вместо голосования – фильтр Калмана, отслеживающий состояния с | Сглаживает шум и предсказывает | | | | учётом динамики переключений. | переходы. | +---+------------------------------------+------------------------------------------------------------------+---------------------------------------+Сравнительные таблицы эффективности
Таблица 4.1. Сравнение методов распознавания
+---------------------------+-----------------+-----------------+-----------------+-----------------+ | Метод | Скорость (CPU) | Устойчивость к | Учёт лиц / рук | Защита от реплея| | | (кадр/сек) | освещению | | | +---------------------------+-----------------+-----------------+-----------------+-----------------+ | Object Detection (YOLO) | 2–5 | Средняя | Частично | Нет | | Яркость + ROI + голос | 30–50 | Низкая | Нет | Нет | | Edge Density + маски | 40–60 | Высокая | Да (маскировка) | Нет | | Offline-арбитр (HOG+Витер)| 0.5–1 (внешний) | Очень высокая | Да (в модели) | Да (ШИМ+) | | **ГИБРИД (online+offline)**| 40–60 + резерв | Максимальная | Полная | Полная | +---------------------------+-----------------+-----------------+-----------------+-----------------+Таблица 4.2. Текущее решение vs предлагаемый гибрид
+------------------------------------+---------------------------+-----------------------------------+ | Параметр | Текущее решение | Предлагаемый гибрид | | | (яркость + ROI) | (Edge + маски + offline) | +------------------------------------+---------------------------+-----------------------------------+ | Калибровка под новое устройство | Десятки часов, ручная | Автоматическая по первому кадру | | Устойчивость к бликам / теням | Низкая (ошибки > 30%) | Высокая (< 2%) | | Учёт лиц и рук | Отсутствует | Маскировка, сбой < 1% | | Защита от реплей-атак | Отсутствует | ШИМ-анализ – отклонение 100% | | Производительность на слабых | 30–50 FPS (просадки) | 40–60 FPS (стабильно) | | Точность в сложных условиях | 70–80% | 98–99% (с offline – 99.9%) | | Возможность постобработки при сбое | Нет | Да (буфер + сервер) | +------------------------------------+---------------------------+-----------------------------------+Связь с задачей сшивки микроскопа (общая методология)
Обе разработки демонстрируют одну архитектурную закономерность – гибридный конвейер с разделением по времени и сложности. Ниже показано соответствие компонентов.
+---------------------+----------------------------------+----------------------------------+ | Компонент | Микроскопия (склейка) | MotionCode (распознавание) | +---------------------+----------------------------------+----------------------------------+ | Быстрый online- | Фазовая корреляция (FFT) | Edge Density + ROI | | сенсор | – грубый сдвиг | – грубое состояние ячеек | +---------------------+----------------------------------+----------------------------------+ | Точный корректор | Взаимная информация (локально) | HOG-дескрипторы (локально) | | (редкий вызов) | – уточнение при низкой уверен. | – уточнение при низкой уверен. | +---------------------+----------------------------------+----------------------------------+ | Offline-верификатор | Global Bundle Adjustment | Витерби + супер-резолюция | | | – устранение дрейфа | – восстановление последоват-ти | +---------------------+----------------------------------+----------------------------------+ | Учёт физических | Размытие, дефокус → анализ | Лица, руки → маскировка | | помех | качества кадра | | +---------------------+----------------------------------+----------------------------------+ | Ключевой вывод | Один кадр – мусор; | Один кадр – мусор; | | | только время даёт точность | только время даёт точность | +---------------------+----------------------------------+----------------------------------+Общий принцип:
· Online – дешёвая, инвариантная метрика (FFT / градиенты) работает на потоке. · Offline – тяжёлая оптимизация (BA / Витерби) вызывается при сомнениях или финально, обеспечивая абсолютную точность. · Помехи подавляются на раннем этапе (маски, фильтры качества).
Рекомендации по внедрению (приоритет)
Срочно заменить яркость на плотность границ – это снизит калибровку и повысит устойчивость.
Внедрить маскировку лиц (MediaPipe) на этапе предобработки.
Реализовать серверный арбитр: буфер 3 секунды, HOG + Витерби, вызывать при низкой уверенности.
Добавить ШИМ-анализ как дополнительный фильтр против видеоподделок.
Перейти от голосования к фильтру Калмана для учёта динамики кода.
Заключение
Предложенная гибридная архитектура устраняет фундаментальные недостатки исходного решения, обеспечивая промышленную надёжность, безопасность и простоту эксплуатации. Опыт, полученный при разработке системы сшивки микроскопических изображений, подтверждает универсальность данного подхода для широкого класса CV-задач на мобильных платформах. Рекомендуем авторам принять эти дополнения и представить обновлённую версию технологии.
Документ подготовлен в рамках экспертного аудита и может быть использован как техническое задание для следующей итерации разработки MotionCode.
funca
Вы наверное рассматривали вариант зашить в QR код локацию, OTP или что ещё требуется для подтверждения присутствия в данной точке в данный момент. Интересно, почему не пошли этим путем, вроде же все
простопонятно?stranget1918 Автор
Да, думали об этом. Но QR-код легко сфотографировать и переслать коллеге. Можно было показывать его недолго или быстро менять несколько QR-кодов, но тогда слабые телефоны просто не успевали бы их считать. Поэтому стали искать другой вариант.