0

我已经修改了 Sobel 过滤器示例以实现 Canny 过滤器的非最大值抑制。但是,以下代码会生成异常:

unsigned char pix00 = pCannyOriginal[ i-1 + (blockIdx.x-1) * blockDim.x];
unsigned char pix01 = pCannyOriginal[ i+0 + (blockIdx.x-1) * blockDim.x];
unsigned char pix02 = pCannyOriginal[ i+1 + (blockIdx.x-1) * blockDim.x];
unsigned char pix10 = pCannyOriginal[ i-1 + (blockIdx.x+0) * blockDim.x];
unsigned char pix11 = pCannyOriginal[ i+0 + (blockIdx.x+0) * blockDim.x];
unsigned char pix12 = pCannyOriginal[ i+1 + (blockIdx.x+0) * blockDim.x];
unsigned char pix20 = pCannyOriginal[ i-1 + (blockIdx.x+1) * blockDim.x];
unsigned char pix21 = pCannyOriginal[ i+0 + (blockIdx.x+1) * blockDim.x];
unsigned char pix22 = pCannyOriginal[ i+1 + (blockIdx.x+1) * blockDim.x];

我知道这会导致对内存的无效访问,但是原始纹理上的同一组分配不会生成一个。那么,tex2D 函数是否有无效内存访问的机制呢?我应该如何解决这个问题?

另请注意,使用原始 lena.pgm 不会产生任何异常,但用其他东西替换它会产生任何异常。原始 lena.pgm 是否包含一些额外的行和列,或者我在这里遗漏了什么?

4

1 回答 1

1

原始代码依赖于 2D 纹理:

    unsigned char pix00 = tex2D(tex, (float) i-1, (float) blockIdx.x-1);
    unsigned char pix01 = tex2D(tex, (float) i+0, (float) blockIdx.x-1);
    unsigned char pix02 = tex2D(tex, (float) i+1, (float) blockIdx.x-1);
    unsigned char pix10 = tex2D(tex, (float) i-1, (float) blockIdx.x+0);
    unsigned char pix11 = tex2D(tex, (float) i+0, (float) blockIdx.x+0);
    unsigned char pix12 = tex2D(tex, (float) i+1, (float) blockIdx.x+0);
    unsigned char pix20 = tex2D(tex, (float) i-1, (float) blockIdx.x+1);
    unsigned char pix21 = tex2D(tex, (float) i+0, (float) blockIdx.x+1);
    unsigned char pix22 = tex2D(tex, (float) i+1, (float) blockIdx.x+1);

但是,纹理不是简单的数组:它们支持插值(参见这篇文章)和一些其他选项,例如cudaAddressModeClamp(如果为负索引,则越界访问 ---> 0,如果索引太大,则为最后一个,请参见另一篇文章)。

在您的代码中,如果您对简单的线性化数组使用相同的id ,除非您采取适当的预防措施,否则您(x,y)最终会访问错误的地址(x < 0和/或)。y < 0

于 2013-05-09T09:42:32.903 回答