Распознавание на собственном железе камеры
У GK7205V500, V510 и V530 есть нейронный ускоритель, и теперь на нём работает
YOLOv8: человек, велосипед, машина, мотоцикл, автобус, грузовик, кошка и
собака. Кадр 640×384 маленькая модель считает за 46–50 мс, большая за 102–112.
Найденное уходит туда же, куда и движение: в метаданные ONVIF, в рамки поверх
картинки в браузере, в дорожку внутри записи и в /api/v1/analytics.
Главное вот что: модели лежат прямо в прошивке, а ускоритель заводится сам. Ничего не докачивается, не компилируется и не настраивается. Такого на этих камерах ещё не было. По умолчанию выключено, включается одной строчкой.
Модели собирает только CI в репозитории xmnpu-models, поэтому у каждого файла видно коммит и прогон, который его сделал. Перед выкладкой проверяется, что урезанная до целых чисел модель находит то же самое, что исходная; не сошлось — сборка падает и не публикует ничего. Веса, картинки для калибровки и список классов закреплены по хешам.
Драйвер под всем этим написали заново и открыли. В прошивке лежал закрытый
npu.o из вендорского SDK, теперь там
свой код, который отдаёт
вендорской библиотеке то же устройство и те же вызовы. Заодно починили то, чего
в блобе не делали: брошенные задачи освобождаются, мьютекс не остаётся
захваченным, работающая задача не освобождается из обработчика прерывания.
Частоту подняли с 450 до 600 МГц.
Поворотная камера ведёт человека
На пульте в браузере появилась кнопка Follow, там же видна рамка на том, за кем камера идёт.
Работает по шагам: пока голова стоит и картинка устоялась, детектор отдаёт людей; камера выбирает одного и дальше держится за него, узнавая по рамке, ближайшей к прежней; голова доворачивается на столько шагов, сколько нужно, чтобы человек оказался в середине кадра. Пока голова едет, распознавание не слушают — кадры смазаны. Тронете пульт сами, через ONVIF или DVRIP — слежение встанет на паузу.
Резкость прямо во время поворота
Смаз при повороте считали нехваткой битрейта, а дело в выдержке: пока затвор открыт, картинка успевает уехать. Проверили в лоб — учетверённый битрейт поднимает резкость в 1,4 раза, короткая выдержка в 3,4.
Теперь камера знает, когда мотор крутится, и укорачивает выдержку ровно на это время: при повороте картинка вчетверо резче, а в покое поток не растёт ни на бит. Если держать короткую выдержку всегда, поток неподвижной камеры удваивается, поэтому так и не делают.
Попутно нашли, почему при повороте видео рвалось сразу у всех зрителей. Драйвер шаговых моторов отсчитывал паузы между шагами холостым циклом процессора, потому что ядро умело ждать только по 10 мс, и во время поворота это съедало 70–86% процессора. После правки в ядре — не больше 5%, а моторы ещё и ускорились: наклон втрое, с 13 до 41 шага в секунду. Отставшему зрителю камера теперь сама шлёт опорный кадр, как только разгрузится очередь: пауза 0,1–0,3 секунды вместо 0,8–1,0, потерянных кадров 2–3% вместо 11–13%.
Мерили на Goke GK7205V510 с сенсором MIS2009 и головкой на шаговых моторах, 1080p.
Защита от полос перестала гадать
Лампы от сети мигают сто раз в секунду, и если выдержка не кратна полупериоду, по картинке ползут полосы. Режим против них был, но включался только в сумерках, а в ярко освещённой комнате не срабатывал вовсе — ровно там, где полосы и видны. Теперь выдержку держат кратной всегда, и полос стало меньше процента вместо двадцати.
Ценой этого ломался день: на солнце камере нужна выдержка в пару миллисекунд, а короче десяти ей теперь нельзя, и кадр засвечивается. Отличить солнце от лампы по яркости не выходит: комната под двухсотваттным прожектором даёт 2,0 от цели, уличная сцена 2,46, так что любой порог ошибается в одну из сторон.
Поэтому камера ставит опыт. Когда картинка держится заметно выше цели на самой короткой кратной выдержке, камера на мгновение укорачивает выдержку и смотрит, появились ли полосы от лампы. Появились — свет сетевой, режим остаётся включённым, и следующий час эту сцену не переспрашивают. Не появились — свет ровный, то есть солнце, и выдержку отпускают. Картинка при проверке один раз моргает, меньше чем на полсекунды.
Экономный архив рядом с Xiongmai
storageSaver — для камер, у которых запись лежит неделями и диск стоит дороже
картинки. То же самое, что у других производителей зовётся H.264+, H.265+ или
H.265X. Ступени три: первая не выбрасывает ни одного кадра, просит примерно на
четверть меньше места и на движущихся частях кадра лучше обычных настроек; две
следующие экономят сильнее, до половины с лишним, но уже пропускают кадры.
Режим Xiongmai разобрали и повторили на своём стенде, считав настройки прямо с
их прошивки на ходу, так что сравнивали одно с одним. На спокойной сцене они
экономят 13%, мы 27%. На оживлённой их режим не экономит вовсе: поток вырастает
на 22% против обычных настроек, то есть делает хуже ровно тогда, когда в кадре
что-то происходит. А на движущихся частях кадра при одинаковом битрейте наш
режим archive рисует их лучше обычных настроек и не теряет ни одного кадра,
а их режим рисует хуже и выбрасывает половину.
Ещё
- Камера может читать SMS. Сообщения оператора про активацию, пополнение и кончающиеся деньги — на странице, а не через AT-команды с расшифровкой UCS2 вручную. Баланс по короткому коду, отправка своих, пересылка входящих в Telegram.
- Камера рассказывает о своих падениях. Лог ядра переживает перезагрузку, а majestic оставляет дамп с последними строчками, которые успел записать; отправить можно руками или автоматически. На сайте они складываются по подписи из пяти верхних кадров стека, поэтому один баг с сотни камер — одна строка. Открытый список лежит на /crashes, а за присланное падение дают звёзды клуба.
- Битрейт можно не задавать совсем. Ноль теперь означает «посчитай сам» — по разрешению, частоте кадров, кодеку и режиму управления битрейтом. Это новое значение по умолчанию.
- Ночью можно остаться в цвете, инфракрасная и белая подсветка разведены по отдельным каналам.
- Смена канала связи больше ничего не рвёт. Переехали с провода на LTE или обратно — SIP, отдача потока наружу, WHIP и сеансы WebRTC переподключаются по новому адресу. Открытая ссылка на камеру тоже остаётся живой.