Русский
Русский
English
Статистика
Реклама

Блог компании recognitor

RPi-няня

28.08.2020 10:04:17 | Автор: admin
Периодически меня подмывает сделать что-то странное. Очевидно бесполезную вещь, которая не оправдывает себя по объему вложенных средств, и через полгода после создания пылиться на полке. Но зато полностью оправдывает себя по количеству эмоций, полученному опыту и новым рассказам. На Хабре даже есть две моих статьи про такие эксперименты: Алкоорган и умная кормушка для птиц.
Что ж. Пришло время рассказать о новом эксперименте. Как собрал, что из этого вышло и как повторить.

К новому проекту меня подтолкнуло событие, в каком-то смысле, банальное родился сын. Я заранее устроил себе отпуск на месяц. Но ребёнок оказался тихим было свободное время. И спящий рядом деть.
Дома много разных embedded-железок для computer vision. В итоге решил сделать видео-няню. Но не такую унылую, которыми завалены все магазины. А что-то поумнее и поинтереснее.


Статья будет написана в повествовательном ключе, чтобы понять как шла разработка игрушки, куда она пришла и куда движется дальше.
У статьи есть несколько дополнений:
1) Видео где я показываю и рассказываю как всё работает.
2) Небольшая статья на VC где я рассказываю почему такие штуки скорее всего не придут в нормальный продакшн, и про ограничения ML систем такого плана.
3) Сорсы всего на гитхабе + готовый образ для RPi. В конце статьи описание как пользоваться.

Выбор идеи


Самый банальный функционал видеоняни посмотреть в любой момент что происходит с ребёнком. Но, к сожалению, это не всегда работает. Вы не будете смотреть трансляцию всё время, это не удобно. Младенца можно вообще положить спать рядом в коконе, зачем видео всё время? В итоге, для начала собралась следующая подборка:
  1. Система должна давать возможность посмотреть видео или фото в любой момент с телефона
  2. Система должна реагировать на просыпание ребёнка, и извещать об этом
  3. Система должна детектировать пропадание лица, для предотвращения СВДС


Выбор платформы


У меня была большая статья на Хабре про сравнение различных платформ. Глобально, для прототипа типа того что я делаю есть несколько вариантов:
  1. Jetson Nano. Есть на руках + я много с ним работал (не только с Nano), но меня немного смущает, что он более производственный. Из коробки запустятся только самые простые модели. Чтобы ускорить и оптимизировать память надо переносить на TensorRT. Это требует времени. Но все обученные сети надо искать, тестировать, не факт что запуститься их коробки, не факт что из коробки TensorRT пойдёт.
  2. VIM3. Никогда не использовал, попробовать было бы интересно. Но ради проекта для которого есть уже пять разных вариантов исполнения не хотелось тратить денег.
  3. Raspberry PI + Movidius. Есть большая пачка предобученных сетей. Производительности хватит, удобно работает, более менее стабилен.
    1. Абсолютно непроизводственное решение, но для игрушки сойдёт.
    2. Нереально переобучить выложенные сети. Не все сети обученные с нуля будут работать.
  4. Raspberry PI 4 при работе через OpenCV будет хорошо утилизировать открытые сети, чего должно хватить. Но, было подозрение, что не хватит производительности.
  5. Coral у меня он есть на руках, по производительности прошло бы, но в другой моей статье написано почему я его не люблю:)

Итого я выбрал Rpi+movidius. Есть на руках, умею работать с ним.

Железо


Вычислитель Raspberry Pi 3B, нейропроцессор Movidius Myriad X. С этим понятно.
Остальное поскрёб по сусекам, докупил.



Камера


Я проверил три разных, которые у меня были:
  • Камера от RaspberryPI. Шумная, неудобный кабель, нет удобного крепления. Забил.
  • Какая-то IP камера. Очень удобно потому что не надо включать в RPI. Камера разнесена с вычислителем. Моя камера имела даже два режима, дневной и ночной. Но та что была у меня не давала достаточного качества лица.
  • Веб камера от Genius. Я её использовал уже лет 5. Но что-то в последнее время стала работать нестабильно.А для RPI в самый раз. Более того, оказалось что её можно тривиально разобрать и достать оттуда IR фильтр. Плюс, как потом выяснилось, что это был единственный вариант с микрофоном.


А фильтр меняется вот так:



В целом, понятно, что это не продуктовое решение. Но работает.
Если что, то в коде увидите оставшиеся куски для перехода на другие два типа камер. Возможно даже что-то сходу заработает, если 1-2 параметра поменять.

Освещение


С одной из старых задачек у меня завалялся осветитель:
Подпаял к нему какой-то блок питания. Светит неплохо.

Направляю на потолок комната освещена.


Экран


Для некоторых режимов работы мне понадобился монитор. Остановился на таком. Хотя не уверен что это самое правильное решение. Может стоило взять полноформатный. Но про это позже.


Питание


Ребёнок спит в произвольных местах. Так что проще когда система питается от павербанка. Выбрал такой, просто потому что лежит дома для походов:


OpenVino


Пройдём немного по OpenVino. Как я сказал выше большим преимуществом OpenVino является большой объём предобученных сетей. Что нам может пригодиться:
Детекция лица. Таких сетей в OpenVino много:
  1. 1
  2. 2
  3. 3

Распознавание ключевых точек на лице. Это нужно нам чтобы запускать следующие сети
Распознавание ориентации лица. Активность ребёнка и куда смотрит.
Распознавание направление взгляда если пробовать взаимодействовать
Анализ глубины? Может быть получится
Анализ скелета
Ну и много других интересных
Основным минусом этих сетей будет их основное преимущество их предобученность
Это можно поправить, но сейчас мы делаем быстрый прототип, наша цель не работа в 100% случаев, а принципиальная работа которая будет приносить хоть какую-то пользу.

Поехали. Общая логика версии 1


Так как мы разрабатываем embedded устройство, то нам надо с ним как-то взаимодействовать. Получать фото/сигналы о тревоге. Так что решил сделать так же как когда делал кормушку, через телеграмм. Но довести до ума.
Для первой версии я решил:
  • Запустить на RPi обозначенные сети (хотелось бы сразу все, вдруг производительность позволит). Это позволит посмотреть больше вариантов решения задачи/вероятных путей развития
  • Написать общий шаблон программы.
  • Придумать алгоритм распознающий просыпание.
  • Сделать алгоритм присылающий уведомление при потере лица

Пошло всё более-менее неплохо, не считая кучи багов всего вокруг. Это свойственно для ComputerVision Я привык к этому:)
Вот краткая сводка того на что я натолкнулся:
  1. OpenVino под RPi не запускается в последней версии (на май 2020) из-за того что не срабатывает from openvino.inference_engine import IECore. Есть способы иначе использовать OpenVino (через OpenCV например), но там логика программы изменится, не хотелось.
  2. OpenVino старой версии не работает на новых сконверченных нейронных сетях, надо конвертить с -generate_deprecated_IR_V7 или брать старые
  3. OpenVino в последней версии (опять же, на май) с Movidius под виндой не может инферить сетки с int 8 из официального репозитория. В int32 может. Под RPi в int8 может. Ничего критичного, но сложнее дебажить.
  4. OpenVino не устанавливается под виндой в нестандартную папку. Точнее ставится, но все дальнейшие проблемы не решились и OpenVino не запустился. Про это много ругани, но судя по тому что у меня то же самое произошло так и не починили.
  5. OpenVino не работает на старых но мощных процах Intel (не везде дебажить удобно, но не критично).
  6. PyTorch в версии 1.5 не смог сконвертировать сети в onnx, пришлось конвертировать из 1.4


Но, тут как Уверен что если бы пошёл через TensorRT, то там бы проблем было как всегда больше.

Итак. Всё сбилжено, сети запущены, получаем что-то такое (запустив стек по голове, ориентации, ключевым точкам):

Видно, что лицо будет часто теряться когда ребёнок закрывает его руками/поворачивает голову. да и не все показатели стабильны.

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

Остальные графики грусть/злость/радость/удивление. Даже не особо суть того что где по цветам. К сожалению, данные сети нестабильны, что мы и видим. Нестабильность возникает когда:
  • Лишняя тень на лице (что ночью не редкость)
  • Лиц ребёнка не было в обучающей выборке OpenVino => произвольные переключения на другие эмоции
  • Ребёнок реально корчит рожи, в том числе во сне

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

Ок, с помощью эмоций просыпание не распознать. Пока что мне не хотелось обучать что-то самому, так что решил попробовать на базе тех же сетей но с другой стороны. Одна из сетей дает угол поворота головы. Это уже лучше (суммарное отклонение от взгляда в камеру во времени в градусах). Последние 5-10 минут перед просыпанием:

Уже лучше. Но Сын может начать махать головой во сне. Или наоборот, если поставить большой порог проснуться и не махать головой после этого. Получать каждый раз уведомление Уныло:

(здесь где-то час времени сна)
Значит надо всё же делать нормальное распознавание

Возникшие проблемы версии 1


Просуммируем всё что мне не понравилось в первой версии.
  1. Автозапуск. Не удобно запускать эту игрушку каждый раз заново, подключаться по SSH, запускать скрипт наблюдения. При этом скрипт должен:
    • Проверять состояние камеры. Бывает что камера выключена/не воткнута. Система должна ждать пока пользователь включит камеру.
    • Проверка состояния ускорителя. То же самое что с камерой.
    • Проверка сети. Штуку я хочу использовать и дома и на даче. А может где-то ещё. И опять же, заходить по ssh не хочу => надо сделать алгоритм подключения к wiFi если инета нет.
  2. Просыпание, обучение сети. Простые подходы не зашли, значит надо обучать нейронку на распознавание открытых глаз.

Автозапуск


В целом, схема автозапуска получилась следующей:
  • Запускаю на старте программу свою. Как я это делаю написал отдельную статью, не сказать что это на RPi сделать тривиально. Если кратко:
    • Создаю сервис который инициализирует OpenVino окружение
    • Сервис на старте запускает сначала скрипт проверки окружения, а потом основной рабочий скрипт
  • Проверяю наличие камеры
  • Проверяю наличие Movidius-модуля
  • Проверяю наличие интернета
    • Если нет запускаю камеру и жду QR-кода локальной wifi сети
  • Проверяю наличие информации о канале telegram через который будет управление. Если нет жду QR-код с данными на управление


Обучение сети для распознавания глаз


В OpenVino нет готовой сети для распознавания глаз.
Хахаха. Сеть уже появилась. Но её запушили, как оказалось, только после того как я начал разрабатывать. А в релизе и документации она появилась уже когда я более-менее всё сделал. Сейчас писал статью и нашёл апдейт.
Но, переделывать не буду, так что пишу как делал.

Можно очень просто обучить такую сеть. Выше я уже говорил, что использовал выделение глаз по кадру. Осталось всего ничего: добавить сохранение все встреченных на кадре глаз. Получается такой датасет:

