我正在尝试实现我用 C# 编写的模糊函数。我希望它在 openCL 内核中运行
功能如下:
private static int cSharpBlur(double[,] blur, int width, int height, int[,] imageToInt, int[,] outputImage, int i, int j)
{
int maskSize = 1;
double sum = 0.0f;
// Collect neighbor values and multiply with gaussian
for (int a = -maskSize; a < maskSize + 1; a++)
{
for (int b = -maskSize; b < maskSize + 1; b++)
{
sum += blur[a+1, b+1] * imageToInt[Clamp(i+a,0,width-1), Clamp(j+b,0,height-1)];
}
}
byte[] values = BitConverter.GetBytes(imageToInt[i,j]);
int alpha = values[3];
int alphasum = alpha * (int)sum;
values[3] = (byte)alphasum;
int newValue = BitConverter.ToInt32(values,0);
return newValue;
}
现在我显然在openCL中没有.GetBytes和BitConverter.ToInt32。 我也没有二维数组。
我通过以下方式解决了这个问题 __kernel void gaussianBlur(__global int* imageToInt, int 宽度, int 高度, __global double* 模糊缓冲区, int 模糊缓冲区大小, __全局 int* 输出缓冲区){ int col = get_global_id(0); int row = get_global_id(1);
double sum = 0.0f;
for (int a = -1; a < 2; a++)
{
for (int b = -1; b < 2; b++)
{
sum += blurBuffer[a+b+2] * imageToInt[col+width*row];
}
}
outputBuffer[col + width * row] = sum;
缺少的是整个 getBytes 和 ToInt 的东西。
如何在 openCL 中做到这一点?
提前致谢,周末愉快!
对于
getBytes
,请使用 as_uchar4
:
uchar4 values = as_uchar4(imageToInt[col+width*row]);
对于
ToInt32
,请使用 as_int
:
int newValue = as_int(values);
所以你的内核应该看起来像这样:
__kernel void gaussianBlur(__global int* imageToInt, int width, int height, __global double* blurBuffer, int blurBufferSize, __global int* outputBuffer) {
int col = get_global_id(0); int row = get_global_id(1);
int maskSize = 1;
double sum = 0.0f;
for(int a = -maskSize; a < maskSize + 1; a++) { // Collect neighbor values and multiply with gaussian
for(int b = -maskSize; b < maskSize + 1; b++) {
sum += blurBuffer[a+1+(b+1)*2*maskSize] * imageToInt[col+width*row];
}
}
uchar4 values = as_uchar4(imageToInt[col+width*row]);
int alpha = (int)values.s3;
int alphasum = alpha * (int)sum;
values.s3 = (uchar)alphasum;
int newValue = as_int(values);
outputBuffer[col+width*row] = newValue;
}
这些
as_...
函数内置于 OpenCL C 中,只要总位数保持不变,您就可以重新解释组成数字的位。在您的例子中, int
由 4 个字节组成,就像 uchar4
向量数据类型一样。使用 uchar4
,您可以使用 .s1
、.s1
、.s2
、.s3
或使用 .x
、.y
、.z
、.w
对各个字节进行寻址。
as_...
函数也可用于获取 float
数字的各个位,例如:
float x = 1.0f;
int bits = as_int(x);
在普通C中,你也可以手动编写这样的函数:
uint as_int(const float x) {
return *(int*)&x;
}
OpenCL C 比大多数其他语言都具有更多的数学功能。所有内置功能都列在这张超级有用的参考卡中。