Улучшение скорости обработки изображений - PullRequest
9 голосов
/ 28 января 2012

Я использую C ++ и OpenCV для обработки некоторых изображений, снятых с веб-камеры в режиме реального времени, и я стремлюсь добиться максимальной скорости от моей системы.

Кроме изменения алгоритма обработки (предположим, что пока вы не можете его изменить). Что-нибудь, что я должен сделать, чтобы максимизировать скорость обработки?

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

Предполагая, что у меня есть x-core процессор, разделение обработки на x потоков на самом деле ускоряет процесс? ... или издержки управления этих потоков сводят его на нет, предполагая, что я ищу пропускную способность 20 кадров в секунду (полагаю это повлияет на ответ, который вы дадите, так как оно должно дать вам представление о том, сколько обработки будет выполнено для потока)

Может ли многопоточность помочь здесь?

Существуют ли какие-либо советы по увеличению скорости OpenCV, а также любые подводные камни, с которыми я могу столкнуться, которые снижают скорость.

Спасибо.

Ответы [ 6 ]

6 голосов
/ 28 января 2012

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

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

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

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

5 голосов
/ 28 января 2012

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

"... путем построения заголовка для части другой матрицы. Это может быть одна строка, один столбец, несколько строк, несколько столбцовпрямоугольная область в матрице (называемая минорной в алгебре) или диагональ. Такие операции также являются O (1), потому что новый заголовок будет ссылаться на те же данные. Вы можете фактически изменить часть матрицы с помощью этой функции, например"

// add 5-th row, multiplied by 3 to the 3rd row
M.row(3) = M.row(3) + M.row(5)*3;

// now copy 7-th column to the 1-st column
// M.col(1) = M.col(7); // this will not work
Mat M1 = M.col(1);
M.col(7).copyTo(M1);

Возможно, вы уже знали об этой проблеме, но я думаю, что важно выделить заголовки в openCV как важный и эффективный инструмент кодирования.

4 голосов
/ 28 января 2012

Предполагая, что у меня есть x-core процессор, ускоряет ли разделение обработки на x потоков?

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

Некоторые алгоритмы чрезвычайно легко распараллелить, например, имеющие форму:

for (i=0; i < DATA_SIZE; i++)
{
   output[i] = f(input[i]);
}

для некоторой функции f,Они известны как смущающе распараллеливаемый ;Вы можете просто разделить данные на N блоков и N потоков обрабатывают каждый блок отдельно.Такие библиотеки, как OpenMP, делают этот вид потоков чрезвычайно простым.

3 голосов
/ 28 января 2012

Если конкретный алгоритм, который вы используете, уже оптимизирован для многопоточной / параллельной платформы, использование его на x-core процессоре ничего не даст для вас.Алгоритм должен быть по своей сути многопоточным, чтобы использовать несколько потоков.Но если бы он не был разработан с учетом этого, его пришлось бы изменить.С другой стороны, многие алгоритмы обработки изображений "смущающе параллельны", по крайней мере, в концепции.Можете ли вы поделиться более подробной информацией об имеющемся у вас алгоритме?

2 голосов
/ 28 января 2012

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

1 голос
/ 16 января 2014

В качестве примера кода для многопоточной обработки изображений с OpenCV, вы можете проверить мой код:

https://github.com/vmlaker/sherlock-cpp

Это то, что я придумал, чтобы использовать преимущества x-core CPU для повышения производительности обнаружения объектов. Программа detect - это в основном параллельный алгоритм, который распределяет задачи по нескольким потокам, отдельный конвейерный поток для каждой задачи:

  1. Распределение кадровой памяти и захват видео.
  2. Обнаружение объектов (один поток на каждый классификатор Хаара.)
  3. Увеличение вывода с помощью результата обнаружения и отображение кадра.
  4. освобождение памяти.

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

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