Остаётся его разметить и обучить. Более подробно процесс разметки я описал тут (и видео процесса на 10 минут тут). Для разметки использовалась Толока. На настройку задания ушло~2 часа, на разметку 5 минут + 300 рублей бюджета.
При обучении думать особо не хотелось, так что взял заведомо быструю сеть, которая имеет достаточное качество для разрешения задачи mobilenetv2. Весь код, включая загрузку датасета, инициализацию и сохранение занял меньше 100 строк (большей частью взятых из открытых источников, переписал пару десятков строк):
Скрытый текст
import numpy as npimport torchfrom torch import nnfrom torch import optimfrom torchvision import datasets, transforms, modelsdata_dir = 'F:/Senya/Dataset'def load_split_train_test(datadir, valid_size = .1):    train_transforms = transforms.Compose([transforms.Resize(64),                                           transforms.RandomHorizontalFlip(),                                           transforms.ToTensor(),                                       ])    test_transforms = transforms.Compose([transforms.Resize(64),                                      transforms.ToTensor(),                                      ])    train_data = datasets.ImageFolder(datadir,                    transform=train_transforms)    test_data = datasets.ImageFolder(datadir,                    transform=test_transforms)    num_train = len(train_data)    indices = list(range(num_train))    split = int(np.floor(valid_size * num_train))    np.random.shuffle(indices)    from torch.utils.data.sampler import SubsetRandomSampler    train_idx, test_idx = indices[split:], indices[:split]    train_sampler = SubsetRandomSampler(train_idx)    test_sampler = SubsetRandomSampler(test_idx)    trainloader = torch.utils.data.DataLoader(train_data,                   sampler=train_sampler, batch_size=64)    testloader = torch.utils.data.DataLoader(test_data,                   sampler=test_sampler, batch_size=64)    return trainloader, testloadertrainloader, testloader = load_split_train_test(data_dir, .1)print(trainloader.dataset.classes)device = torch.device("cuda" if torch.cuda.is_available()                                  else "cpu")model = models.mobilenet_v2(pretrained=True)model.classifier = nn.Sequential(nn.Linear(1280, 3),                                 nn.LogSoftmax(dim=1))print(model)criterion = nn.NLLLoss()optimizer = optim.Adam(model.parameters(), lr=0.003)model.to(device)epochs = 5steps = 0running_loss = 0print_every = 10train_losses, test_losses = [], []for epoch in range(epochs):    for inputs, labels in trainloader:        steps += 1        inputs, labels = inputs.to(device), labels.to(device)        optimizer.zero_grad()        logps = model.forward(inputs)        loss = criterion(logps, labels)        loss.backward()        optimizer.step()        running_loss += loss.item()        if steps % print_every == 0:            test_loss = 0            accuracy = 0            model.eval()            with torch.no_grad():                for inputs, labels in testloader:                    inputs, labels = inputs.to(device), labels.to(device)                    logps = model.forward(inputs)                    batch_loss = criterion(logps, labels)                    test_loss += batch_loss.item()                    ps = torch.exp(logps)                    top_p, top_class = ps.topk(1, dim=1)                    equals = top_class == labels.view(*top_class.shape)                    accuracy += torch.mean(equals.type(torch.FloatTensor)).item()            train_losses.append(running_loss / len(trainloader))            test_losses.append(test_loss / len(testloader))            print(f"Epoch {epoch + 1}/{epochs}.. "                  f"Train loss: {running_loss / print_every:.3f}.. "                  f"Test loss: {test_loss / len(testloader):.3f}.. "                  f"Test accuracy: {accuracy / len(testloader):.3f}")            running_loss = 0            model.train()torch.save(model, 'EyeDetector.pth')


И ещё пара строк на сохранение модели в ONNX:
Скрытый текст
from torchvision import transformsimport torchfrom PIL import Imageuse_cuda=1mobilenet = torch.load("EyeDetector.pth")mobilenet.classifier = mobilenet.classifier[:-1]mobilenet.cuda()img = Image.open('E:/OpenProject/OpenVinoTest/face_detect/EyeDataset/krnwapzu_left.jpg')mobilenet.eval()transform = transforms.Compose([transforms.Resize(64),                                      transforms.ToTensor(),                                      ])img = transform(img)img = torch.unsqueeze(img, 0)if use_cuda:    img = img.cuda()img = torch.autograd.Variable(img)list_features = mobilenet(img)ps = torch.exp(list_features.data.cpu())top_p, top_class = ps.topk(1, dim=1)list_features_numpy = []for feature in list_features:    list_features_numpy.append(feature.data.cpu().numpy())mobilenet.cpu()x = torch.randn(1, 3, 64, 64, requires_grad=True)torch_out = mobilenet(x)torch.onnx.export(mobilenet, x,"mobilnet.onnx", export_params=True, opset_version=10, do_constant_folding=True,input_names = ['input'],output_names = ['output'])print(list_features_numpy)


Сохранение модели в ONNX нужно для дальнейшего вызова модели в Open Vino. Я не запаривался с преобразованиев в int8, оставил модель как была в 32-битном формате.

Анализ точности, метрики качества?.. Зачем это в любительском проекте. Такие штуки оцениваются по-другому. Никакая метрика не скажет вам система работает. Работает система или нет вы поймёте только на практике. Даже 1% ошибок может сделать систему неприятной для использования. Я бывает обратное. Вроде ошибок 20%, но система сконфигурирована так, что они не видны.

Такие вещи проще смотреть на практике, будет работать или нет. И уже поняв критерий работы вводить метрики, если они будут нужны.

Проблемы версии 2


Текущая реализация качественно другая, но всё же она имеет ряд проблем:
  • Лицо детектируется не всегда. Это особенность вызвана тем, что сеть обучалась для других условий:
    • Целевым объектом сети были явно не младенцы
    • Сеть не обучалась в ИК
    • Сеть явно отдаёт преимущество вертикальным лицам
    • Сеть явно предпочитает лица размером где-то в кадра.

  • Иногда ребёнок может проснуться не открывая глаз. Скорее всего при этом он будет махать головой. Но, как мы показали выше, махание головой не есть однозначное просыпание. Так что хотелось бы детектировать звук, чтобы понять проснулся или нет.
  • Мы получили неплохую платформу детектирования просыпания. А что ещё можно сделать на её базе?


Переобучить детект лица?


Я не стал переобучать детект лица. В отличие от распознавания глаз тут сильно больше работы. И со сбором датасета, и с качественным обучением.
Конечно, можно заоверфититься на лицо сына, наверное даже чуть лучше работать будет чем текущая сеть. Но по остальным людям нет. И, возможно, по сыну через 2 месяца тоже нет.
Собирать нормальный датасет долго.

Звук


Можно было бы пойти по классическому пути распознавания звука, и обучить нейронку. В целом это было бы не очень долго, максимум в несколько раз дольше чем распознавание глаз. Но мне не хотелось возиться со сбором датасета, так что воспользовался более простым способом. Можно использовать готовые инструменты WebRTC. Получается всё элегантно и просто, в пару строк.
Минус, который я нашёл на разных микрофонах качество работы решения разные. Где-то тригериться со скрипа, а где то только с громкого крика.

Идём дальше, что ещё


В какой-то момент я провёл тест, запустив зацикленное 5-секундное видео себя с супругой:



Был видно, что сын залипает на лица людей в поле зрения (монитор подвесил его минут на 30). И родилась идея: сделать управление выражением лица. Это не просто статичное видео, но и вариант взаимодействия. Получилось как-то так (при смене эмоции сына происходит переключение видеоряда):

Папа, ты что, долбанулся?!

Наверное, надо попробовать с большим монитором. Но пока не соберусь.
Может надо подменить проигрываемое видео. Благо это просто видео проигрывается из отдельных картинок, где смена кадров подстраивается под FPS.
Может надо подождать (на текущем уровне ребёнок мог банально не понять связи своих эмоций и экрана)

А потом?


Одним и перспективных направлений, мне кажется, попробовать сделать управление какими-то физическими обектами/лампочками/моторчиками через направление взгляда/позу.
Но пока глубоко не продумывал этот вопрос. Скорее пока что буду тестировать управление эмоциями.

Как всё в итоге выглядит, описание, мысли


Как сейчас всё работает (в начале статьи есть более масштабное видео):
  • Всё управление идёт через Telegramm + через камеру.
  • Если не нужно управление видео эмоциями, то вся девайсина выглядит так:

  • Запускается включением питания на павербанке.
  • Если есть подключенная сеть то устройство уже готово к работе
  • Если нет сети то надо показать QR-код с сетью, система автоматически запуститься
  • Через Telegramm можно выбрать набор событий за которыми следить:

  • Каждый раз когда происходит событие которое интересно, присылается уведомление:

  • В любой момент можно запросить фотографию с устройства чтобы посмотреть что твориться


