
Комментарии 7
Вы наверное рассматривали вариант зашить в QR код локацию, OTP или что ещё требуется для подтверждения присутствия в данной точке в данный момент. Интересно, почему не пошли этим путем, вроде же все просто понятно?
Да, думали об этом. Но QR-код легко сфотографировать и переслать коллеге. Можно было показывать его недолго или быстро менять несколько QR-кодов, но тогда слабые телефоны просто не успевали бы их считать. Поэтому стали искать другой вариант.
Все равно не понятно, какую проблему вы решаете. Что мешает транслировать видео со стенда? Вопрос с дистанцией стандартно решается с помощью bluetooth, если точности в несколько метров достаточно.
С bluetooth всё не так просто. Он должен быть включён на телефоне, устройство нужно связать с планшетом, а после смены телефона настраивать заново. К тому же веб-панель может работать на устройстве без Bluetooth. Большая часть нашей аудитории это малый бизнес, владельцам которого нужно недорогое решение, работающее без сложной настройки. А от удалённых трансляций у нас в агоритме зашит PWM.
Проще говоря, для нашего целевого клиента, визуальный код более понятное и контролируемое решение , чем bluetooth, NFC, подключение по Wi‑Fi и подобные технологии.
В соседней ветке обсуждалась статья о склейке кадров микроскопа
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” для безопасности.
В соседней ветке обсуждалась статья о склейке кадров микроскопа
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.
От object detection к классическому CV: разрабатываем сканер для слабых смартфонов