2015-02-08 85 views
0

爲了在穩定圖像上運行一些視覺算法(強調「實時」),我正在執行實時反饋的圖像穩定。目前,使用CPU實現的LK金字塔版本的這個過程幾乎不夠快,即使事先構建金字塔(參考圖像和「以前的」特徵只計算一次),但它需要縮放到以約四倍的分辨率處理圖像,這使得它在當前的實現中變得太慢。自從OpenCV爲支持CUDA的設備cv :: gpu :: PyrLKOpticalFlow類實現相同的LK方法後,我想我可能會嘗試通過整合GPU來加快速度。我使用::稀疏調用與一組以前的功能。GPU加速LK金字塔中的窗口大小限制

我的主要問題是,似乎有一個窗口大小的限制,而我的太大。該限制發生在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; 
} 

我的問題是我需要的約80×80像素的窗口大小,這是A.爲什麼我想要使用GPU加速和B.爲什麼這在OpenCV中似乎不起作用。 :)另外,對於更大的分辨率圖像,此窗口大小將需要增加。

我對實際實現GPU加速並不熟悉,所以我想知道是否有人可以解釋爲什麼OpenCV中存在這種限制,如果它是硬件或OpenCV實現施加的真正限制,以及是否有方法解決它。看起來奇怪的是,這將是一個硬件限制,因爲這些是你想要使用GPU的情況。我可以通過較小的搜索窗口獲得合理的速度,但穩定性對於應用程序來說不夠好。

我需要這麼大的搜索窗口大小,因爲我正在計算運動到第一個(參考)幀。運動是週期性的,加上一些小的隨機漂移,所以這種方法效果很好,但當匹配特徵可能在30-40個像素之外(以原始分辨率)時,需要更多空間來搜索週期的峯值。

這是在Linux上使用OpenCV版本2.4.10,從源代碼爲CUDA支持構建的。

(這是一個(稍作修改)從http://answers.opencv.org/question/54579/window-size-limit-in-gpu-accelerated-lk-pyramid/重職,但似乎並沒有太大的活動有,所以希望SO提供了更好的環境討論!)

+1

如果你編譯適當的設備,並且你的窗口是方形的,它在我看來應該能夠達到80x80的「winSize」。但沒有更大。該算法似乎是以這樣一種方式實現的,即它依賴於GPU線程塊大小,所以是的,似乎涉及到HW /算法限制。你是否調試過它來發現實際請求的'winSize'是什麼,並在斷言的位置上計算出的'patch'?最終可能有人會像Jet47一樣來給你一個明確的答案。 – 2015-02-08 03:27:38

回答

3

補丁大小被傳遞到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) 

的補丁大小的限制是爲了減少模板實例的數量。您可以通過修改此代碼並添加更多實例來爲您的需要增加此限制。