英文:
What does this OpenCL code mean? How does uchar16 work? (OpenCV laplacian3.cl source)
问题
在 https://github.com/opencv/opencv/blob/4.x/modules/imgproc/src/opencl/laplacian3.cl 的第107至118行,我找到了以下代码:
arr[0] = (uchar16)(a, b.s0123, b.s456789ab, b.scde);
arr[1] = b;
arr[2] = (uchar16)(b.s123, b.s4567, b.s89abcdef, c);
arr[3] = (uchar16)(d, e.s0123, e.s456789ab, e.scde);
arr[4] = e;
arr[5] = (uchar16)(e.s123, e.s4567, e.s89abcdef, f);
arr[6] = (uchar16)(g, h.s0123, h.s456789ab, h.scde);
arr[7] = h;
arr[8] = (uchar16)(h.s123, h.s4567, h.s89abcdef, i);
arr[9] = (uchar16)(j, k.s0123, k.s456789ab, k.scde);
arr[10] = k;
arr[11] = (uchar16)(k.s123, k.s4567, k.s89abcdef, l);
变量 a, b, c, d, e, f, g, h, i, j, k, l
声明如下:
uchar a; uchar16 b; uchar c;
uchar d; uchar16 e; uchar f;
uchar g; uchar16 h; uchar i;
uchar j; uchar16 k; uchar l;
我对于例如 b.s0123
的含义也感到有些困惑。它看起来不像普通的 C++ 代码。也许它是特殊的 OpenCL 语法?
英文:
In https://github.com/opencv/opencv/blob/4.x/modules/imgproc/src/opencl/laplacian3.cl, line 107-118, I found the following code:
arr[0] = (uchar16)(a, b.s0123, b.s456789ab, b.scde);
arr[1] = b;
arr[2] = (uchar16)(b.s123, b.s4567, b.s89abcdef, c);
arr[3] = (uchar16)(d, e.s0123, e.s456789ab, e.scde);
arr[4] = e;
arr[5] = (uchar16)(e.s123, e.s4567, e.s89abcdef, f);
arr[6] = (uchar16)(g, h.s0123, h.s456789ab, h.scde);
arr[7] = h;
arr[8] = (uchar16)(h.s123, h.s4567, h.s89abcdef, i);
arr[9] = (uchar16)(j, k.s0123, k.s456789ab, k.scde);
arr[10] = k;
arr[11] = (uchar16)(k.s123, k.s4567, k.s89abcdef, l);
The variables a,b,c,d,e,f,g,h,i,j,k,l
are declared as following:
uchar a; uchar16 b; uchar c;
uchar d; uchar16 e; uchar f;
uchar g; uchar16 h; uchar i;
uchar j; uchar16 k; uchar l;
I'm a little confused what does, for example, b.s0123
do? It doesn't look like normal C++ code to me. Maybe it's special OpenCL grammar?
答案1
得分: 1
在OpenCL中,uchar16
是一个包含16个元素的向量。
你可以使用一种类似于“成员”的语法访问它的元素。你可以访问单个元素(b.s0
),或者将多个元素作为另一个向量访问(b.s0123
)。
假设 b
是一个 uchar16
...
arr[0] = (uchar16)(a, b.s0123, b.s456789ab, b.scde);
这组成了一个 新的 uchar16
(并将其赋值给 arr[0]
),使用了 a
的值和 b
的前15个元素(0
到 e
),分为三部分访问:两个4元素的向量和一个3元素的向量。b
的值会 向右偏移(视图向左偏移)。
arr[1] = b;
这只是复制了这个向量。
arr[2] = (uchar16)(b.s123, b.s4567, b.s89abcdef, c);
这类似于第一个情况,不过现在取的是 b
的最后15个值,以及 c
。这会使 b
看起来向 左偏移。
这个模式会再次重复三次,使用不同的变量。
总的来说,这看起来像是通过准备一个(大)矩阵来设置卷积。我猜测这是一个3x3的卷积(通过偏移实现),它可以在4通道的数据上运算(b,e,h,k
)。
这是有道理的,因为拉普拉斯算子是通过卷积一个核来计算的。
从_这些实现_中你不会学到太多关于拉普拉斯算子或卷积的理论知识。这些实现只是 代码。代码不能解释理论。
英文:
In OpenCL, an uchar16
is a 16-element vector.
You can access its elements using a kind of "member" syntax. You can access individual elements (b.s0
), or access several elements as another vector (b.s0123
).
Given that b
is an uchar16
...
arr[0] = (uchar16)(a, b.s0123, b.s456789ab, b.scde);
That composes a new uchar16 (and assigns it to arr[0]
), using the value of a
and the first 15 elements of b
(0
to e
), accessed in three pieces: two 4-element and one 3-element vector. The values of b
appear shifted to the right (the view is shifted left).
arr[1] = b;
That just copies the vector.
arr[2] = (uchar16)(b.s123, b.s4567, b.s89abcdef, c);
That's like the first case, except now the last 15 values of b
are taken, along with c
. This makes b
appear shifted to the left now.
That pattern repeats another three times, with different variables.
Overall, that looks like a convolution is set up by preparing a (big) matrix. I'm guessing it's a 3x3 convolution (the shifts) and it can operate on 4-channel data (b,e,h,k
).
That makes sense because the laplacian is calculated as a convolution of a kernel.
You are not gonna learn much about the laplacian or convolutions from those implementations. These implementations are code. Code does not explain the theory.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论