2017-05-12 92 views
0

一般情況:如何實現遍歷偏移並更高效地使用遍歷偏移?如何更好地實現遍歷(位)映射?

比方說,我們有一個位圖定義如下。我們如何從一個固定像素開始遍歷(在這種情況下收集)所有附近的像素 - 最終避免這8個if語句?

// The bitmap 1920x1080px 
RGBColor[][] imageMatrix = new RGBColor[1920][1080]; 

// Collect all nearby pixels that are not white 
ArrayList<RGBColor> neighboringPixels = new ArrayList<RGBColor>(); 

// Width-index of center pixel 
int w = 50; 
// Height-index of center pixel 
int h = 50; 

// Initializing offsets for a more elegant check-up... 
int[][] offsets = { { -1, -1 }, { 0, -1 }, { 1, -1 }, 
     { 1, 0 }, { 1, 1 }, { 0, 1 }, { -1, 1 }, 
     { -1, 0 } }; 

// But this is what I came up with 
// Get top-left pixel 
if (!(w - 1 < 0 || w - 1 > 255 || h - 1 < 0 || h - 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w - 1][h - 1]); 
} 
// Get top pixel 
if (!(w < 0 || w > 255 || h - 1 < 0 || h - 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w][h - 1]); 
} 
// Get top-right pixel 
if (!(w + 1 < 0 || w + 1 > 255 || h - 1 < 0 || h - 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w + 1][h - 1]); 
} 
// Get right pixel 
if (!(w + 1 < 0 || w + 1 > 255 || h < 0 || h > 255)) { 
    neighboringPixels.add(imageMatrix[w + 1][h]); 
} 
// Get bottom-right pixel 
if (!(w + 1 < 0 || w + 1 > 255 || h + 1 < 0 || h + 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w + 1][h + 1]); 
} 
// Get bottom pixel 
if (!(w < 0 || w > 255 || h + 1 < 0 || h + 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w][h + 1]); 
} 
// Get bottom-left pixel 
if (!(w - 1 < 0 || w - 1 > 255 || h + 1 < 0 || h + 1 > 255)) { 
    neighboringPixels.add(imageMatrix[w - 1][h + 1]); 
} 
// Get left pixel 
if (!(w - 1 < 0 || w - 1 > 255 || h < 0 || h > 255)) { 
    neighboringPixels.add(imageMatrix[w - 1][h]); 
} 
+0

定義「有效」?你的意思是速度或代碼行嗎? –

+0

@Lashane我主要是指一行代碼。如果我們在三維空間中工作,必須有一種方法可以避免這8個if語句,甚至是26個if語句。 – JAR

回答

-1

你迭代在一個3x3正方形:

for (int i=w-1; i<w+2; ++i) { 
    if (i<0 || i>=255) continue; 
    for (int j=h-1; j<h+3; ++j) { 
     if (j<0 || j>=255) continue; 
     if (i==w && j==h) continue; 
     neighboringPixels.add(imageMatrix[i][j]); 
    } 

寫,你可以,讓編譯器進行優化,簡單的代碼。

+1

它幾乎是正確的代碼,只是改變'if(i == 0 && j == 0)繼續;'使用w/h而不是'0' –

+0

@Lashane你是對的。 – JAR

-1

簡單:

for (int i = -1 ; i <= 1 ; i++) { 
    int wi = w + i; 
    if (wi >= 0 && wi <= 255) { 
     for (int j = -1 ; j <= 1 ; j++) { 
      int hj = h + j; 
      if (!(i == 0 && j == 0) && hj >= 0 && hj <= 255) { 
       neighboringPixels.add(imageMatrix[wj][hj]); 
      } 
     } 
    } 
} 
0

您當前的代碼包含在最壞的情況下32個條件。

在行的代碼而言更多或更少的最小解我來是這樣的:

final int minH = Math.max(0, h - 1); 
final int maxH = Math.min(255, h + 1); 
final int minW = Math.max(0, w - 1); 
final int maxW = Math.min(255, w + 1); 

for (int i = minH; i <= maxH; i++) 
    for (int j = minW; j <= maxW; j++) 
     if ((i != h) || (j != w)) 
      neighboringPixels.add(imageMatrix[i][j]); 

在最壞的情況下會有4 + 4 * 4 * 2 = 36分的條件。

在執行時間方面最少的解決方案可以是這樣的:

final int prevH = h - 1; 
final int minW = Math.max(0, w - 1); 
final int nextH = h + 1; 
final int maxW = Math.min(255, w + 1); 

if ((prevH >= 0) && (prevH <= 255)) 
    for (int i = minW; i <= maxW; i++) 
     neighboringPixels.add(imageMatrix[prevH][i]); 
if ((h >= 0) && (h <= 255)) { 
    if ((minW != w) && (minW <= 255)) 
     neighboringPixels.add(imageMatrix[h][minW]); 
    if ((maxW != w) && (maxW >= 0)) 
     neighboringPixels.add(imageMatrix[h][maxW]); 
} 
if ((nextH >= 0) && (nextH <= 255)) 
    for (int i = minW; i <= maxW; i++) 
     neighboringPixels.add(imageMatrix[nextH][i]); 

最壞情況2 + 2 + 4 + 6 + 2 + 4 = 20個條件

如進一步優化:

條件if ((a>=0) && (a<=255))可以優化到if ((a&~0xff) != 0),但它只適用於[0-255]範圍