Всем привет!
Мне в проекте по распознаванию/трекингу объектов на видео понадобилось как-нибудь гибко раскидывать задачи по потокам.
Вкратце опишу последовательный пайплайн:
1. Захват и декодирование с камеры очередного кадра.
2. Распознавание объектов на нём.
3. Трекинг распознанных объектов.
4. Распознавание номеров, если объект — автомобиль.
5. Отображение кадра.
6. Сохранение кадра и результатов распознавания.
Каждая операция может быть как быстрой, так и достаточно медленной. Поясню: видео можно декодировать аппаратно (если железо поддерживает), а можно и нет. Объекты могут распознаваться быстро (если есть мощная нвидиевская видеокарточка), а могут и нет. Трекинг может длиться 1-2 млсек, а может и 20 млсек, если объектов много. Распознавание номеров может вообще ничего не занимать, если автомобилей нет, а может и нормально.
Например, захват, декодирование и распознавание объектов (пункты 1 и 2) должны идти друг за другом. Далее трекинг и распознавание номеров (3 и 4) могут работать параллельно, отображение и сохранение (5 и 6) ждут результатов трекинга (но не распознавания номеров!), чтобы нарисовать траекторию. При этом, пунктам 1 и 2 не обязательно дожидаться завершения 3-6, они могут начинать работать сразу же после своего завершения.
Думаю понятно.
Вот тут хочется одновременно применить два способа распараллеливания.
1. Что-то типа taskflow, где я выделяю последовательные части пайплайна и параллельные, сделать типа графа задач.
2. Сделать в отдельном низкоприоритетном потоке распознавание номеров и очередь сообщений к нему, в которую засылать кусочки изображения для распознавания и выгребать результаты по мере поступления. Этих результатов ждать не надо, распознается секундой раньше или секундой позже — без разницы.
Для параллелизма типа 1 нашёл библиотеки cpp-taskflow (на CppCon2018 о ней рассказывали) и более продвинутый вариант Threading Building Blocks (TBB). Что скажете? Что лучше выбрать? Я так понимаю, Microsoft забили в своём компиляторе на openmp, для кроссплатформенного софта на неё даже смотреть смысла нет.
Для очереди с сообщениями, видимо, надо искать что-то альтернативное и ни в одну из указанных библиотек её не уложить.
Библиотека ищется по возможности простая и для Win|Lin|Mac.
P.S. Сейчас это всё как-то делается вручную, но хочется красиво отрефакторить.
Здравствуйте, Nuzhny, Вы писали:
N>Библиотека ищется по возможности простая и для Win|Lin|Mac.
Посмотрите еще на transwrap (ее анонсы регулярно всплывают на reddit/r/cpp) и на fastflow (она сильно не новая, раньше жила на SourceForge, но вроде как еще шевелится).
PS. А вообще, наш SO-5, наверное, тоже бы с этим справился
Здравствуйте, Nuzhny, Вы писали:
N>Для параллелизма типа 1 нашёл библиотеки cpp-taskflow (на CppCon2018 о ней рассказывали) и более продвинутый вариант Threading Building Blocks (TBB). Что скажете? Что лучше выбрать?
TBB. Либо посмотреть в сторону std::async/std::future/std::packaged_task (либо boost::future — там больше фич).
N>Я так понимаю, Microsoft забили в своём компиляторе на openmp, для кроссплатформенного софта на неё даже смотреть смысла нет.
У них есть аналог TBB — Microsoft PPL, в студии ЕМНИП из коробки.
А что с OpenMP у Microsoft? Он, насколько я помню, был у них вполне рабочий, может нет каких-то новых фич, но тем не менее (хотя для C++ предпочитаю библиотечный решения типа TBB).
N>P.S. Сейчас это всё как-то делается вручную, но хочется красиво отрефакторить.
Если время терпит, можно подождать пока Parallelism TS реализуют в мейнстриме.
Здравствуйте, Nuzhny, Вы писали:
N>Всем привет! N>Мне в проекте по распознаванию/трекингу объектов на видео понадобилось как-нибудь гибко раскидывать задачи по потокам. N>Вкратце опишу последовательный пайплайн:
как забавно, я тоже занимаюсь примерно этим (хобби).
Мне понравился csp подход, когда все общение идет через каналы.
Boost::fibers::buffered/unbuffered channels, как работает — https://youtu.be/Gihdujm6EWU?t=723
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>У них есть аналог TBB — Microsoft PPL, в студии ЕМНИП из коробки. EP>А что с OpenMP у Microsoft? Он, насколько я помню, был у них вполне рабочий, может нет каких-то новых фич, но тем не менее (хотя для C++ предпочитаю библиотечный решения типа TBB).
Здравствуйте, SomeOne_TT, Вы писали:
SO_>как забавно, я тоже занимаюсь примерно этим (хобби).
И у меня хобби.
SO_>Мне понравился csp подход, когда все общение идет через каналы. SO_>Boost::fibers::buffered/unbuffered channels, как работает — https://youtu.be/Gihdujm6EWU?t=723
Boost можно поставить в зависимость, но проект открытый. Боюсь, посыпется куча issue от windows-юзеров. Мне нравится вариант чего-то полегче с гитхаба.
Здравствуйте, Nuzhny, Вы писали:
N>Boost можно поставить в зависимость, но проект открытый.
TBB как зависимость потяжелее будет. Если хочется минимизировать зависимости — то можно свой простой пул/очередь сделать.
N>Мне нравится вариант чего-то полегче с гитхаба.
Здравствуйте, Nuzhny, Вы писали:
N>При этом, пунктам 1 и 2 не обязательно дожидаться завершения 3-6, они могут начинать работать сразу же после своего завершения. N>Думаю понятно.
Пункт 3, трекинг, требует результатов трекинга для предыдущего кадра?
Пункт 4, насколько я понял, может одновременно выполнятся для нескольких кадров — это планируется параллелить?
N>2. Сделать в отдельном низкоприоритетном потоке распознавание номеров и очередь сообщений к нему, в которую засылать кусочки изображения для распознавания и выгребать результаты по мере поступления. Этих результатов ждать не надо, распознается секундой раньше или секундой позже — без разницы.
Что планируется делать в случае медленного распознания и разрастания очереди? отменять старые задачи?
Здравствуйте, Evgeny.Panasyuk, Вы писали:
N>>При этом, пунктам 1 и 2 не обязательно дожидаться завершения 3-6, они могут начинать работать сразу же после своего завершения. EP>Пункт 3, трекинг, требует результатов трекинга для предыдущего кадра?
Да, для построения модели движения каждого объекта. Перемешивать кадры нельзя.
EP>Пункт 4, насколько я понял, может одновременно выполнятся для нескольких кадров — это планируется параллелить?
Планируется. Я думал о создании отдельного потока и накидывания в него кусочков изображений в виде сообщений. Или имеется в виду ещё более мелкое дробление там? Этого не нужно.
EP>Что планируется делать в случае медленного распознания и разрастания очереди? отменять старые задачи?
С этим нам поможет трекинг: если номеров в очереди будет слишком много, то накидывать буду только с тех машин, которые ещё не распознавались, а с уже распознанных отменять. Всё равно лучше по несколько раз распознать для каждой машины, чтобы вероятность повысить.
Здравствуйте, Nuzhny, Вы писали:
N>Что скажете? Что лучше выбрать?
Есть еще HPX. https://github.com/STEllAR-GROUP/hpx
Сам еще особо не смотрел, но вроде выглядит многообещающе.
Здравствуйте, Nuzhny, Вы писали:
N>Библиотека ищется по возможности простая и для Win|Lin|Mac.
Почитал документацию для недавно зарелизенной OpenCV 4.0, они там делают что-то похожее: G-API (там простой пример есть).
То есть задают граф из операций и выставляют их зависимость друг относительно друга, а потом запускают его на выполнение. Подход витал в воздухе уже давно.
Здравствуйте, Nuzhny, Вы писали:
N>Всем привет! N>Мне в проекте по распознаванию/трекингу объектов на видео понадобилось как-нибудь гибко раскидывать задачи по потокам. N>Вкратце опишу последовательный пайплайн: N>1. Захват и декодирование с камеры очередного кадра. N>2. Распознавание объектов на нём. N>3. Трекинг распознанных объектов. N>4. Распознавание номеров, если объект — автомобиль.
Блин, а колорадских жуков никто не собирается распознавать?
-- Пользователи не приняли программу. Всех пришлось уничтожить. --