Syntax/Functions 用于 OpenCV 的 OpenCL 实现
Syntax/Functions used in the OpenCL-Implemantation of OpenCV
我试图了解 OpenCV 中 OpenCL 的使用,但我不明白:
这是来自 orb.cpp
的代码部分示例,其中创建了位于 orb.cl
中的名称为 ORB_HarrisResponses
的内核(可能):
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 实现的基本了解以回答以下问题:
- "normal" 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));
在这部分中,位于字符串 orb.cl
build 中的内核代码 ORB_HarrisResponses
被创建为 hr_ker
(对吗?)。
- 但是 format(...) 的作用是什么?
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);
在内核参数的这一部分中设置了 imgbuf
、layerinfo
、keypoints
并且内核的输出存储在响应中。
nkeypoints是怎么回事?
为什么前面没有ocl::KernelArg
这个参数?
orb.cl
中的内核有7个参数但只设置了5个,为什么?
- 从 return
hr_ker.args(...)
中 return 到底是什么?
这种语法是一种内部 OpenCV "sugar" 不重复一些常见的代码块。不幸的是,没有好的文档,所以学习它的唯一方法是查看源代码和示例。
给你的一些提示:
- OpenCL API 和 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_OCL_RUN_
宏和 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_ker.args
returns 引用 cv::ocl::Kernel
因此您可以使用以下结构:kernel.args(...).run(...)
.
一些有用的链接:
cv::format
documentation. It works like boost::format
.
希望对您有所帮助。
我试图了解 OpenCV 中 OpenCL 的使用,但我不明白:
这是来自 orb.cpp
的代码部分示例,其中创建了位于 orb.cl
中的名称为 ORB_HarrisResponses
的内核(可能):
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 实现的基本了解以回答以下问题:
- "normal" 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));
在这部分中,位于字符串 orb.cl
build 中的内核代码 ORB_HarrisResponses
被创建为 hr_ker
(对吗?)。
- 但是 format(...) 的作用是什么?
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);
在内核参数的这一部分中设置了 imgbuf
、layerinfo
、keypoints
并且内核的输出存储在响应中。
nkeypoints是怎么回事?
为什么前面没有
ocl::KernelArg
这个参数?orb.cl
中的内核有7个参数但只设置了5个,为什么?- 从 return
hr_ker.args(...)
中 return 到底是什么?
这种语法是一种内部 OpenCV "sugar" 不重复一些常见的代码块。不幸的是,没有好的文档,所以学习它的唯一方法是查看源代码和示例。
给你的一些提示:
- OpenCL API 和 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_OCL_RUN_
宏和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_ker.args
returns 引用cv::ocl::Kernel
因此您可以使用以下结构:kernel.args(...).run(...)
.
一些有用的链接:
cv::format
documentation. It works likeboost::format
.
希望对您有所帮助。