В целом отзывы от себя любимого:
  1. Детектор лица работает не очень. Это реально особенность любых детекторов нефайнтьюненых на детей. Обычно это не мешает детектировать просыпание (хоть парочка нормальных фото с открытыми глазами да придёт). Сейчас нет планов переобучать.
  2. Без экрана немного непрозрачный запуск (считался QR код или нет). А с экраном много проводов. Я думаю, самый правильный вариант будет посадить диодов на GPIO. И зажигать их в зависимости от статуса (есть коннект, не работает камера, не работает Movidius, нет коннекта к telegram'у, и.т.д.). Но пока не сделал
  3. Иногда сложно закрепить камеру. Так как у меня есть пара штативов как то справляюсь. А без них, пожалуй, ничего бы не заработало.
  4. Реально позволяет освободить сколько-то времени и дать свободы перемещения. Больше это чем у нормальной радионяни/видеоняни со стримингом? Не знаю. Может чуть-чуть проще.
  5. Прикольная штука для экспериментов.


Как запускать


Как я и говорил выше я попробовал выложить все исходники. Проект большой и разветвлённый, так что может что-то забыл или не дал подробных инструкий. Не стесняйтесь спрашивать и уточнять.
Есть несколько способов всё развернуть:
  1. Сорсы с гитхаба. Это более сложный способ, придётся долго настраивать RPi, может что-то забыл. Зато вы полностью держите процесс под контролем (включая настройки RPi).
  2. Использовать готовый образ. Тут можно сказать что безблагодатно и несекьюрно. Зато на порядок проще.


GitHub


Основной репозиторий расположен тут github.com/ZlodeiBaal/BabyFaceAnalizer
Он состоит из двух файлов которые надо запускать:
  1. Скрипт инициализации/проверки состсояния/настройки сети QRCode.py (для этого скрипта, напомню, есть более подробное описание). Он подключает WiFi и проверяет что имеется настройки для бота в Telegram.
  2. Основной рабочий скрипт face.py

Кроме того. в Git нет двух вещей:
  1. Файла с креденшоналами WiFi wpa_supplicant_auto.conf
  2. Файла с креденшоналами Telegram бота tg_creedential.txt

Можно позволить система создать их автоматически при следующем запуске. Можно использвать следующие, заполнив пустые поля:
tg_creedential.txt
token to access the HTTP API чтобы его получить, отправьте @BotFather в telegram команду "/newbot"
socks5:// по умолчанию не используется, но должна быть пустая строчка хотя бы
логин для socks5 по умолчанию не используется, но должна быть пустая строчка хотя бы
пароль для socks5 по умолчанию не используется, но должна быть пустая строчка хотя бы


wpa_supplicant_auto.conf
network={
ssid="******"
psk="*******"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}


Свистелки и перделки по настраиванию RPi


К сожалению, просто положить и запустить скрипты на RPi не получиться. Вот что ещё надо для стабильной работы:
  1. Установить l_openvino_toolkit_runtime_raspbian_p_2020.1.023.tgz по инструкции docs.openvinotoolkit.org/latest/openvino_docs_install_guides_installing_openvino_raspbian.html
  2. Установить автозапуск
  3. Удалить мессадж о дефолтном пароле (может не надо, но мне мешало) sudo apt purge libpam-chksshpwd
  4. выключить скринсейвер www.raspberrypi.org/forums/viewtopic.php?t=260355
  5. Для детекции аудио:
    • pip3 install webrtcvad
    • sudo apt-get install python-dev
    • sudo apt-get install portaudio19-dev
    • sudo pip3 install pyaudio
  6. Скачать модели из репозитория OpenVino используя скрипт Get_models.py в папке Models


Образ


Образ выложен тут(5 гигов).
Пара моментов:
  1. Используется стандартный логин-пароль (pi, raspberry)
  2. Включен доступ по SSH
  3. По умолчанию не подключен WiFi и не настроен адрес бота в телеге которого система будет использовать для контроля.


Как настроить WiFi в образе


Первый вариант после запуска показать QR код с текстом:
WIFI:T:WPA;P:qwerty123456;S:TestNet;;

Где после P идёт пароль сети, после S индентификатор сети.
  1. Если у вас есть телефон с Android 10 то там такой QR код генерируется автоматически при нажатии поделиться сетью
  2. Если нет то можно сгенерировать на www.the-qrcode-generator.com


Второй вариант зайти по SSH на RPi (подключившись по проводу). Либо включить монитор и клавиатуру. И положить файл
wpa_supplicant_auto.conf
network={
ssid="*********"
psk="*******"
proto=RSN
key_mgmt=WPA-PSK
pairwise=CCMP
auth_alg=OPEN
}

c вашими настройками wi-fi в папку "/home/pi/face_detect".

Как настроить телеграм-бота в образе


Первый вариант после запуска показать QR код с текстом:
tg_creedential.txt
token to access the HTTP API чтобы его получить, отправьте @BotFather в telegram команду "/newbot"
socks5:// по умолчанию не используется, но должна быть пустая строчка хотя бы
логин для socks5 по умолчанию не используется, но должна быть пустая строчка хотя бы
пароль для socks5 по умолчанию не используется, но должна быть пустая строчка хотя бы

сгенерировав его через www.the-qrcode-generator.com
Второй вариант зайти по SSH на RPi (подключившись по проводу). Либо включить монитор и клавиатуру. И положить файл tg_creedential.txt описанный выше в папку "/home/pi/face_detect".

Ремарка про детство


Уже когда собрал первую версию и показывал её своей маме, то получил внезапный ответ:
-О, а мы в твоём детстве почти так же делали.
?!
Ну, коляску с тобой на балкон выставляли, через форточку туда выкидывали микрофон, который был включен в усилитель в квартире.

Вообщем внезапно оказалось что это наследственное.

Ремарка про супругу


А как супруга отнеслась?
А как она позволила тебе эксперименты над сыном ставить?!
Спрашивали не раз.
Но, я жену испортил хорошо. Вот, она даже на Хабре иногда статьи пишет.

P.S.1


Я не специалист по ИБ. Конечно, я попробовал сделать так, чтобы никаких паролей нигде не светилось, и.т.д., а каждый смог сконфигурировать под себя, указав всю секьюрную информацию после старта.
Но не исключаю что что-то где-то не досмотрел. Если увидите явные ошибки попробую исправить.

P.S.2


Скорее всего про апдейты по этому проекту буду рассказывать в своём телеграм-канале, либо в группе вконтакте. Если накопиться много интересного, то сделаю ещё одну публикацию тут.
Подробнее..

Edge платы для домашнего Computer Vision

13.04.2021 06:09:41 | Автор: admin

Я люблю делать всякие странные штуки с Computer Vision. Из того, что я выкладывал на Хабре - умная кормушку для птиц и камера для слежения за ребенком. По работе примерно тем же занимаюсь. Так что слежу за актуальным рынком embedded устройств для ComputerVision. Прошлый обзор я делал полтора года назад. Для Embedded это долго. В этом я сосредоточусь на устройствах которые вышли недавно + некоторый анализ что из этих устройств можно использовать дома/для хобби.

Рассказ будет построен следующим образом:

  • Продуктовые железки которые стали классикой продакшна / железки которые почти доросли до таких.Их можно взять и запустить из коробки. Большие OpenSource комьюнити/персональные фреймворки. Время развертывания обученной сети на такой железке в 1-2 дня.

  • Продуктовые железки которые почти стали классикой, но по которым слишком мало открытых проектов/документации/где часть проекта закрыта. В таких проектах сложно ожидать большой подставы, и скорее всего все будет более-менее будет работать. Но вот что нужно будет сделать для работы сети, и как её сконвертировать, как перенести - нельзя будет оценить заранее.

  • Железки которые выглядят интересно, но нет ни гайдов по ним, ни историй успехи, ни подробной документации.

  • Железка есть информации почти нет/нельзя получить без запросов. На рынке нет истории использования/успеха.

Сразу несколько дисклеймеров, чтобы не возвращаться к ним:

  • Далеко не все из перечисленного я лично использовал/тестировал

  • Далеко не все перечислено. Я уверен что забыл/не знаю многое. И очень надеюсь что в комментарии накидаете чего-нибудь интересного

  • Я фокусируюсь на устройствах где есть GPU/NPU или прочие ускорители инференса. Безусловно, есть всякие FPGA, и прочее, но я не считаю их применимыми для хоббийных проектов. (что такое NPU GPU TPU и другие аббревиатуры - можно прочитать в этой замечательной статье)

Часть 1. Ближе всего к продукту

С одной стороны, весь этот раздел можно было бы свести к простому перечислению:

  • Jetson

  • Intel

  • Coral

  • Android телефоны

  • Прочие Embedded, устройства с хорошим процессором, без NPU/GPU

И в этом списке за последние 2 года появился бы лишь Coral. Но, в реальности, все сильно интереснее. Появились не только и не столько новые архитектуры, как имплементации/доработки старых. О чем мы и поговорим.

В мире Jetsonов новинок нет. Сейчас в продаже:

  • jetson nano

  • jetson xavier nx

  • jetson agx

  • jetson tx2

12ого началась конференция GTC от NVIDIA, но ничего нового на ней не объявили, так что, скорее всего, на следующий год ничего нового не будет.

Встречаются имплементации Jetson'а, под другие экосистемы. Самое известное - AWS Panorama. Jetson находящийся внутри экосистемы Амазона.

PanoramaPanorama

Jetson, безусловно, одна из самых удобных плат для хобби. Есть разводка GPIO, много кода который работает из коробки. Нейронные сети можно никуда не конвертировать, используя в оригинальном фреймворке.
Cтоит понимать, что из всех четырех Jetson'ов для хобби лучше всего подходит Nano. Он стоит лишь 100$, что значительно меньше следующего в серии NX, стоящего 400$. В теории, TX2в середине, но его почти нет в продаже + менее удобная плата. Проектов на Jetson очень много. Например из того что было в медийном пространстве - 1, 2. Вот тут есть неплохая подборка.
Лично я участвовал где-то в 5-7 проектах где Jetson был основной платформой. 2-3 из них переросли в полноценные продукты. Но, вынужден сказать, что для хобби его не использовал ни разу. Почему? Какая-то совокупность факторов всегда. Nano у меня был первой серии, там были баги по питанию. Иногда была не нужна производительность дополнительная. Иногда хотелось опробовать чего-то нового.

В отличие от Jetson, на базе Movidius появляются интересные штуки. В первую очередь это M.2 и mPCIe карты. Какие-то даже уже были, когда я писал прошлый обзор: 1, 2, 3.
Сейчас их очень много от разных производителей.

Удобны ли ли они для каких-нибудь прототипов и хобийных проектов? Мне кажется, что ниша есть, но очень узкая:

  • Когда надо много производительности (есть сборки где есть несколько мовидиусов)

  • Когда USB соединение слишком нестабильно, но M.2/PCIe хватит (переносные устройства)

Во вторую очередь - это ряд устройств от luxonis. Они устраивали большую компанию на кикстартере про OAK и OAK-D. OAK это платы где movidius воткнут не на материнскую плату, а на плату с камерой. Кроме того, у них есть несколько устройств с movidius когда он стоит на плате 1, 2. Я не буду вдаваться подробнее тут, кому интересно - про них я делал более подробный обзор у себя в блоге/на Youtube:

Кому лень читать/смотреть - вот краткая выдержка:

  • + Минус одно USB соединение + к стабильности - для части проектов полезно

  • - От USB все равно не уйти - до прода скорее всего не дойдет

  • + Неплохой дизайн, неплохой корпус

  • - Заменили хороший OpenVino на какой-то мутный DepthAI

  • - Дорого. Дороже чем собрать такое с оригинальным Movidius'ом, дороже чем с Jetson Nano

  • - В камере хорошее разрешение, но провален куда более полезный функционал для машинного зрения (ИК диапазон, нормальное управление выдержкой/частотой, синхронизация с вспышкой, и.т.д.)

Мне куда больше понравились эти две платы 1, 2. Но тут сразу понятно, что на первой оочень слабый процессор, а вторая дорогая и там есть лишнее соединение.

Кроме luxonis до movidius'а в камере догадался FLIR, достаточно крупный производитель камер. Они выпустили FireFly DL, который явно на порядки более продуктовый чем OAK, а стоит только на 100$ дороже (+объектив).

Чтобы закончить с Movidius окончательно. По простоте использования/наличию документации/комментариям и поддержке - на мой взгляд Movidius - это один из самых разумных ускорителей для своих проектов на нейронных сетях. Его минус - сложный переход с продакшну, и необходимость конвертации сети. То что вышло за последние годы - расширяет возможности использования. Но все же мне не хватает плат сравнимых с RPi3 где мовидиус бы стоял напрямую на плате.

Google Coral. Вот тут много нового. В своем прошлом обзоре я был крайне недоволен им - очень ограниченные платы, очень бажные. Но прогресс. Баги пофикшены, выпущена новая линейка. Есть почти все то же самое что и в movidius, только напрямую от производителя - отдельные платы, стики, M.2, pci-e, чистые чипы, и.т.д..

В качестве основного фреймворка - специальный tflite, где уже сильно меньше потерь на конвертации. Но, как видно, слоев все равно сильно меньше чем в том же ONNX.
Из плюсов, про которые не сказал - на базе Coral уже сторонние производители создают свои решения. Например Asus. Из минусов - считанные разы слышал что его использовали в продакшене. И, обычно, для каких-то простых задач.
Для себя я понимаю почему я избегаю Coral - при прочих равных не хочу трогать TensorFlow. А по текущим характеристикам он нигде не превосходит вариантов выше.

Телефоны. Так же, стоит отметить, многие телефоны получили поддержку из плат сопроцессоров для нейронных сетей. Есть несколько фреймфорков для инференса моделей на них. Например тут и тут описывал. Зачастую телефон стал удобнее чем embedded для пилота и хобби. Основной минус - отсутствие периферии. Второй серьезный минус для меня - внутренняя инфраструктура приложений. Конечно, Unity и Flutter упрощают логику использования. Но все же, лично для меня, телефоны сильно сложнее чем Linux-системы.
С другой стороны, в телефоне уже есть и камера и акселерометр, и интернет.

Прочее. Под "прочим" я в первую очередь подразумеваю системы где заход в нейронные сети идет со стороны процессора. Например в процессорах Intel за счет OpenVino можно сильно оптимизировать сети. На некоторых процессорах, например на RaspberryPI есть оптимизация под инструкции Neon. RPi4 вполне может справляться с какими-то задачами детекции и трекинга в реальном времени. Так что если вам нужно с помощью машинного зрения раз в день проверять рассаду - думаю подойдет.

Часть 2. Работает, но мало информации

Есть такая забавная штука. В ML сейчас 90% знаний открыто. Есть статьи, большая часть публикаций с OpenSource. Подробнейшие фреймворки на Nvidia и Intel. Но рынок аппаратных платформ был исторически не такой. Хотите подключить камеру по csi-mpi к своей платформе? Будьте добры купите дорогущий мануал по протоколу. Хотите разрабатывать на нашей платформе? Для этого вам нужно специальное программное обеспечение которое просто так вы не скачаете. И много фирм по производству железа по-другому и не мыслят. Как результат мы имеем полтора гайда на платформу до её покупки. Невозможность протестировать до покупки. Отсутствие форумов по теме. И проблему с каждой функцией где что-то пошло не так.

При этом платформы становятся популярнее и популярнее, реализовать можно все больше и больше. К таким платформам я в первую очередь отношу:

  • RockChip

  • Gyrfalcon

Обе платформы я видел в проде. Даже немного экспериментировал. Но у обоих платформ крайне неудобный фреймворк переноса сетей/использования.

RochChip. Основная платформа на которой все делается - Rockchip 3399Pro. Самая популярная реализация, наверное - Firefly, RockPiN10 или Toybrick.

Что забавно, у того же ASUS есть версия не только на базе Google Coral, но и на базе RockChip.
Сейчас разрабатывается новая версия - 1, 2.
В целом, плюс RockChip'а - это плата которую любят все разработчики железа. Есть референсный дизайн, комплектующие, и.т.д. Собрать продукт проще и быстрее чем на Jetson.
Но перенос сети весьма непредсказуем. Документация куцая и полукитайская. Как поддерживается - не понятно. Я видел несколько проектов где сети все же перенесли. Но, гарантировать что это всегда можно, нельзя.

Gyrfalcon. Вторым примером закрытой архитектуры, но на базе которой я видел проекты - является Gyrfalcon

Забавно, что платы на его базе в продаже почти отсутствуют. Что-то из того что есть: 1, 2, 3 .

Если я правильно понимаю, Gyrfalcon ориентирован на корпоративный рынок. Отсюда и закрытость инфраструктуры и мало число девайсов в продаже. Глобально, с прошлой моей статьи ничего особо не поменялось.

Делать ли свои проекты на базе этих платформ? Подходят ли они для хобби? В целом, такое мне кажется возможным. Главное чтобы были простые сетки. Классификация/базовая детекция, и.т.д.
По цене такие платформы достаточно дешевы и сравнимы с OpenVino|Jetson вариантами.
Но надо серьезно понимать зачем так делать. Это может быть:

  • желание сделать продукт из своей разработки

  • желание распаять свою систему

  • нехватка в Jetson|RPi каких-то возможностей

Я ни разу не испытывал такой необходимости. Но это может быть логичным для кого-то.

Часть 3. Внешне все выглядит неплохо, есть какая-то документация, но примеров нет

Пожалуй, сюда я отнесу только одну плату Khadas VIM3 . Много кто о ней знает, но не видел ни одного человека который бы что-то на ней сделал. Есть в открытой продаже, просто купить. Заявлены неплохие параметры по скорости.

Судя по документации перенос моделей достаточно простой. Но, так как никто не пробовал/не тестировал, - не понятны ограничения. Сама плата собрана на базе процессора Amlogic A311D, который содержит NPU модуль. Amlogic многие позиционируют как конкурент RockChip, сравнивая их. Но сравнений именно NPU модулей - нет.

Все что я говорил в прошлом раздели про проекты - глобально справедливо и тут. Единственное, внешне мне приятнее подход Khadas - документация открыта, поддерживаемые гиты, вроде все на русском английском. Возможно как-нибудь возьму попробовать, но пока лень. По цене выглядит неплохо, на уровне Jetson.

Часть 4. Железки есть, информации нет

Большая часть плат тут имеет очень слабую документацию. Часть плат - это отладочные платы для мобильных платформ. Другая часть - платы специально под ML, но по которым очень мало информации и данных в интернете.

BeagleV. Плата которая пока не вышла, но выглядит неплохо. Разработана на базе процессора U74 от SiFive. Используется RISC-V архитектура.

BeagleBoard - странная плата с комьюнити вокруг. Именно вокруг этого комьюнити частично построена плата BeagleV. Плата сделана на базе NPU модуля от Texas Instruments. Вроде даже какие-то репозитории есть:

  1. Фреймворк от TI для обучения нейронных сетей. Аж 55 звезд на гитхабе.

  2. Репозиторий платы. Аж 88 звезд.

Считать ли это "популярным" решением - не уверен. Но, возможно, какие-то базовые сети запустить будет можно.

Пример настоящего Edge (минимальное использование ЦПУ и энергоэффективности) это - Sipeed Maixduino и Grove AI Hat. Но, разработка на них, судя по отзывам, которые я слышал, ужасна. Сети плохо поддерживаются, мало производительности. Вот тут пример использования. Ну, по сути все проблемы обычного Arduino.
Я видел людей которые делали и адекватные проекты на их базе, и хоббийные. Но я не готов:)

