Opencl CLENQUEUREADBUFFER返回一个空缓冲区

Opencl CLENQUEUREADBUFFER返回一个空缓冲区,opencl,Opencl,我正在尝试实现一个OpenCL项目,它应该接收两个灰色通道图像并返回一个灰色通道缓冲区 我的OpenCL代码: __kernel void motion_detection(__global uchar* bgImage, __global uchar* motionImage,__global uchar* outputImage) { int i = get_global_id(0); int tsh = 7; uchar bgEl = bgImage[i]; uchar

我正在尝试实现一个OpenCL项目,它应该接收两个灰色通道图像并返回一个灰色通道缓冲区

我的OpenCL代码:

 __kernel void motion_detection(__global uchar* bgImage, __global uchar* motionImage,__global uchar* outputImage)
{
  int i = get_global_id(0);
  int tsh = 7;
  uchar bgEl = bgImage[i];
  uchar motionEl = motionImage[i];


float bg = convert_float(bgEl);
float mo = convert_float(motionEl);
float temp = fabs(bg-mo);

if(temp>tsh){temp=255.0;
 }else
       {temp=0.0;
     }

outputImage[i] = convert_uchar(bg);
}
我的主人:

// get width and height of input image
height = inputImage->rows;
width = inputImage->cols;

// get the pointer to pixel data
cl_uchar* inputImageData = inputImage->data;
cl_uchar* motionImageData = motionImage->data;
cl_uchar* outputImageData = outputImage->data;
设置缓冲区后:

// Create memory object for input Image
inputImageBuffer = clCreateBuffer(
    context,
    CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
    width * height * greyPixelSize,
    inputImageData,
    &status);
CHECK_OPENCL_ERROR(status, "clCreateBuffer failed. (inputImageBuffer)");

motionImageBuffer = clCreateBuffer(
    context,
    CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
    width * height * greyPixelSize,
    motionImageData,
    &status);
CHECK_OPENCL_ERROR(status, "clCreateBuffer failed. (inputImageBuffer)");


// Create memory objects for output Image
outputImageBuffer = clCreateBuffer(
    context,
     CL_MEM_READ_WRITE,
    width * height * greyPixelSize,
    0,
    &status);
设置参数并执行OpenCL内核:

// input buffer image
status = clSetKernelArg(
    kernl,
    0,
    sizeof(cl_mem),
    &inputImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (inputImageBuffer)");

status = clSetKernelArg(
    kernl,
    1,
    sizeof(cl_mem),
    &motionImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (inputImageBuffer)");

    // outBuffer imager
    status = clSetKernelArg(
    kernl,
    2,
    sizeof(cl_mem),
    &outputImageBuffer);
CHECK_OPENCL_ERROR(status, "clSetKernelArg failed. (outputImageBuffer)");

status = clEnqueueNDRangeKernel(
    commandQueue,
    kernl,
    1,
    NULL,
    globalThreads,
    localThreads,
    0,
    NULL,
    &ndrEvt);
clFinish(commandQueue);
这是我的问题,当执行此指令时,它将outputImageData返回为\0,而不返回其他内容:


对输出缓冲区使用CL_WRITE_ONLY标志。这不意味着主机上无法访问缓冲区吗?实际上,它是CL_MEM_READ_WRITECL_WRITECL_WRITECL_WRITE_只是从设备的角度来看,而不是从主机的角度来看,所以在这里可以。您希望从clEnqueueReadBuffer返回0,这表示它已工作。当它返回时,由于您设置了blocking_read标志,缓冲区应该已被读取。bgImage是否包含一些有意义的内容?您的内核似乎按原样将bgImage复制到outputImage,并将其转换为float,再转换回uchar以写入结果。无论如何,如果对clEnqueueReadBuffer有疑问,最好只从这个内核中写入常量值,看看读取缓冲区是否正常。@harism是的。我正在从motionImage中减去backgroundImages像素,如果此减法大于阈值,则在outputimage中将像素设置为255。
status = clEnqueueReadBuffer(
    commandQueue,
    outputImageBuffer,
    CL_TRUE,
    0,
    width * height * greyPixelSize,
    outputImageData,
    0,
    NULL,
    NULL);
CHECK_OPENCL_ERROR(status, "clEnqueueReadBuffer failed.");