OpenCV的OpenCL实现中使用的语法/函数

OpenCV的OpenCL实现中使用的语法/函数,opencv,opencl,Opencv,Opencl,我试图理解OpenCV中OpenCL的用法,但我不明白: 这是来自orb.cpp的示例代码部分,其中创建了位于orb.cl中名为orb\u harrisresponse的内核(可能): 但这不是常规的OpenCL语法(像clCreateKernel这样的函数…)。有人知道我在哪里可以基本了解OpenCV的OpenCL实现,以回答以下问题: “正常”OpenCL和OpenCV OpenCL之间的连接在哪里 从内核源文件构建程序的位置 创建内核的函数在哪里 等 我在网上找不到文件或相关问题。 谢

我试图理解OpenCV中OpenCL的用法,但我不明白:

这是来自
orb.cpp
的示例代码部分,其中创建了位于
orb.cl
中名为
orb\u harrisresponse
的内核(可能):

但这不是常规的OpenCL语法(像clCreateKernel这样的函数…)。有人知道我在哪里可以基本了解OpenCV的OpenCL实现,以回答以下问题:

  • “正常”OpenCL和OpenCV OpenCL之间的连接在哪里
  • 从内核源文件构建程序的位置
  • 创建内核的函数在哪里
我在网上找不到文件或相关问题。 谢谢

编辑:感谢您的回答,这有助于理解一些事情:

 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));
在这一部分中,位于字符串
ocl::features2d::ORB_oclsrc
中的内核代码
ORB_harrisresponse
被创建为
hr_ker
(右?)

  • 但是格式(…)是做什么的呢
如果
hr\u ker.empty()
返回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);
在这部分内核参数中,
imgbuf
layerinfo
关键点被设置,内核的输出被存储在响应中

  • nkeypoints怎么了

  • 为什么此参数前面没有
    ocl::KernelArg

  • orb.cl
    中的内核有7个参数,但只设置了5个,为什么
  • 从return
    hr\u ker.args(…)
    返回的确切内容是什么

此语法是一种内部OpenCV“sugar”,不重复某些常见代码块。不幸的是,没有好的文档,所以学习它的唯一方法是查看源代码和示例

给你的一些提示:

  • OpenCLAPI和opencv之间的连接位于
    modules\core\src\ocl.cpp
    (请参见
    Kernel
    Kernel::Impl
    Program
    ProgramSource
    KernelArg
    类)
  • 存储在*.cl文件中的内核源代码(例如,ORB内核位于modules\features2d\src\opencl\ORB.cl文件中)。在模块构建时,内核的代码正在复制到自动生成的cpp文件(例如opencl_kernels_features2d.cpp),代码可以通过
    ocl::features2d::orb_oclsrc
    访问
  • 要在opencv中使用opencl实现,您需要传递到函数
    cv::UMat
    ,而不是常规的
    cv::Mat
    (请参见
    cv\u OCL\u RUN\ucode>宏和
    cv::OutputArray::isUMat()
    方法)
基本上,opencv中的所有opencl实现都执行以下操作:

  • 定义内核参数,如全局大小、块大小等
  • 使用带有源代码和定义参数的字符串创建cv::ocl::Kernel。(如果未创建内核或没有针对指定输入参数的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\u ker.args
    返回对
    cv::ocl::Kernel
    的引用,因此可以使用以下构造:
    Kernel.args(…).run(…)
一些有用的链接:

  • cv::format
    。它的工作原理是

希望能有所帮助。

谢谢你回答我的问题:)。也许你可以再看一次编辑过的问题:)你好,我有一个问题与你的答案有关,所以我希望你再看一次:)你说:“ocl::KernelArg::ReadOnlyNoSize实际上扩展到三个参数:imgbuf、imgstep、imgoffset0。”我如何从imgstep和imgoffset获取值?谢谢:)@akarsakov实际上在opencv3.3.0中,cv::ocl::KernelArg::ReadWrite()将扩展为五个参数,类似于
\u全局uchar*dst、int-dst\u步长、int-dst\u偏移、int-dst\u行、int-dst\u cols
ORB_HarrisResponses(__global const uchar* imgbuf, int imgstep, int imgoffset0,
                    __global const int* layerinfo, __global const int* keypoints,
                    __global float* responses, int nkeypoints )