Глобально, Qualcomm - это, конечно, производитель процессоров для мобильных. Но, на их же базе, есть какое-то количество именно embedded платформ. При этом, Qualcomm - имеет свой SDK, и свою платформу для исполнения нейронных сетей. Года 2.5 назад я сталкивался с ней. И тогда там была жесть. Простейший слой сложения не поддерживался. Что там говорить про сплиты или объединения. По сути работал лишь VGG на трехканальный вход.
Сейчас, судя по слухам все лучше. К тому же, должен нормально работать Tensorflow lite.
Но вот с платами под эмбеддед у Qualcomm плохо. Есть вот такое (но стоит почти 500 баксов). Или вот такое (мало информации, но выглядит прикольно, за 300 баксов камера + корпус + ускоритель = неплохо).

Примерно так же себя ведет Huawei. Есть фреймворк. Не пользовался, и не знаю. Есть какое-то количество плат. Должен работать Tensorflow lite.
Но, мне сложно придумать где такая плата будет иметь смысл на использование.

Наверное, стоит добавить и Модуль. Как никак отечественные производители. Но, понятно, вся документация открыто не выложена, не слышал про успешное применение, и.т.д.
Но, наверное, для госсектора кто-то применять может.

В целом, вся группа последних девайсов, очень на любителя. Иногда они могут иметь смысл для прода. Иногда, для получения новых навыков. В любом случае, чем больше платформ и вариантов развития - тем интереснее и больше выбор.

P.S.

Про девайсы которые попадают мне в руки/про которые я читаю - иногда пишу у себя в блоге (telegramm, vk). Наверное, через год-два проапдейчу тут что накопится.
Прошлый апдейт делал на ютубе.

Подробнее..

Одноглазый глубиномер

21.09.2020 10:09:24 | Автор: admin

Недавно вышла интересная статья от FaceBook о том как можно делать неплохой 3D с монокулярных камер. Статья не очень применимая на практике. Но по качеству картинки завораживает:

Посмотрев на это я решил сделать небольшой рассказ о том что в статье твориться, куда современные технологии пришли, и что можно ждать от них на практике.


Начнём с основ. Существует несколько способов снять 3D:

  • Активная 3д камера (лидар, проекционная, TOF). Излучаем-измеряем.

  • Стерео камера. Оцениваем глубину из геометрии.

  • Монокулярные. Используем для оценки глубины либо опыт, либо сдвиг камеры.

В этой статье мы будем разбирать монокулярное. В чём его сложность? Да вот:

Эта картинка очень хорошо описывает основную проблему. Даже человек не может оценить глубину с одного ракурса.Что-то может, но точность будет не очень + возможна масса ошибок.

Как с этим борются? Камера должна двигаться, а место действия не должно меняться. Алгоритмы которые могут собрать из это картинку называются SLAM. Логика там более-менее одинаковая (описываю грубо):

  • На первом кадре выделяем набор фич и кладём их в общий мешок.

  • На каждом новом кадре выделяем фичи, сравниваем их с фичами из мешка.

  • Найдя пересекающиеся - можно оценить текущий сдвиг относительно прочих кадров, а для всех фич из мешка - оценить положение

Вот пример того как это работает из далёкого 2014 года (но вообще было и сильно раньше):

У алгоритмов есть одна забавная бага. Вы не можете знать абсолютные расстояния в полученной сцене. Только относительные.

Но это не сложно исправить замерив хотя бы один объект.

Хорошие SLAM-алгоритмы появились ещё лет десять назад. Сейчас вы можете найти их в AR Core или ARKit, которые доступны почти на каждом телефоне. Вот как это будет выглядеть прямо из коробки без всяких лидаров:

Эти же алгоритмы используются в:

  • Алгоритмах восстановления 3Д по серии кадров (фотограмметрия)

  • Алгоритмах дополненной реальности для редактирования видео

  • Алгоритмах ориентации в дронах

  • И прочее и прочее

Из лучших доступных OpenSource алгоритмов такого плана сейчас есть COLMAP. Он удобно упакован, много исследователей используют его для создания базового решения.
Но в чём проблем таких алгоритмов?

Все SLAM алгоритмы не дают достаточную плотность 3D:

colmapcolmapLSD-SLAMLSD-SLAM

Как с этим борются?

Подходов много. Раньше были аналитические, а сейчас более популярные - через нейронные сети. Собственно, о двух-трех самых популярных и интересных мы и поговорим.
Мы будем говорить именно про самые популярные. Почему не про самые точные? Это интересный вопрос. Если мы говорим самые точные, то мы должны, например, формализовать по какому датасету сравниваем точности. Таких датасетов много.
Но вот суровый минус - они все специфичные. И зачастую сети имеющие хорошие точности на таких датасетах - работают только на них. Хорошим примером является KITTY:

Сети оптимизированные и хорошо обученные по нему - будут не очень хорошо работать на других данных.

При этом зачастую восстановление 3Д это уже не простой констракт плана проверить на датасете глубину, а что-то более сложное, такое как проверить точность восстановления объекта, или оценить точность на всей видеопоследовательности. И тут уже датасетов будет мало, сложно по ним бенчмаркаться.

Если посмотреть на какой-нибудь сабтаск оценки глубины - Depth Estimation, то по каждому конкурсу будет всего одна-две работы.
Так что смысла говорить о самом точном нет. И я буду рассказывать, на свой взгляд о самом интересном и полезном, что показывает разные подходы.

MiDaS

Начнём с замечательного MiDaS. Он вышел год назад, и смог инкапсулировать в себя огромное множество идей:

  • Смогли одновременно обучаться на множестве датасетов с разнородными данными. На стереофильмах, на данных с датчиков глубины, на сканах местности, и.т.д.

  • Натренировали принципиально разные выходы модели для прогнозирования глубины + различные способы смешивания для получения оптимальной оценки.

  • Смогли сделать эту модель достаточно быстрой

Кроме того MiDaS доступен из коробки на разных платформах:

И то и то можно запустить минут за десять. А результат? В первом приближении как-то так:

Видно, что тут оценка глубины есть в каждой точке. Но сразу видно что:

  • Видна нестабильность глубины от кадра к кадру

  • Нет абсолютных значений размера (что типично для монокулярных задач)

  • Глубина достаточно неплохо обрабатывается, в том числе для объектов на похожем фоне

Но, естественно, доверять однозначно таким вещам нельзя:

Полный скан

Устранить дрожание во время кадра можно за счёт учёта соседних кадров и нормировки за их счёт. И тут на помочь приходят ранее упомянутые SLAM алгоритмы.С их помощью строят профиль перемещения камеры, делают привязку каждого кадра к общему плану.
Есть несколько алгоритмов которые такое реализуют. Например Атлас и DELTAS

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

Второй примерно так же, но чуть сложнее:

Есть чуть более хитрые подходы, когда нейронная сеть оценивает глубину как Мидас, и проецирует напрямую в TSDF.
Какая точность у таких методов? Конечно куда меньше чем у любой аппаратуры оснащенной нормальным 3D сканером. Например очередной сканер на iPhoneовском лидаре:

Consistent Video Depth Estimation

Можно ли добиться большего, но с монокулярной камеры? Да, можно. Но для этого надо отправляться в сторону алгоритмов которые оценивают глубину по серии кадров в последовательности. Примером такого алгоритма может быть Consistent Video Depth Estimation.
Его особенностью является интересный подход, когда берётся два снимка из последовательности, для которых через ранее упомянутый SLAM оценивают сдвиг. После чего эти два снимка служат инпутом для обучения модели под текущее видео:

Да-да, для каждого видео обучается (дообучается) отдельная модель.И как-бы основной минус такого подхода - его время. Расчет занимает 4-5 часов на 10-секундное видео. Но результат восхищает:

Почему я привожу тут видео из примеров? Банально. Потому что запустить эту конструкцию, даже при наличии colab по своему видео я не смог.

Но на текущий момент такая штука показывает State-Of-Art в распознавании глубины в видео. А больше примеров можно посмотреть тут.

В формате видео

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

Заключение

В целом, на мой взгляд, для серьёзных задач монокулярный depth не нужен. И в будущем, скорее всего, везде где нужен будет хороший depth - проще будет использовать какой-нибудь лидар, благо точность растет, а цена падает. И в лидарах и в стереокамерах вовсю используются те же самые нейросети. Только вот в лидарах и стереокамерах есть оценка реальной глубины по одному кадру - что делает их априори точнее.
Но это не отменяет того что сегодня Monocular Depth уже используется в десятках применений где он удобнее. И, возможно, в будущем, за счёт повышения качества, он станет использоваться ещё чаще.

