OpenCL图像计算然后屏幕渲染

时间:2016-06-01 14:03:36

标签: delphi opencl

我不知道如何开始实施这个项目:

  1. 将16位整数的矩阵加载到GPU存储器中(这是灰度放射图像)
  2. 通过应用函数(例如对比度增强算法)从第一个数组计算出16位整数的第二个矩阵
  3. 将第二矩阵的感兴趣区域转换为RGB图像以用于屏幕显示。
  4. 我可以做第一步和第二步,我坚持第3步! 我已经在CPU中实现了所有这些,所以这不是处理灰度或RGB图像,也不是为显示创建位图。 我还在OpenCL中实现了前两个步骤,然后在CPU内存中读取结果矩阵以进行RGB位图转换,然后显示它。但这当然是缓慢的,因为在CPU和GPU内存之间来回移动数据(图像真的很大:超过100万像素)。

    感谢任何帮助。我正在用Delphi 10编程,但C / C ++中的示例代码是可以的。我有VC2010并成功重建了NVidia OpenCL oclNbody示例应用程序。

1 个答案:

答案 0 :(得分:0)

您的问题的解决方案在很大程度上取决于您要渲染的内容。也许,如果你进行医学图像处理,你需要显示高质量的图像。

根据您的说法,ROI分辨率远远大于显示分辨率。我不太了解OpenGL内置图像缩放滤镜的质量,所以首先我要测试OpenGL是否是编写复杂的OpenCL-OpenGL互操作代码之前的选择。无论如何,我更愿意使用缩放过滤器,我可以自定义。

因此,最灵活的选择是创建2个大小相同的OpenCL缓冲区以显示分辨率。然后,实现OpenCL内核,它们执行Grayscale - &gt; RGB转换&amp;下采样。<​​/ P>

伪代码如下:

// Original grayscale image;
cl_mem orig_image = clCreateBuffer(sizeof(uint16_t)*orig_width*orig_heigth);

// Grayscale ROI, downscaled to dispaly resolution, still 16 bits;
cl_mem disp_grayscale = clCreateBuffer(sizeof(uint16_t)*disp_width*disp_heigth);

// RGB image to display;
cl_mem disp_rgb = clCreateBuffer(sizeof(uint8_t)*3*disp_width*disp_heigth);

clEnqueueNDRangeKernel(DownscaleFilter, orig_image, disp_grayscale);
clEnqueueNDRangeKernel(GrayscaleToRGb, disp_grayscale, disp_rgb);

uint8_t *pixels = clEnqueueMapBuffer(disp_rgb);
// Deal with it as with usual image;

clEnqueueUnmapMemoryObject(disp_rgb);
// pixels are no longer available;
IMO,这里最复杂的问题是开发高质量的缩减滤波器。我已经测试了新的HEVC视频编码标准的8抽头缩减滤波器,非常好。