2017-05-30 37 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