p.s.

В последнее время делаю много мелких статей/видеороликов. Но так как это не формат хабра - то публикую их на своём канале (телега, вк). На хабре обычно публикую когда рассказ становится уже более самозамкнутым, иногда нужно 2-3 разных мини-рассказа на соседние темы.

Подробнее..

Роботы на карантине

04.08.2020 12:21:41 | Автор: admin
Тут недавно мужики на Хабре рассказывали про Flipper и отладку на осциллографе по видеосвязи.

И это, конечно, победа вне конкурса! Но и у нас был интересный опыт отладки робота, находящегося в 2000 км от нас в лодочном гараже на норвежском побережье. Под катом рассказ о том, как мы делали зрение и правили облачные мозги роботам во время карантина удаленно:



Весной мы сделали прототип всей системы удаленного управления по 3D стриму и обучения роботом на двуруком YuMi и познакомились норвежской компанией, чье решение нам очень кстати для трансляции 3D потока Realsense камер Aivero. Так что после не самого простого рабочего периода планы казались безоблачными: слетать в Италию на месяц зимы с семьей, оттуда поездить по выставкам робототехники в Европе и закончить все остановкой на пару недель в городе с прекрасными фьордами в округе Ставенгер, где и обсудить интеграцию 3D кодеков в нашу систему и попробовать убедить Aivero собрать пару роботов вместе.

Что могло пойти не так в этом замечательном плане

Сидя 2 недели на карантине после возвращения (не без приключений) из итальянского локдауна, пришлось сдуть пыль со своего разговорного и письменного английского и исполнять вторую часть плана уже в Zoom-е, а не в антураже фьордов.

Хотя, тут как взглянуть. Карантин заставил многих всерьез начать работать над возможными способами автоматизацией там, где человека не сложно заменить. Тем более для западных стран, в которых минимальная зарплата выше 1500 Евро, где роботизация простого ручного труда актуальна и без текущей эпидемиологической обстановки.

Подключаем разных роботов


Напомню, мы сделали обучение роботов по записям удаленного управления. Т.е. робот подключается к интернету, к нашему облаку и начинает слать 3D картинки и показания датчиков. Обратно получает команды и исполняет их. В такой логике наша задача научить ML процессор вести себя также, как оператор. 3D нужно, чтобы отрисовать оператору сцену в виртуальной реальности. Это удобно, да и ML становится намного точнее при хватании объектов, когда есть карта глубин.

По задумке, мы можем подключать разнообразных роботов к нашему облаку, но создавать их все разнообразие самим это очень тернистый путь. Мы же фокусируемся на их мозгах, на обучении.
В итоге договорились с Aivero о создании универсального однорукого робота с 3D глазами их силами, назовем его Юнит, а весь облачный Robotics достается делать нам.

В приоритете была простота и цена решения для конечного заказчика. И, конечно, универсальность. Мы хотим минимизировать порог входа для автоматизации простого ручного труда. В идеале, чтобы даже владелец малого бизнеса, не обладающий специальными навыками, мог купить или арендовать наш Юнит, поставить его на рабочем месте и запустить.

Подумали пару недель, потестировали гипотезы пару месяцев и вот, что получилось (версия с Jetson AGX в основании и другой обзорной камерой, чем на заглавной):



И прожектор поближе:



Состав:

  • Jetson NX
  • 2 3D камеры Realsense (одна обзорная, другая для рабочей области)
  • прожектор
  • вакуумный насос, если нужен
  • роборука (Eva / UR / ABB YuMi) с вакуумным или механическим захватом
  • интернет WiFi или проводной



Такая телескопическая стойка с вычислителем и вакуумным насосом в основании ставится рядом с рабочей областью робота, подключается к интернету (например по QR коду к WiFi), и сразу начинает решать поставленную задачу практически без настройки.

Здесь можно сразу оценить и стоимость. Самая доступная роборука Eva 8000 Евро (в России не поставляется), а UR10 уже обойдется почти в 50 000 Евро, но тут нужно отметить, что UR заявляет значительно большую надежность, так что в долгосрочной перспективе может оказаться и не сильно дороже. Да и дешевеют они последнее время. Остальной комплект обходится еще около 2000 Евро.

ABB YuMi IRB 14050


Мы раньше имели дело с двуруким YuMi, но здесь попробовали новую версию IRB14050, которая по сути просто одна оторванная рука.


Кратко, чем понравилась:

  • точность и механическое качество исполнения
  • высокая чувствительность к коллизиям и демпферы на суставах

и не понравилось:

  • тяжело удаленно разрешать коллизии и нештатные ситуации
  • малый угловой ход некоторых суставов делает траектории довольно сложными для, казалось бы, простых движений, которые для кинематики других 6-ти координатных рук не представляют сложности
  • малая грузоподъемность в сравнении с аналогами
  • дополнительно требует заливать (а порою и отлаживать) программу на своем языке программирования от ABB, которая обрабатывает команды по TCP от компьютера

И не кратко.

Здесь мы потратили больше всего времени. Рецепт, как запускать, совсем не простой:

  1. Возьмите машину с Windows, т.к. иначе не получится установить RobotStudio от ABB.
  2. Идем в репу https://github.com/BerkeleyAutomation/yumipy и добываем там RAPID (это язык программирования от ABB) файл для загрузки в робота (у нас одна рука, так что левая или правая подойдут одинаковые), заодно переделываем python API для однорукого YuMi IRB 14050 вместо двурукого IRB 14000.
  3. Если хотим планирование траектории, то находим IRB14000 urdf файл описания геометрии робота и его кинематики для ROS moveit. Удаляем одну руку и корпус робота IRB14000, так и получаем IRB14050.
  4. Забираем из планировщика ROS moveit нужную траекторию и с помощью слегка модифицированного Python API запускаем.
  5. В случае коллизии или иных происшествий запускаем FlexPendant for OmniCore, сбрасываем состояние и визуально разрешаем проблему.

Но, конечно, это лишь возможная траектория того, как можно заставить YuMi повиноваться, да и всех мелочей, где можно споткнуться, тут не упомянуть, конечно.

Eva




Кратко, чем понравилось:

  • Конечно, цена
  • API простое и лаконичное

И минусы:

  • нет детекции коллизий (заявлено в релизе осенью)
  • точность позиционирования над ней еще нужно поработать производителю, но нам хватает

Конечно, простота управления подкупает:

pip install evasdk 

и

import evasdkeva = evasdk.Eva(host_ip, token)with eva.lock():    eva.control_wait_for_ready()    eva.control_go_to([0, 0, 0, 0, 0, 0])

И роборука вжух! и исполняет.

Нет, конечно, потом мы смогли переполнить логи в контроллере руки, после чего она переставала слушаться. Но надо отдать должное производителю создание issue в их гите хватило, чтобы они разобрались в причинах (и привело к паре созвонов с целым консилиумом о наших проблемах).

И в целом, Automata (производитель Eva) большие молодцы! Надеюсь у них получится расти и развиваться на рынке робототехники и дальше, делая роботов сильно доступнее и проще, чем они есть сейчас.

UR



Понравилось:

  • отлично сделана по механике и высокая точность
  • большие диапазоны углов в суставах, что делает планировку траектории заметно проще
  • коллизии можно разрешить в VNC Viewer, подключившись к компьютеру роборуки
  • хорошо отлажена в инфраструктуре ROS

Минусы:

  • устаревшая ОС на контроллере UR, где-то уже полтора года нет никаких обновлений безопасности
  • все-таки не самый современный способ коммуникации, хотя он неплохо прикрыт доступными открытыми библиотеками

