2010-05-31 129 views
0

我迭代一个3维阵列(这是与用于每个像素3个值的图像),以3×3滤波器应用于各像素,如下所示:多维阵列边缘/边界条件

//For each value on the image  
for (i=0;i<3*width*height;i++){ 
    //For each filter value 
    for (j=0;j<9;j++){ 
     if (notOutsideEdgesCondition){ 
      *(**(outArray)+i)+= *(**(pixelArray)+i-1+(j%3)) * (*(filter+j)); 
     } 
    } 
} 

我正在使用指针算术,因为如果我使用数组符号,我会有4个循环,并且我尝试尽可能少地使用循环。我的问题是我的notOutsideEdgesCondition已经完全失控,因为我必须考虑8个边界情况。我有以下处理条件

  • 左路军:((i%width)==0) && (j%3==0)
  • 右栏:((i-1)%width ==0) && (i>1) && (j%3==2)
  • 上排:(i<width) && (j<2)
  • 下排: (i>(width*height-width)) && (j>5)

还是要考虑4个角落案件将有更长的表达。在这一点上,我停下来问自己这是否是最好的方法,因为如果我有一个5行长的条件评估,它不仅会让调试变得非常痛苦,而且会减慢内部循环。这就是为什么我来问你是否有一个已知的算法来处理这种情况,或者如果有更好的方法来解决我的问题。非常感谢。

回答

1

是的,有一个更好的方法。编写一个快速循环来处理确保没有边界问题的情况。这将包括从第二列到倒数第二列的区域和第二到倒数第二行的区域。然后,您可以编写四个例程来处理每个边(第0行,第0列,第N行和第N列),您可以手动编写最后四个点。

也就是说,你正在做的寻址计算也有很多更快的方法。

+0

I我会尝试一下,它会需要更多的编码,但希望我可以使它更简单。另外,您是否可以指出我正确的方向来使寻址计算更快? – kirbuchi 2010-05-31 06:57:22

+0

我做了一个快速谷歌试图找到一个关于展开阵列寻址计算的教程,但没有找到一个。 简而言之,应避免尽可能多的按像素寻址计算。使用一个指针,当你工作时,它会逐个像素地递增,并且移除所有的模运算和乘法运算。 为了实现你的3x3内核寻址,你应该保持3个指针(每行一个到你当前的地方)或者一个指针和一个常量'stride'(行之间的位移)被加入。使用多个循环来知道什么时候添加/减去步幅。 当。没有更多的字符 – swestrup 2010-05-31 19:26:43

+0

好,所以现在我已经处理了4个侧边的情况,并且会手工编码角落情况。内核的3指针方法似乎是最好的,因为在解决边界情况时,我可以单独禁用每个内核行。考虑到这一点,我可以与图像阵列类似地进行处理,并将它们分开以便稍后进行CUDA实现,这是我的最终目标。非常感谢。 PS:我会寻找一本关于数组展开和寻址优化的书籍或教程。 – kirbuchi 2010-06-01 04:48:11

0

一个很好的提示是在数组的顶部添加一行,另一行在结尾(对列执行相同的操作)。

这些附加行/列不会包含任何信息,但它们将缓解计算(无边界情况)。在消耗更多的内存的价格...

只是一个想法:)

+0

我认为它不会占用太多的内存。我可以试一试 – kirbuchi 2010-05-31 07:02:05

+0

在整个阵列周围添加一个边界行将会起作用,但涉及拷贝数组,这可能不是最有效的方法(可能再次,这可能取决于您的处理器缓存策略。) – swestrup 2010-05-31 19:29:44