2010-05-31 86 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