Из питона роборука доступна в двух основных сценариях:

  1. Установить https://github.com/SintefManufacturing/python-urx и наслаждаться. Немного длиньше листинг, чем в случае evasdk, так что не буду приводить. Также есть известные проблемы совместимости с новыми роборуками, судя по issue-трекеру. Кое что пришлось так же поправить под себя, т.к. не все режимы перемещения были имплементированы в библиотеке, но это тонкости.
  2. Пойти по особому ROS-до (https://github.com/ros-industrial/universal_robot). Для тех, кто в ROS как рыба, тут все просто: немного магии с загрузкой некого скрипта в тушку UR и вы можете использоваться moveit (очень полезный кусок ROS, который позволяет, например, планировать траекторию в условиях наличия препятствий).

Мы стараемся избегать ROS, т.к. частично его функции (брокер сообщений) выполняет rabbitmq в нашей системе, да и происходит серьезное усложнение стека используемых технологий. Так что для случая, когда нужно объезжать препятствия, мы инскапсулируем ROS в микросвервис на серверной стороне.

А теперь трюк!

Чтобы вы понимали, UR это:



Т.е. любой чих разрешается на тач-панели робота. И чтобы не 5 раз на дню мучать нашего коллегу из Aivero, гоняя в лодочный гараж, нужно как-то влезть туда удаленно.

Оказалось, что на UR контроллере установлен linux (и кстати не самый слабый x86 процессор).
Набираем ssh IP user: root, password: easybot.

И вы в Debian Wheezy.

Так что берем и ставим VNC server и обнаруживаем себя полным хозяином робота! (Тут надо только заметить, что Wheezy уже 2 года как не обновляется и просто взять и поставить vnc сервер у вас не получится из-за устаревших регистров. Но тут есть ссылка на magic file, который позволяет это сделать).

Кстати, в Universal Robots, когда мы им показали наше демо, сказали, что подобное удаленное управление требует новой процедуры сертификации безопасности. Справедливо. Очень любопытно, как в Smart Robotics с этим обстоят дела в целом. Не могу представить, чтобы переменные целеуказания от компьютерного зрения могли бы быть 100% безопасны для окружающих.

Пришло время учить робота хватать коробочки


Напомню, мы же показываем что делать роботу в VR:


Т.е. у нас по каждому перемещению записано, как выглядела сцена и что за команда была, например такая:

{op": "pickup_putdown_box", "pos1": [441.1884, -112.833069, 151.29303],"pos2": [388.1267, 91.0179138, 114.847595],"rot1": [[0.9954941, 0.06585537, -0.06822499], [0.0917332, -0.851038456, 0.517028868], [-0.0240128487, -0.52095747, -0.85324496]],"rot2": [[0.992139041, 0.102700718, -0.07150351], [0.100485876, -0.99436, -0.0339238755], [-0.0745842, 0.026472155, -0.996863365]],"calibration": [[-0.01462146, 0.9814359, -0.191232175, 551.115051], [0.9987302, 0.0051134224, -0.0501191653, -6.613386], [-0.0482108966, -0.191722155, -0.9802644, 771.933167]],"box": [[474.331482, -180.079529, 114.765076], [471.436157, -48.88102, 188.729553], [411.868164, -180.27713, 112.670532], [476.105164, -148.54512, 58.89856]],"source": "operator"}

В общем этого нам достаточно, чтобы обучить сеточки определять bounding box объекта в пространстве и где его хватать.

Так что сидим полчаса и показываем роботу как жонглировать 4-мя типами коробок, получаем около 100 примеров. Нажимаем магическую кнопку ну точнееsudo docker run -e INPUT_S3_FOLDER= OUTPUT_S3_FOLDER= rembrain/train_all_stages:dev. И идем спать. С утра докер отправляет сообщение ML-процессору обновить веса, и мы с замиранием сердца (роботов хоть и дали бесплатно тестировать производители, стоят денег прямо серьезных), запускаем и



Надо сказать, что ни один робот при отладке не пострадал. Я думаю исключительно благодаря невероятному везению.

Однажды мой двухлетний сын подошел и решил поиграться с VR трекером. Залез на стул, взял его с подоконника И отправил UR10 в невообразимое путешествие, отодвинув штангу с камерой и заведя роборуку в довольно хитрое положение. Так что пришлось добавить немного предохранителей в управление. И вторую обзорную камеру, т.к. иначе порою просто не видно куда уехала рука и можно ли ею двигать.

А если без шуток, то точность детекции таких не сложных коробок в наших тестах превышала 99.5% даже при небольшой обучающей выборке из нескольких сотен примеров. Основной источник проблем здесь уже не компьютерное зрение, а сопутствующие сложности: например, какие-то аномалии в исходной укладки объектов, или непредусмотренные помехи в кадре. Но затем мы и делаем обучающуюся систему с операторами в цикле, чтобы быть готовым ко всему, разрешая проблемы, не вовлекая живых людей на месте.

Еще об одном алгоритме, о том, что меня в backend и промахе в UI frontend-е
Проблема плотной упаковки

Иногда bin-picking применения соседствуют с задачей bin-stuffing, ну т.е. разумной упаковкой в корзину. В случае одинаковых объектов это не проблема. Но если мы говорим даже о коробочках разного размера, это реально сложная задача упаковки.

Можно эту задачу решать через планирование, но в нашем случае мы не можем гарантировать, что все легло ровно как мы планируем. Поэтому придется играть в тетрис. Т.е. смотреть что у нас сейчас в корзине, куда все складываем, и думать куда поставить задетектированный объект. Такой жадный подход здесь не самый лучший, но иначе все становится сильно сложнее.

Таким образом, мы переводим трассируем луч по пикселю карты глубин и заполняем воксельный объем корзины. А затем ищем самое лучшее место, где расположить новую коробку (на деле самую нижнюю точку, ближнюю к одному углу корзины). Как-то так:



Иногда получается ерунда, т.к. не под частью коробки просто нет опоры, например как здесь:



Backend

Мы придерживаемся прежней схемы, когда каждому роботу отдали по серверу ретрансляции на websocket-ах, как на этой схеме:



Единственное, сервис Coordinator стал разрастаться в кластер с кучей сервисов внутри. Например, свое место там заняли брокер сообщений Rabbit и mongoDB, сборка логов, как у людей (и это кстати правда удобно в распределенной системе). Так же пришлось добавить активный сервис мониторинга, который активно проверяет целостность всей системы и отвечает о текущем статусе каждого робота.

Но и в целом, конечно, работы по backend-у так много, что позаниматься ML частью системы уже за счастье.

И вот у нас слишком сложный UI

Смиритесь. Если вы разработчик и думаете, что вы сделали UI уже для человеков, то нет. Сходите к человеку и попросите его этим воспользоваться.

Мы привыкли к AWS console, Yandex console, начинает казаться, что и для управления роботами нужно вот именно это, разве что для телефона, а не на десктопе. Не так то и удобно монтировать робота и бегать к компьютеру или ноутбуку.

Казалось, что получилось невероятно круто и понятно.

Вот консоль с роботами, где прямо все про него -> можно зайти в стрим и командовать им -> а если хочется озадачить, то идем в задания, делаем задание, выбирая один из темплейтов -> и даже здесь надо просто обвести пальцем и определить область откуда брать предметы, и куда класть.



Однако, нет потока. Тесты показали, что все несколько контринтуитивно и UX нужно менять. Вот он новый интересный опыт преодолеем и это. А пока что назовем текущий UI robot Console и оставим его для себя.

Что дальше


Снимаем видео монтажа и настройки робота за 2 минуты, готовим материалы для продвижения на нескольких типах задач.

Параллельно ищем новые практические применения помимо понятного и популярного bin-picking (лично я мечтаю о применении роботов на стройке).

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

Так что карантин пошел на пользу!
Подробнее..

Тихая революция и новый дикий запад в ComputerVision

21.04.2021 02:17:19 | Автор: admin

Казалось бы, революция с Computer Vision уже была. В 2012 году выстрелили алгоритмы основанные на сверточных нейронных сетях. Года с 2014 они дошли до продакшна, а года с 2016 заполонили все. Но, в конце 2020 года прошел новый виток. На этот раз не за 4 года, а за один. поговорим о Трансформерах в ComputerVision. В статье будет обзор новинок, которые появились в последний год. Если кому-то удобнее, то статья доступна в виде видео на youtube.

Трансформеры - это такой тип нейронных сетей, созданных в 2017 году. Изначально, они использовались для переводов:

Но, как оказалось, работали просто как универсальная модель языка. И пошло-поехало. Собственно, известная GPT-3 - порождение трансформеров.

А что с ComputerVision?
А вот тут все интересненько. Не сказать, что трансформеры хорошо подходят для таких задач. Все-таки временные ряды, да к тому же одномерные. Но уж больно хорошо работают в других задачах. В своем рассказе я пройдусь по наиболее ключевым работам, интересным местам их приложения. Постараюсь рассказать про разные варианты как трансформеры смогли запихать в CV.

DETR

На дворе 2020. Поперло. С чего? Тут сложно сказать. Но мне кажется, надо начать с DETR (End-to-End Object Detection with Transformers), который вышел в мае 2020 года. Тут Трансформеры применяются не к изображению, а к фичам выделенным сверточной сетью:

В таком подходе нет особой новизны, ReInspect в 2015 делал что-то похожее, подавая выход BackBone сети на вход рекуррентной нейронной сети. Но на сколько рекуррентная сеть хуже чем Трансформер - настолько же ReInspect проигрывал Detr. Точность и удобство обучения для трансформеров выросло в разы.

Конечно, есть пара забавных штук, которых до DETR никто не делал (например как реализуется позиционное кодирование, которое необходимо для трансформера). Я описал свои впечатления тут.
Могу лишь добавить, что DETR открыл путь к возможности использования трансформеров для ComputerVision.Использовали ли его на практике? Работает ли он сейчас? Не думаю:

  1. Основная его проблема - сложность обучение, большое время обучения. Частично эту проблему решил Deformable DETR.

  2. DETR не универсальный. Есть задачи где работают лучше другие подходы. Например тот же iterdet. Но в каких-то задачах лидерство держит до сих пор (или его производные - https://paperswithcode.com/sota/panoptic-segmentation-on-coco-panoptic ).

Сразу после DETR вышел Visual Transformer (статья + неплохой обзор) для классификации. Тут трансформеры тоже берут выходной Feature map с стандартного backbone:

Я бы не назвал Visual Transformer большим шагом, но это характерная для тех времен мысль. Попробовать применить трансформер к тем или иным выделенным через backbone фичам.

VIT

Поехали дальше. Следующий большой шаг это ViT:

Он был опубликован в начале декабря 2020 года (реализация). И тут все уже по-взрослому. Трансформер как он есть. Картинка разбивается на мини-участки 16*16. Каждый участок подается в трансформер как слово, дополняясь позиционным энкодером.

И, внезапно, это все заработало. Не считая того что училось все долго (и точность не state-of-art). И на базах меньше 14 миллионов изображений работало как-то не топово.
Но все эти проблемы решил аналог. На этот раз от FaceBook - Deit. Который сильно упрощал обучение и инференс.

На больших датасетах этот подход до сих пор держит первые места почти на всех классификациях - https://paperswithcode.com/paper/going-deeper-with-image-transformers

На практике мы как-то попробовали использовать в одной задаче. Но, с датасетом в ~2-3 тысячи картинок, все это не очень заработало. И классические ResNet были куда стабильнее и лучше.

CLIP

Пойдем дальше. CLIP. Это очень интересное применение трансформеров совсем с другой стороны. В CLIP задача переформулирована. Задача не в том чтобы распознать изображение, а найти максимально близкое текстовое описание для изображения. Здесь трансформер учит лингвистическую часть эмбединга, а сверточная сеть - визуальные эмбединги:

Такая штука учиться очень долго, зато получается универсальной. Он не деградирует при смене датасета. Сеть способна распознавать вещи которые видела совсем в другом виде:

Иногда это работает даже слишком круто:

Но, не смотря на то что это хорошо работает на некоторых датасетах - это не универсальный подход:

Тут сравнение с линейным приближением ResNet50. Но надо понимать, что по части датасетов работает сильно хуже чем моделька обученная по 100 картинкам.

Мы пробовали из интереса протестировать на нескольких задачах, например распознавание действий/одежды. И везде CLIP работает очень плохо. Вообще про CLIP можно рассказывать очень долго. На Хабре есть хорошая статья. А я делал видео, где говорил про него:

Vision Transformers for Dense Prediction

Следующая сетка, которая, на мой взгляд показательна - Vision Transformers for Dense Prediction, которая вышла месяц назад. В ней можно переключаться между подходами Vit/Detr. Можно для первого уровня использовать свертки, а можно трансформеры.

При этом сетка используется не для детекции/классификации, а для сегментации/оценки глубины. Что дает State-of-art результат сразу по нескольким категориям, при этом в RealTime. Вообще очень печально что @AlexeyAB (автор Yolov4 и один из авторов статьи), не бахнул сюда публикацию отдельную про него. В целом сетка приятная, запускается из коробки, но пока нигде не пробовал. Если кому-то интересно, я делал более подробный обзор тут:

---------------------------------------

В этом месте нужно немного переходнуть. Все что было выше - это самые яркие примеры основных подходов использования трансформеров:

  • Трансформеры используются для обработки выхода сверточной сети

  • Трансформеры используются для нахождения логики поверх выдачи сети

  • Трансформеры используются напрямую применяясь к изображению

  • Гибрид подходов 1-2

Все что будет ниже - примеры того как те же самые трансформеры/подходы используются для других задач. Поехали.

PoseFormer

Pose3D. Трансформер можно применить и к явным фичам, выделенным уже готовой сетью, например к скелетам:

В этой работе Трансформер используется для восстановления 3д модели человека по серии кадров. В CherryLabs мы делали такое (и более сложные реконструкции) ещё года 3 назад, только без трансформеров, с эмбедингами. Но, конечно, Трансформеры позволяют сделать это быстрее и стабильнее. Результат - вполне неплохое и стабильное 3D, без переобучения:

Плюс трансформеров в данном случае - возможность работать с данными которые не обладают локальной корреляцией. В отличие от нейронных сетей (в особенности сверточных). Это позволяет Трансформеру обучаться на сложные и разнообразные примеры.

Если что, идея пришла одновременно много кому. Вот ещё один подход/реализация той же идеи.

TransPose

Если посмотреть где сверточных сетей не хватает именно потому что присутствует вложенная внутренняя логика изображения, то сразу приходит на ум именно поза. TransPose - сетка которая распознает позу оптимизируя свертки:

Сравните с классическими подходами в распознавании позы (достаточно старая версия OpenPose)

И таких стейджей было в разных работах до десятка. Сейчас они заменены одним трансформером. Получается, конечно, сильно лучше чем у современных сетей:

SWIN

Выше мы уже упоминали одну сетку по сегментации на базе Трансформеров от Intel. SWIN от Microsoft показывает результаты лучше, но уже не в RealTime.По сути это улучшенный и расширенный VIT/Deit, переработанный под сегментацию:

Это сказывается на скорости, зато внушительное качество, лидерство в множестве категорий - https://paperswithcode.com/paper/swin-transformer-hierarchical-vision

LOFTR

Есть задачи в которых сверточные сети вообще не очень работают. Например задача сопоставления двух изображений. Года полтора назад для такого зачастую использовали классический пайплайн через SIFT/SURF+RANSAK ( хороший гайд на эту тему + видео которое я записывал год назад ). Год назад появился SuperGlue- единственное крутое применение Graph Neural Network которые я видел в ComputerVision. При этом SuperGlue решал только задачу сопоставления. А теперь есть решение на трансформерах, LOFTR практически End-To-End:

Сам я попользоваться не успел, но выглядит круто:

Распознавание действий

В целом, конечно, трансформеры хороши всюду где есть последовательности, сложная логическая структура или требуется их анализ. Уже есть несколько сетей где действия анализируются трансформерами: (Video Transformer Network, ActionBert). Обещают в ближайшее время добавить в MMAction.

Трекинг

Я уже писал год назад огромную статью на Хабре что работает в трекинге и как трекать объекты. Множество подходов, сложная логика. Прошел всего год, и по многим бенчмаркам есть безусловный лидер - STARK:

Конечно, он не решает всех кейсов. И не во всех кейсах побеждают трансформеры. Но, скорее всего, это не надолго. Вот, например, трекинг глаз на трансформерах. Вот трекинг по типу сиамских сетей пару недельной давности. Вот трекинг BBOX + фичи один, а вот другой, с почти одинаковыми названиями

TransTrackTransTrackTransTTransT

И все имеют неплохие скоры.

ReID

Реиндентификацию можно вынести из трекинга, как вы помните. 20 дней назад вышел трансформер с распознаванием ReID- весьма неплохо может бустануть трекинг.

Распознавания лиц через трансформеры недельной давности похоже тоже подошло:

Медицина

Если смотреть более конкретные применения тут тоже много интересного. VIT уже вовсю запихивают для анализа КТ и МРТ (1,2):

И для сегментации (1,2):

Удивительное

Что меня удивляет - я не вижу хорошей реализации OCR на трансформерах. Есть несколько примеров, но по бенчмаркам они как-то на дне:

Все state-of-art пока на классических подходах. Но люди пробуют. Даже сам что-то года 2 назад пробовал прикрутить. Но что-то результата это не дает.

Ещё из интересного

Никогда бы не подумал, но трансформеры уже применили для раскраски картинок. И, наверное, это правильно:

Что дальше

Мне кажется что трансформеры должны выйти в топ почти по всем категориям для ComputerVision. И, безусловно, для любой аналитики видео.

Трансформеры едят входные данные линейно. Разными хитрыми способами в них сохраняют пространственную информацию. Но кажется, что рано или позно кто-нибудь придумает более актуальную реализацию, возможно где трансформер и 2д свертка будут объединены. И, люди уже пытаются -

Ну а пока, смотрим на то как изменяется мир. Буквально каждый день. Когда материала накапливается достаточно - я обычно выкладываю большую статью на хабр. А про отдельные статьи/идеи обычно рассказываю у себя в канале - https://t.me/CVML_team (дублирую сюда https://vk.com/cvml_team ).

А текущая статья, если кому удобнее, доступна на youtube:

Подробнее..

Самая сложная задача в Computer Vision

15.06.2020 12:08:41 | Автор: admin
Среди всего многообразия задач Computer Vision есть одна, которая стоит особняком. К ней обычно стараются лишний раз не притрагиваться. И, если не дай бог работает, не ворошить.
У неё нет общего решения. Практически для каждого применения существующие алгоритмы надо тюнинговать, переобучать, или судорожно копаться в куче матриц и дебрях логики.

Статья о том как делать трекинг. Где он используется, какие есть разновидности. Как сделать стабильное решение.

Что можно трекать


Трекингом называют задачу сопровождения объектов. От детекции задача отличается тем что нам не только надо задетиктировать объект в первом кадре, но и понять где он находится в следующем.

Что можно трекать?

  • Людей
  • Животных
  • Машины и прочую технику

Конечно, можно трекать что угодно (точки на пальцах, или на лице), но 99% задач из перечисленных категорий.

Разберем в каких задачах это используется на практике для каждой категории.

Люди


Трекинг людей нужен чаще всего.
Самая стандартная задача на которой больше всего решений трекинг людей на улице. Для этого даже большой челлендж есть (даже не один):



Где применяется трекинг на улице/в толпе? Всякие системы безопасности/защиты периметра. Иногда чтобы отслеживать кого-то.

Не сказать что существует готовое общее решение работающее всегда. Почему? В такой толпе даже человек неправильно всё разметит:



Другая задача, на мой взгляд самая востребованная, и не такая маргинальная подсчёт числа посетителей торговых точек, аналитика по торговому залу. Короче статистика для бизнеса. На хабре было несколько статей на эту тему, например эта. Сюда же можно отнести задачи плана подсчёт входящих/выходящих людей в транспорте.



Примерно те же подходы используются при трекинге на предприятиях. Это очень важно для детектирования ситуаций плана вход в закрытую зону (пример с Хабра). Но может работать и для задач уровня помыл ли руки перед подходом к разделочному столу. Тут важнее не статистика, а качество решения.



Отдельная задача трекинг в домах. Она достаточно редко встречается, но на мой взгляд сложнее любой из вышеперечисленных из-за сложности установок камер. Яркий пример фирмы которая ей занимается CherryLabs.

Животные


Глобально, трекинг животных в 95% нужен только на фермах. В природе делают скорее детекцию, чтобы посчитать статистику. А на ферме очень полезно знать какая корова не отдоилась и куда она пошла. Как ни странно, но таких фирм очень много. Вот несколько которые решают эти задачи Cows.ai, Cattle-Care. Но, как водиться, таких не мало.

image
(Видео с сайта первых)

Можно трекать овец. Можно свиней.

А можно Рыбок! (картинка от google, но есть много разных фирм, например Aquabyte)

image

Машины и прочая техника


Машины и прочие самолёты обычно трекать очень просто. Они ездят по практически идеальным траекториям, что сильно упрощает работу алгоритма. Прочую технику зачастую трекают военные, и это редко встречается на практике.

А машины трекать нужно и в системах умного города, и в системах выписывания штрафов, и в всяких системах сопровождения гонок.



Как можно трекать


Есть несколько базовых алгоритмов, которые будут лежать в основе любого построения трека, и бесчисленное число комбинаций между ними:

  • Детекция объектов в кадре. Не важно что тут используется. Главное чтобы детекция выдавала положение объекта. Это может быть YOLO, SSD, или любой из десятков более новых алгоритмов.
  • Алгоритм распознавания объекта в кадре. Так называемая задача ReIndentification. Это может быть:

    1. Распознавание человека по телу
    2. Распознавание человека по лицу
    3. Распознавание типа автомобиля
    4. и.т.д, и.т.п.

  • Алгоритмы сопоставления объектов по физическим параметрам. Это может быть сопоставление по IoU(пересечение выделенного прямоугольника), сопоставление по скелету (насколько они похожи), сопоставление по положению на полу/на земле/на дороге. и.т.д.
  • Алгоритм межкадрового трекинга. Эта часть самая загадочная.
  • Сюда входит много алгоритмов оптического трекинга, оптического потока, и.т.д

Когда человек решает задачу трекинга, то он использует все перечисленные алгоритмы. Какие-то подсознательно, какие-то сознательно.

Но для любого алгоритмиста это ад и кошмар. Как найти взаимоотношения между алгоритмами, как понять что происходит, как всё это собрать.

Сейчас эти взаимосвязи пытаются обучать, или закладывать напрямую в алгоритм. Но всё слишком нестабильно. Классикой является алгоритм трекинга, который завязывает наборы детекций и матриц перехода в трек с учётом пропусков и появлением новых объектов. Обычно это различные фильтры Калмана, или нейронки.

Что важно отметить при переходе к алгоритмам трекинга


95% качества при трекенге, как впрочем и у любой задачи ComputerVision установка камеры.
Сравните:




Где проще посчитать людей?

Но помните, установка камеры сверху зачастую усложняет создание системы. Ни Yolo ни SSD, ни стандартные ReID алгоритмы не будут работать по таким объектам. Потребуется полномасштабное переобучение (ниже приведу пример).

Детекция объектов в кадре


Про детекцию есть много постов на Хабре. Есть сети которые показывают более высокое качество. Есть сети которые показывают более высокую скорость. Зачастую скорость может быть завязана на железо. На одной железке быстро на второй медленно.

Если вы не разбираетесь что вам надо, то на июнь 2020 хорошим вариантом является YOLOv4, обеспечивающая баланс качества/производительности. Для максимальной скорости можно посмотреть в сторону YOLOv3- tiny или в сторону быстрых версий EfficientDet.

(Ещё мутный YOLOv5 появился за время написания статьи, но там какая-то хрень).

Но в ряде случаев эти решения могут не быть оптимальными.

Ниже мы будем рассматривать ряд решений где детектор объединен с другими алгоритмами, там, зачастую, будут использованы предопределенные сети, которые сложно будет перенести

Для трекинга детекция это основа. Какие бы крутые у вас не были следующие алгоритмы без детекции трекинг не будет работать.

Прямым следствием является то, что детектор скорее всего придётся преобучать по вашему датасету.

Обычно детекторы учатся на каких-нибудь универсальных датасетах (например Microsoft COCO):

image

Там мало людей которые плохо видны, скорее всего нет камеры похожей на вашу (ИК, широкий угол). Нет ваших условий освещения, и многое другое.

Переобучение детектора по датасету из используемых условий может уменьшить число ошибок в 2-3 раза. Лично я видел примеры где и в 10-20 уменьшало (процентов с 60-70 точности до 98-99).

Отдельным моментом стоит отметить что в ситуациях когда люди/животные/машины в нестандартных ракурсах переобучать придётся всегда. Вот пара примеров как работает непереобученный Yolo v4:





Несколько мест где можно взять готовые нейронки для детекции:


Я не буду подробно заостряться на этой теме, про детекцию безумно много статей.

Person ReIndentification


Предположим вы мельком в толпе увидели эффектную блондинку в красном платье. Выходите из толпы, и внезапно блондинка тоже вышла.



Вы не видели как она вышла из толпы. Вы не видели её последние 30 секунд. Но вы же знаете, что это она.

Тут работает именно алгоритм распознавания по телу.

В ML существуют алгоритмы для создания хэш-кода, который потом можно использовать для определения человека через какое-то время.

Особенно после разрыва трека.

Существует несколько крупных датасетов для обучения таких алгоритмов. Самые известные:

  • Market-1501
  • CUHK03
  • MARS
  • DukeMTMC
  • iLIDS-VID

Большая часть датасетов собрана каким-то таким образом:

image

Ставится несколько камер, и отмечаются одни и те же люди которые проходят между ними. Некоторые датасеты собирают с одной и той же камеры.

Есть множество способов обучить такие нейронки, если вам это интересно, то вот тут есть хорошая подборка с исходниками.

В качестве примера я приведу старый способ, который был популярен года 4 назад, и очень простой. Сейчас пользуются его вариациями (на картинке именно такой пример).

image

У нейронной сети создаётся бутылочное горлышко, из небольшого числа нейронов. А на выходе нейронной сети будет число нейронов по числу людей в датасете. Сеть научится распознавать людей, но параллельно научится описывать их в качестве небольшого вектора.

Так просто никто уже не делает. При обучении последних версий ReID используется и hard negative mining, и различные хитрые аугментации и трюки с подрезанием, и фокальные потери, и многое-много другое.

Всё бы хорошо, но у ReID алгоритмов есть слишком много проблем. Даже по датасетам которые идеально под них заточены (улица, одинаковые условия освещения, почти одинаковое время съемки, отсутствие пёстрого фона, нет больших пересечений людей, нет заслонений объектами переднего фона, человек целиком в кадре, и.т.д., и.т.п.), даже у самых последних моделей точность будет на уровне 95-98%

На практике такие сети очень сложно использовать: Предположим у вас завод где все ходят в одинаковой униформе

Так что данный класс сетей надо использовать в очень ограниченных задачах, или при очень аккуратном контроле, иначе он не привнесёт точности в ваш алгоритм.

Ниже мы рассмотрим как алгоритмы ReID используются в сетях трекинга и иногда ощутимо повышают результат.

ReID по одежде


Одна из вариаций ReID распознавание по одежде:

  1. Пример сорсов
  2. Пример алгоритма
  3. Пример алгоритма

По сути тот же вектор что и выше, только который можно контролировать глазом. По опыту работает хуже обычного ReID, но в некоторых ситуациях может давать более стабильную работу.



Например, если у вас люди носят три типа формы можете обучить по ним!

ReID по лицу


Отдельно стоит упомянуть про возможность трекинга по лицу. Если с вашей камеры видно лицо, да ещё и в разумном качестве бинго! Вы можете сделать хорошую систему трекинга.

Про распознавание по лицам можно почитать например тут 1, 2.

По практике скажу только одно. Не видел ни одной системы трекинга где лица были бы видны всегда и хорошо. Скорее это был один из дополнительных факторов, который изредка помогал что-то пофиксить, либо давал привязку трека к человеку.

Про точность распознавания лиц и их применимость я писал длинную статью.

Пусть будет ещё картиночка про олдфажеский TripletLoss для обучения лиц, который уже не используется:



ReID не на людях


Алгоритм реиндентификации очень удобен для трекинга. Хотите посмотреть где он работает на животных? Например тут:


Для некоторых рыб можно вообще обучить аналог лицевого ReID, с достаточно высокой точностью. Вот тут рассказано подробнее 1, 2

Очень хорошо ReID работает на коровах. Каждая корова по шкуре уникальна: 1, 2

И, как я слышал, ReID не очень работает на животных где окрас одинаков, например овцы или свиньи.

Прочие ReID


Какие-то аналоги ReID можно использовать для трекинга автомобилей (например распознавание марки автомобиля). Можно обучить ReID для трекинга людей по головам.

Но так как ReID обычно обучать муторно достаточно редко вижу его использование для трекинга вне случаев описанных выше (не для трекинга применений масса!).

Алгоритмы сопоставления объектов по физическим параметрам


Как мы говорили выше ReID это лишь набор параметров объекта, которые мы выделяем нейронной сетью. Но не стоит забывать, что у ведомого объекта может быть множество параметров, которые сложно выделить нейронной сетью, но просто использовать для трекинга.
Например:

  • Размеры выделенной области (bbox) объекта. Чем более похожи объекты в соседних кадрах по размеру тем с большей вероятностью это один объект.
    image
  • Положение центра масс. Чем ближе центр масс к планируемой траектории тем с большей вероятностью это один и тот же объект.
  • Скорость передвижения объекта в прошлых кадрах. Чем больше скорость и ускорение соответствуют какому-то объекту, тем с большей вероятностью это одно и то же.
  • Координаты проекции на землю. Можно вычислить если знать как висит камера. Для установок камер вертикально сверху совпадает с позапрошлым пунктом. Хорошо работает при трекинге машин.

  • Близость позы. ReID алгоритмы работают в длительном окне времени, не учитывая позу человека, стараясь отвязаться от неё. Но если сэтап имеет достаточно высокую скорость обработки, то наоборот, можно привязывать соседние детекции по позе человека.

    image
  • Наверняка есть что-то что я ещё забыл. Но оно сильно реже на практике.

Оптический трекер


Ну вот мы и пришли. К могучем, огромному, бесполезному оптическому трекингу!

По этой теме фанатеют многие. Смысл этого класса алгоритмов очень простой.

Пусть в первом кадре у нас есть заданное положение объекта. Нужно найти его в следующем.
И не важно какой объект: человек, машина, точка на руке, вертолёт или падающий лист.

Задача достаточно простая и древняя. Для неё существует множество подходов. Начинающихся ещё с OpticalFlow задачи:

image

(найти для каждой точки кадра порождающую её точку с прошлого кадра).

А потом пошло поехало:


И многое, многое другое.

Любой новичок, который хочет решить задачу трекинга с загорающимися глазами подскакивает, и говорит Да, я хочу использовать это!.

Обычно после этого он натыкается на примеры из Эндриана Розеброка:


И использует их в продакшне (видел минимум в двух фирмах)

Но нет Не надо так. Каждый раз когда вы берёте пример с pyimagesearch и несёте его в прод вы делаете грустным ещё одного котика (с).



Эдриан хороший популяризатор. Возможно он даже знает как делать машинное зрение. Но 95% его примеров это пример использования готовой библиотеки. А готовая библиотека почти всегда бесконечно далека от прода.

Разберём что может пойти не так (специально записал!):

  1. Похожие объекты, оптический трекинг не учитывает направление и скорость, он выбирает оптимальный минимум ближе всего:


  2. Неадекватный детектор потери. Например человек входит в дверь. Оптический трекер это не любит:

  3. Неадекватная реакция на сильно изменение формы. Резкий разворот/поворот убивает трекеры:

  4. Перепады яркости

Есть и другие, менее значительные причины, которые тоже могут проявится. Это приводит к нескольким утверждениям:

  1. Если у вас более-менее стабильная детекция оптический трекер нет смысла использовать
  2. Если у вас нет опыта тонкого тюнинга таких алгоритмов то тоже не надо брать такое
  3. Если у вас есть несколько независимых алгоритмов, а их результаты вы планируете склеивать в ручную то лучше не надо использовать оптический трекер. Только при автоматической склейке где какой-то ML алгоритм выберет параметры склейки сам.

Это не значит, что оптический трекер не имеет смысла вообще. Есть небольшой процент ситуаций когда его использование может быть оправданно. Какие? Апологеты этого подхода выделяют два типа ситуаций:

  1. Оптимизация скорости работы. Запускать детектор пореже, а трекинг меньше ест.
  2. Универсальность работы на любом железе.

Но по мне оба аргумента очень сомнительны при современном уровне развития технологий.

Единственное место, наверное, где трекинг имеет смысл вы не можете набрать базу для детекции. Вот пример как можно трекать вот через классические, встроенные в OpenCV алгоритмы (реинициализирую руками после разрыва):

И вот что выдаст обычный YOLOv4 (детекции клею через SORT, про который будет ниже):


Понятно, что YOLO можно дообучить, и всё будет сильно лучше. Но, наверное, когда нет таких сил можно и через трекинг прототип сделать.

А вот что будет оптическим трекером из OpenCV (GOTURN, каждый раз когда разрыв реинициализирую заново):


И да, ниже по тексту мы столкнёмся с алгоритмами которые включают в себя оптический трекер по умолчанию.

Часть 2


Как всё это завязать.

Нагенерили детекций. Возможно нагенерили каких-то метрик близости между ними. Как всё это завязать друг с другом?

Есть много подходов. Проблемы есть почти везде. Начнём с простого.

Классическая математика


Самым классическим и стабильным подходом является модель движения + алгоритм целераспределения. Собственно, все эти алгоритмы целераспределения и родились в 60-70 годах для слежения за целями в воздухе и космосе.

Как ни странно, один из самых классических подходов, где в качестве модели был взят фильтр Калмана, а в качестве целераспределения венгерский алгоритм выстрелил в 2016, взяв первое место в MOT соревновании (SORT). И если по точности он был плюс-минус сравним с другими решениями, то по скорости бил в 20 раз. А по понятности в 100.

Почему этого не произошло раньше? Не знаю. Подход настолько классический и дубовый, что для определения параметров спутников нам его ещё году в 2008 на кафедре МФТИ преподавали. И эта программа, как я понимаю, лет 20-30 не менялась.
Скорее всего так вышло потому, что не было ни одной opensource реализации нормальной. Всё пряталось в глубинах продуктового софта.

В целом, фильтра Калмана достаточно универсален, но местами перебор. В реальных задачах мы очень часто пользовались более простыми моделями, где в качестве модели движения использовали какие-нибудь аппроксимации, либо более простые методы линейной комбинации.
Такие аппроксимации могут быть очень крутым способом насадить детекции на один трек.

На базу такого алгоритма можно насадить любые другие метрики близости. Например близость по позе. Или близость точек между результатами оптического трекинга.

Или в конце концов близость между ReID описаниями. Именно так делает, например DeepSORT.

Сравните качество работы SORT против Deep SORT:



И то и то собрано на базе детекции из Yolov4 которая выглядиттак.

Надо сказать что данный подход до сих пор в топе.

На сегодняшний день самый топовый из трекеров с открытым кодом по MOT конкурсу FairMOT. И, как ни странно, он реализует ту же самую логику, только более хитро обученную.

А вот так будет выглядеть то же самое видео что и выше (правда я запустил не самую мощную сетку, как я понял):


На более мощной чуть лучше детекция работает. Тут явно завалена ближняя часть.

Только вот не везде этот подход будет работать. ReID нестабилен в большом временном окне. ReID не будет работать по одинаковым вещам как машины, или олени. Или, например, работники в униформе.

Мы наталкивались на задачи когда ReID был самой плохой метрикой для людей, из всех перечисленных.

Нейронончки везде


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

image

К этому подходу будет относится и упомянутые уже LSTM сети трекинга:

image

И так же упомянутые сети трекинга скелетов:



image

Казалось бы. Раз можно достичь высокие результаты так и надо делать всегда! Но, как ни странно, нет.

Предположим вы решили обучить трекер по головам. Подошли серьёзно. И LSTM-сеть с пачкой кадров взяли. И ReID добавили, и детектор переобучили.

Только вот есть одна проблема. Обучать по видео это огромные объемы датасетов. Длительная разметка, не понятен профит от обучения относительно того же SORT. Даже FairMot надо переобучать. И куда сложнее переобучать, чем отдельно YOLO.

И самое плохое. Если вы сегодня обучаете по головам, а завтра люди с наклоном (или объектив поменяли) то это разные датасеты. И если для детекции это сделать несложно (у нас сейчас на такую итерацию уходит в среднем 3-4 дня), то собрать датасет треков это огромная задача.

Как в реальности


Мы затронули интересный вопрос. А как всё устроено на практике?. Тут всё интересно. По сути, как мне кажется: на практике всё либо очень сложно, либо очень просто.

Очень сложно когда надо получить какой-то качественно новый результат. Например водить автомобиль. Тогда рождаются вот такие химеры:



Бывает и сложнее. Я почти уверен, что если у любой Tesla или Yandex-машинке разрисовать схему обучения алгоритмов трекинга то там сума сойдёт даже адекватный человек.

По тому что видел лично я:

  • В двух стартапа видел схему с уже упомянутого pyimagesearch. Когда происходила детекция, а для связывания детекций использовался оптический трекер. В одном стартапе работало на гране допустимого качества. Во втором не работало.
  • В одном стартапе разрабатывали детектор + аналог МНК для слежения. Но там трекались точки на человеке. Работало хорошо.
  • Сами участвовали/разрабатывали несколько систем трекинга авто. И везде трекинг был через какого-нибудь Калмана/аналог с МНК. Видел несколько фирм где в целом было так же. Работало у всех хорошо.
  • Видел 3 фирмы где в качестве трекинга использовался SORT. Одной из них разрабатывали процесс обучения детектора, который подавался в SORT. У всех всё было классно, всё работало.
  • Участвовали/до сих пор участвуем в разработке стартапа где трекаются люди в помещениях. Используются почти все техники которые тут упомянуты. Но вес каких-то очень мал. Работает в целом неплохо. Но, конечно, хуже того что человек глазом может.

Что посоветую использовать


Я всегда считаю что простота залог успеха. Мне больше всего нравится SORT. Пока писал статью написал простой пример того как можно SORT использовать, строчек на 20. Вот тут описание того как оно работает.

Это сработает и для трекинга людей, и для машин, и для котиков.


Если вы хотите залезть в ReID то проще всего это будет сделать через DeepSort. Но надо понимать, что ReID это огромный мир, вариантов использования масса. Многие из них напрямую не связаны с трекингом.

Если вам нужно трекать людей очень долго то советую использовать FaceID-сети, и хорошо ставить камер. Без этого вы обречены на мучения.

Вообще, правильно помнить, что без правильного оборудования трекинг это всегда мучение. Хорошая и правильно поставленная камера >> алгоритма трекинга.

Если вы решили трекать что-то сложное или нестандартное, или захотели сильно повысить точность того что у вас есть вам придётся использовать большинство описанных техник!

P.S.


Тема трекинга очень большая. Я наверняка что-то забыл. Что-то, может, неправильно написал. Да и примеров не много. Но это всё можно поправить в комментариях! Особенно последний пункт.
Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru