2017-05-30 36 views
1

的OpenCL的-Implemantation使用語法/函數我試着去了解OpenCV的範圍內使用OpenCL的,但我不明白:在OpenCV中

這是一個例子Codepart從orb.cpp其中名爲ORB_HarrisResponses內核位於orb.cl創建(propably):

ocl::Kernel hr_ker("ORB_HarrisResponses", ocl::features2d::orb_oclsrc, 
      format("-D ORB_RESPONSES -D blockSize=%d -D scale_sq_sq=%.12ef - 
      D HARRIS_K=%.12ff", blockSize, scale_sq_sq, harris_k)); 
return hr_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf), 
      ocl::KernelArg::PtrReadOnly(layerinfo), 
      ocl::KernelArg::PtrReadOnly(keypoints), 
      ocl::KernelArg::PtrWriteOnly(responses), 
      nkeypoints).run(1, globalSize, 0, true); 

但是,這是不是正規的OpenCL語法(如clCreateKernel功能...)。有人知道我在哪裏可以對OpenCV的OpenCL實現有一個基本的瞭解,以回答以下問題:

  • 「正常」OpenCL和OpenCV OpenCL之間的連接在哪裏?
  • 當程序從內核源文件建立?
  • 哪裏是函數,它創建內核解釋呢?

我couldn't找到的文檔或相關問題網頁。 感謝

編輯:謝謝回答它有助於瞭解幾件事情:

ocl::Kernel hr_ker("ORB_HarrisResponses", ocl::features2d::orb_oclsrc, 
      format("-D ORB_RESPONSES -D blockSize=%d -D scale_sq_sq=%.12ef -D HARRIS_K=%.12ff", blockSize, scale_sq_sq, harris_k)); 

在這部分位於orb.cl構建字符串ocl::features2d::orb_oclsrc內的內核代碼ORB_HarrisResponseshr_ker創建(右? )。

  • 但格式(...)是什麼?

if hr_ker.empty() return false;

return hr_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf), 
      ocl::KernelArg::PtrReadOnly(layerinfo), 
      ocl::KernelArg::PtrReadOnly(keypoints), 
      ocl::KernelArg::PtrWriteOnly(responses), 
      nkeypoints).run(1, globalSize, 0, true); 

在內核參數imgbuflayerinfo這一部分,keypoints被設置和內核的輸出被存儲在應答。

  • nkeypoints發生了什麼?

  • 爲什麼沒有這個參數的ocl::KernelArg

  • orb.cl中的內核有7個參數,但只設置了5個,爲什麼?
  • 究竟是從退貨hr_ker.args(...)返回什麼?

回答

2

此語法是一種內部OpenCV「糖」,不重複一些常見的代碼塊。不幸的是,沒有好的文檔,所以學習它的唯一方法是通過源代碼和示例來查看。

一些建議給你:OpenCL的API和OpenCV之間

  • 連接在modules\core\src\ocl.cpp(見KernelKernel::ImplProgramProgramSourceKernelArg類)。
  • 存儲在* .cl文件中的內核源代碼(例如ORB內核位於modules \ features2d \ src \ opencl \ orb.cl文件中)。內核的模塊構建代碼正在複製到自動生成的cpp文件(例如opencl_kernels_features2d.cpp),代碼可以通過ocl::features2d::orb_oclsrc訪問。
  • 要在opencv中使用opencl實現,您需要傳遞函數cv::UMat而不是常規cv::Mat(請參閱CV_OCL_RUN_宏和cv::OutputArray::isUMat()方法)。

裏面基本上所有的OpenCV OpenCL實現執行以下操作:

  • 定義內核參數,如全球大小,塊大小等
  • 創建簡歷:: OCL ::內核使用字符串源代碼和定義的參數。 (如果沒有創建內核,或者對於指定的輸入參數沒有opencl實現,則處理傳遞給常規的cpu代碼)。
  • 通過cv::ocl::KernelArgs傳遞內核參數。有幾種類型的參數可以優化處理:只讀,只寫,常量等。
  • 運行內核。

因此對於使用opencl實現的最終用戶是透明。如果出現問題,則處理切換到cpu實現。

讓我們討論下面的代碼片段:

return hr_ker.args(ocl::KernelArg::ReadOnlyNoSize(imgbuf), 
      ocl::KernelArg::PtrReadOnly(layerinfo), 
      ocl::KernelArg::PtrReadOnly(keypoints), 
      ocl::KernelArg::PtrWriteOnly(responses), 
      nkeypoints).run(1, globalSize, 0, true); 

和OCL函數聲明:

ORB_HarrisResponses(__global const uchar* imgbuf, int imgstep, int imgoffset0, 
        __global const int* layerinfo, __global const int* keypoints, 
        __global float* responses, int nkeypoints) 
  • nkeypoints是整數,所以沒必要把它換到ocl::KernelArg。它會直接傳遞給內核。
  • ocl::KernelArg::ReadOnlyNoSize實際擴展爲三個參數:imgbuf,imgstep,imgoffset0。
  • 其他內核參數不擴展,所以它代表單個參數。
  • hr_ker.args返回對cv::ocl::Kernel的引用,因此您可以使用以下構造:kernel.args(...).run(...)

一些有用的鏈接:

希望它會有所幫助。

+0

感謝您回答我的問題:)。也許你可以再看看編輯的問題:) – Drian

+0

@Drian Yep,我已經更新了答案。 – akarsakov

+0

嗨,我有一個問題與你的答案有關,所以我希望你會再看看這裏:)你說:「ocl :: KernelArg :: ReadOnlyNoSize實際上擴展爲三個參數:imgbuf,imgstep,imgoffset0。」我如何從imgstep和imgoffset獲取值?謝謝:) – Drian