320 likes | 543 Views
Разработка параллельной реализации трекинга объектов с использованием библиотеки Intel Array Building Blocks. Список участников Кайнов Олег Ларцов Иван Ханова Татьяна Руководитель Кустикова Валентина. Содержание. Терминология Постановка задачи Схема решения задачи
E N D
Разработка параллельной реализации трекинга объектов с использованием библиотеки Intel ArrayBuildingBlocks Список участников Кайнов Олег Ларцов Иван Ханова Татьяна Руководитель Кустикова Валентина
Содержание • Терминология • Постановка задачи • Схема решения задачи • Описание последовательной реализации • Схема распараллеливания этапов алгоритма • Описание параллельной реализации • Скорость работы при вызове call и обычном вызове • Результаты экспериментов • Сравнение последовательной и параллельной реализации
Постановка задачи Цель: • Оценить эффективность применения IntelArray Building Blocks для трекинга объектов. Задачи: • Реализовать схему двумерного сопровождения объектов с использованием библиотеки OpenCV. • Разработать параллельную версию алгоритма, используя библиотеку IntelArray Building Blocks. • Оценить время работы параллельной версии.
Схема решения задачи Построение модели фона на основе имеющегося буфера кадров Преобразование кадров видео в оттенки серого Для каждого следующего кадра видео: Преобразование кадра видео в оттенки серого Вычитание фона из текущего кадра Бинаризация изображения Обновление модели фона
Преобразование кадра в оттенки серого • Переводим трехканальное изображение в одноканальное по формуле c некоторымикоэффициентами. • где • - соответсвующие каналы изображения, • - весовые коэффициенты каналов.
Построение модели фона • На основе массива одноканальных изображений строим первую модель фона. • - первый кадр фона. • - k-й кадр видео.
Построение бинаризованного изображения • Вычитаем фон из очередного кадра. • Отсекаем пиксели со значением больше порогового.
Морфология • Избавление бинаризованного изображения от шумов с помощью эрозии.
Обновление модели фона • Для каждого кадра видео обновляем модель фона по формуле. То есть,сложим текущие кадры фона с весовыми коэффициентами.
Описание последовательной реализации • Чтобы начать обрабатывать потоковое видео, нужно создать кадр фона по первым n кадрам исходного видео. • Каждый кадр, который будет использоваться в построении модели фона, нужно будет конвертировать в черно-белый кадр. • Для создания кадра фона будем использовать модель фона с использованием усреднения. - i-й пиксель фона. - i-й пиксель j-ого кадра.
Описание последовательной реализации • Конвертирование кадра в черно-белый кадр void ConvertToGrayscale(IplImage* grayFrame, const IplImage* image,const double r,const double g,const double b); • Создание кадра фона с использованием усреднения IplImage* BGModelAve(IplImage** src, const int n); frame b g r b g r b g r … bg p p p p p p p p p … p p p p p p p p p … p p p p p p p p p … p p p p p p p p p … p p p p p p p p p …
Описание последовательной реализации • После создания первоначального кадра фона для каждого последующего кадра видео будем выполнять последовательность действий. • Конвертировать в черно-белый кадр. • Найти различия между полученным кадром и текущим кадром фона. • К полученному кадру разницы применить сглаживающий фильтр. • Проклассифицировать множество пикселей на фоновые и не фоновые – бинаризовать изображение. • Отобразить полученный кадр. • Обновить кадр фона.
Описание последовательной реализации • Вычисление разности фона и текущего кадра void Diff(const IplImage* bg, const IplImage* frame, unsigned char* const diff); • Получение бинаризованной маски void ClipPix(IplImage* mask,unsigned char* const diff, const char t); background b b b b b b b b b … - frame f f f f f f f f f … = diff d d d d d d d d d … tresh
Описание последовательной реализации • Для уменьшения количества «случайных» белых пикселей – шума – применим метод математической морфологии сужение. void Erosion(IplImage* src, IplImage* out, bool* mask, int maskWidth, int maskHeigth); Маска – двумерный массив (матрица) интенсивностей пикселей. Рассмотрим пиксель .. Шаблон – двумерный булев массив.
Описание последовательной реализации ? да нет Таким образом обрабатываем все пиксели маски.
Описание последовательной реализации • Основываясь на методе поиска границ Канни рисует границы маски на исходном кадре. void CannyTrack(IplImage * src, IplImage * mask, const double lowThresh, const double highThresh,unsigned char track_r, unsigned char track_g, unsigned char track_b); • В данном методе используется OpenCV-функция voidcvCanny(const CvArr* image, CvArr* edges, double threshold1,double threshold2, int aperture_size); • Данная функция «обводит» сегменты из определенного заданного порога интенсивности пикселей. • Затем нужно перенести полученные границы на исходный кадр, отобразив их соответствующим цветом.
Описание последовательной реализации • После того как кадр с отрисованными границами отображен, нужно пересчитать кадр фона. • Для этого создадим циклический буфер, который будет состоять из n предыдущих кадров фона. • Чтобы получить новый кадр фона, вставим на место самого старого фона текущий и пересчитаем фон. IplImage* UpdateBGModel(IplImage* grayFrame, IplImage** src, const int n, const unsigned int OldFramePosition, double* const w) Начало буфера
Схема распараллеливания алгоритма • Во многих функциях производилось одно и тоже действие над каждым пикселем кадра • Данные функции могут быть хорошо распараллелены, если массив интенсивностей мы представим как тип dense<u8> И будем применять к нему метод map(). • Изначально имеем IplImageкоторая имеет поле ImageData, которое является массивом интенсивности. • Используем биндинг: dense<u8>img_arbb; IplImage* img = cvCreateImage(img_size,DEPTH,CHANNELS); bind(img_arbb,(uchar*)img->imageData,img_size);
Схема распараллеливания алгоритма • Конвертирование в черно-белое изображение void ConvertToGrayscale(IplImage* grayFrame, const IplImage* image,const double r,const double g, const double b) • Для каждого элемента полученного dense-контейнера можно сделать следующее: умножить на соответствующий коэффициент его и его соседей, а потом сложить. Каждый третий такой пиксель в массиве (так как трехканальное изображение) и будет пикселем черно-белого кадра. Ядро: void Conv(arbb::f32 &a) { a=neighbor(a,1)*r+a*g+neighbor(a,-1)*b; } Правый сосед Левый сосед Текущий b g r b g r b g r b g r p p p p p p p p p p
Схема распараллеливания алгоритма • Вычисление разности фона и текущего кадра void difference(const dense<i8> &a, const dense<i8> &b, dense<u8> &c) • В данной функции вызывается ядро map(): void diff(i8 a, i8 b, u8 &c) • Получение бинаризованной маски void ClipPix(const dense<i8> &a, dense<i8> &b, const u8 t) • Ядро map(): void Clip(const i8 &a, i8 &b, const u8 t)
Схема распараллеливания алгоритма • Для обновления фона мы сохраняем предыдущие n кадров фона и текущий кадр в циклическом буфере: dense<u8> mainFramesBuffer_arbb • Он содержит (n+1)·ImgHeight·ImgWidthэлементов u8. • Также есть массив коэффициентов: dense<u32> coefficients • В исходной формуле … … bn f b1 b2 … … … ImgSize = ImgHeight·ImgWidth
Схема распараллеливания алгоритма • Рассмотрим реализацию обновления фона • Для каждого i-го пикселя фона: • Сформировать вектор из i-х пикселей кадров из циклического буфера. • Умножить полученный вектор на вектор коэффициентов. * w w w w w w w w w =
Схема распараллеливания алгоритма • Теперь нужно просуммировать все координаты ветора, чтобы получить i-й пиксель фона. • Так как буфер циклический, циклически подвинуть массив коэффициентов вправо на один элемент. dense<u8> UpdateBGModel(dense<u8> &mainFramesBuffer, dense<u32> &coefficients, const int width, const int height, const int n) = w w w w w w w w w
Схема распараллеливания алгоритма • Создание кадра фона с использованием усреднения dense<i8> Average(const dense<i8> &src, int n, int size) • Данная функция аналогична функции обновления фона, за исключением того, что все коэффициенты равны 1/n
Обзор ArBB • ArBBпредоставляет два типа параллелизма: параллелизм по данным и параллелизм по потокам. • ArBB использует собственный тип для хранения однотипных массивов данных: dense-контейнеры. • Есть две специальных ArBB-функции, обеспечивающие работу со скалярными и векторными ArBB-типами: map и call. • Функция map обеспечивает векторизацию, или параллелизм по данным, которая вызывается поэлементно для каждого из элементов контейнера. • Call, по сути, является аналогом обычного вызова функции в С.
Описание параллельной реализации • При первом вызове функции происходит компиляция кода этой функции в реальном времени с учетом особенностей текущего процессора (SSE, AVX) • Все функции, использующие контейнеры и\или переменные ArBB, должны вызываться с помощью call • Когда функция вызывается с помощью call, происходит передача управления библиотеке ArBB, она берет на себя задачу контроля вычислений. После завершения работы функции контроль возвращается основному приложению. • Функция, вызванная с помощью map для контейнера, выполняется поэлементно для каждого элемента контейнера (Параллелизм по данным)
Пример реализации ArBBфункции • Функция получает двумерный контейнер с данными, результат усреднения по столбцам сохраняет во второй контейнер void AverageTwoDim (const dense<i8,2> &a, dense<i8> &res) { _if (res.length()==a.num_cols()) { _for (usizei=0, i<a.num_cols(), i++) {res[i]=add_reduce((dense<i16>)a.col(i))/(i16)a.num_rows(); } _end_for } _end_if } • Для проведения экспериментов использовалась именно эта функция
Сравнение способов вызова ArBB-функций по времени исполнения
Выводы. • Исходя из экспериментов, очевидно, нужно использовать вызовы функций, использующих ArBB, с помощью call. • Пример: void difference(const dense<i8> &a, const dense<i8> &b, dense<u8> &c){ map(diff)(a, b, c); } void diff(const i8 &a, const i8 &b, u8 &c){ i32 cf = a - b; c = (u8)cf; } • Пример вызова: call(difference)(a,b,c);
Схема работы параллельной версии • Т.к. вызов функции с использованием map необходимо производить из функции, вызванной с помощью call, то схема вызова функций такая: Основное приложение – вызов с помощью call – вызов map Вызовы map Контейнеры Основное приложение Вызовы map Вызовы map
Сравнение параллельной и последовательной версий
Выводы • В процессе выполнения работ мы разработали последовательную и параллельную реализацию. Также было разработано демонстрационное приложение с графическим интерфейсом. • Библиотека Intel Array Building Blocks для решения практических задач на данных момент не приспособлена.