【问题标题】:Iterative image processing in CUDACUDA 中的迭代图像处理
【发布时间】:2022-05-15 19:01:32
【问题描述】:

我编写了一个 CUDA 内核来处理图像。但是根据处理后的图像的输出,我必须再次调用内核来重新调整图像。 例如,让我们考虑一个具有9 像素的图像

1 2 3
4 5 6
7 8 9 

假设根据其相邻值,值9 更改为10。由于值已更改,我必须使用相同的内核重新处理新图像。

1 2 3
4 5 6
7 8 10

我已经编写了在单次迭代中处理图像的算法。我计划在 CUDA 中实现迭代的方式如下:

__global__ void process_image_GPU(unsigned int *d_input, unsigned int *d_output, int dataH, int dataW, unsigned int *val) {

     __shared__ unsigned int sh_map[TOTAL_WIDTH][TOTAL_WIDTH];
     // Do processing
     // If during processing, anywhere any thread changes the value of the image call
            { atomicAdd(val, 1); }

}
int main(int argc, char *argv[]) {
    // Allocate d_input, d_output and call cudaMemcpy
    unsigned int *x, *val;
    x = (unsigned int *)malloc(sizeof(unsigned int));
    x[0] = 0;
    cudaMalloc((void **)&val, sizeof(unsigned int));
    cudaMemcpy((void *)val, (void *)x, sizeof(unsigned int), cudaMemcpyHostToDevice);
    process_image_GPU<<<dimGrid, dimBlock>>>(d_input, d_output, rows, cols, val);
    cudaMemcpy((void *)x, (void *)val, sizeof(unsigned int), cudaMemcpyDeviceToHost);
    if(x != 0) 
        // Call the kernel again
}

这是唯一的方法吗?还有其他有效的方法来实现吗?

非常感谢您的宝贵时间。

【问题讨论】:

  • 这个问题在概念上类似于快速行进/快速扫描/快速迭代方法,其中信息通过更新相邻像素在计算域中传播。
  • 也许在该领域引入的关于设置迭代和停止规则的想法可能有用。
  • 谢谢。正如其中一个答案/cmets(已被删除 - 我不知道为什么)中所建议的那样,我删除了 atomicAdd 并将其替换为 *val=1 因为我只关心是否有任何更改。
  • 您能否更具体地说明您正在执行的处理类型,特别是一个像素上的扰动如何反映到相邻像素上的扰动?也许,知道这一点后,人们可以提出一种与您设计的方法不同的方法。

标签: cuda


【解决方案1】:

尽管您提供的信息几乎消失了,但我还是冒险回答。希望对您有所帮助。

根据您所说,您已经根据相邻像素的值为像素设置了更新规则。让x^(k)_ij在第k次迭代时像素号ij的值让

x^(k+1)_ij = f(x^(k)_(i-1)j, x^(k)_ij, x^(k)_(i+1)j, x^(k)_i(j-1), x^(k)_i(j+1))

我假设典型的基于模板的更新规则,但当然其他规则也是可能的。

此时,您必须设置一个停止规则,即指示您的算法是否已达到收敛的规则。例如,您可以在步骤k+1 和k 处评估两个图像之间差异的范数。

一旦以这种方式提出问题,我会说你有以下两种可能性:

  1. Rouy-Tourin-like 方案:所有计算像素都以“同时”的蛮力方式更新,直到达到收敛;
  2. Fast sweeping method: 计算网格沿着预定数量的方向进行扫描(选择性更新),直到达到收敛;

根据您要处理的问题类型,我会说您还有其他可能性:

  1. Fast iterative method:在堆结构的帮助下有选择地更新计算像素。

以上所有方法都比较过,对于eikonal方程的解,here。

当然,对于我们感兴趣的特定问题,您需要展示上述计算方案的收敛性。

【讨论】:

  • 抱歉回复延迟。是的,我使用的是典型的基于模板的规则。如果像素的值大于其平均值的某个阈值(相邻值 * 卷积滤波器),我将用新值(相邻值的平均值)替换它。我正在使用蛮力方法。我是并行编程的新手,正在经历上述方法。将尝试一一合并并在此处发布。非常感谢。
猜你喜欢
  • 2012-03-20
  • 2015-08-09
  • 2014-05-15
  • 2016-08-04
  • 2013-07-03
  • 2016-07-20
  • 2012-06-26
  • 1970-01-01
  • 2014-12-09
相关资源
最近更新 更多