Ограничение размера окна в пирамиде LK с GPU-ускорением

Я выполняю стабилизацию изображения в режиме реального времени, чтобы запустить некоторые алгоритмы зрения на стабилизированных изображениях (акцент на «в реальном времени»). В настоящее время этот процесс, в котором используется версия пирамиды LK, реализованная на ЦП, едва ли достаточно быстр, даже при предварительном построении пирамиды (эталонное изображение и «предыдущие» функции вычисляются только один раз), но его необходимо масштабировать до работать с изображениями с разрешением примерно в четыре раза больше, что делает его слишком медленным в текущей реализации. Я подумал, что могу попытаться ускорить процесс, включив графический процессор, поскольку OpenCV реализовал тот же подход LK для устройств с поддержкой CUDA, класс cv::gpu::PyrLKOpticalFlow. Я использую вызов ::sparse с набором предыдущих функций.

Моя главная проблема заключается в том, что размер окна, похоже, ограничен, а мой слишком велик. Ограничение встречается в файле pyrlk.cpp как утверждение:

CV_Assert(patch.x > 0 && patch.x < 6 && patch.y > 0 && patch.y < 6);

Где размеры патча определены прямо выше:

void calcPatchSize(cv::Size winSize, dim3& block, dim3& patch)
{
    if (winSize.width > 32 && winSize.width > 2 * winSize.height)
    {
        block.x = deviceSupports(FEATURE_SET_COMPUTE_12) ? 32 : 16;
        block.y = 8;
    }
    else
    {
        block.x = 16;
        block.y = deviceSupports(FEATURE_SET_COMPUTE_12) ? 16 : 8;
    }

    patch.x = (winSize.width  + block.x - 1) / block.x;
    patch.y = (winSize.height + block.y - 1) / block.y;

    block.z = patch.z = 1;
}

Моя проблема в том, что мне нужен размер окна около 80x80 пикселей, а именно: А. почему я хочу использовать ускорение графического процессора и Б. почему это не работает в OpenCV. :) Кроме того, с изображениями большего разрешения размер этого окна должен увеличиваться.

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

Мне нужен такой большой размер окна поиска, потому что я рассчитываю движение до первого (эталонного) кадра. Движение является циклическим плюс небольшой случайный дрейф, поэтому этот метод работает хорошо, но требует немного больше места для поиска в пиках цикла, когда совпадающие объекты могут находиться на расстоянии около 30-40 пикселей (при исходном разрешении).

Это использует OpenCV версии 2.4.10 в Linux, созданную из исходного кода для поддержки CUDA.

(Это (несколько измененный) репост из http://answers.opencv.org/question/54579/window-size-limit-in-gpu-accelerated-lk-pyramid/, но, похоже, там не так много активности так что, надеюсь, SO обеспечивает лучшую среду для обсуждения!)


person Anthony    schedule 08.02.2015    source источник
comment
Если вы скомпилируете для правильного устройства, и ваше окно будет квадратным, мне кажется, что вы сможете получить winSize 80x80. Но не крупнее. Алгоритм, по-видимому, реализован таким образом, что он зависит от размера блока потоков графического процессора, поэтому да, похоже, что здесь задействовано ограничение аппаратного обеспечения/алгоритма. Вы отладили его, чтобы узнать, что такое фактически запрошенный winSize и результирующий вычисленный patch в точке утверждения? В конце концов, вероятно, кто-то вроде Jet47 придет и даст вам окончательный ответ.   -  person Robert Crovella    schedule 08.02.2015


Ответы (1)


Размер патча передается ядру CUDA в качестве параметра шаблона.

См. код вызова по адресу https://github.com/jet47/opencv/blob/master/modules/cudaoptflow/src/cuda/pyrlk.cu#L493:

static const func_t funcs[5][5] =
{
    {sparse_caller<1, 1, 1>, sparse_caller<1, 2, 1>, sparse_caller<1, 3, 1>, sparse_caller<1, 4, 1>, sparse_caller<1, 5, 1>},
    {sparse_caller<1, 1, 2>, sparse_caller<1, 2, 2>, sparse_caller<1, 3, 2>, sparse_caller<1, 4, 2>, sparse_caller<1, 5, 2>},
    {sparse_caller<1, 1, 3>, sparse_caller<1, 2, 3>, sparse_caller<1, 3, 3>, sparse_caller<1, 4, 3>, sparse_caller<1, 5, 3>},
    {sparse_caller<1, 1, 4>, sparse_caller<1, 2, 4>, sparse_caller<1, 3, 4>, sparse_caller<1, 4, 4>, sparse_caller<1, 5, 4>},
    {sparse_caller<1, 1, 5>, sparse_caller<1, 2, 5>, sparse_caller<1, 3, 5>, sparse_caller<1, 4, 5>, sparse_caller<1, 5, 5>}
};

где sparse_caller объявляется как:

template <int cn, int PATCH_X, int PATCH_Y>
void sparse_caller(int rows, int cols, const float2* prevPts, float2* nextPts, 
                   uchar* status, float* err, int ptcount,
                   int level, dim3 block, cudaStream_t stream)

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

person jet47    schedule 08.02.2015