2017-05-12 1 views
0

En général: Comment les décalages transversaux peuvent-ils être implémentés et utilisés plus efficacement?Comment la traversée d'une carte (bit-) peut-elle être mise en œuvre de manière plus élégante?

Disons que nous avons un bitmap défini ci-dessous. Comment pourrions-nous traverser (dans ce cas collecter) tous les pixels proches à partir d'un pixel fixe - et finalement éviter ces 8 if-déclarations?

// 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

définir "efficace"? voulez-vous dire la vitesse ou les lignes de code? –

+0

@Lashane I signifie principalement seulement des lignes de code. Il doit y avoir un moyen d'éviter ces 8 affirmations ou même si nous devrions travailler dans une salle en trois dimensions. – JAR

Répondre

-1

Vous itérez sur un carré 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]); 
    } 

écrire le code aussi simple que vous le pouvez et laisser le compilateur faire l'optimisation.

+1

c'est presque le code correct, il suffit de changer 'if (i == 0 && j == 0) continuer;' utiliser w/h au lieu de '0' –

+0

@Lashane Vous avez raison. – JAR

-1

simplement:

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

Vous code actuel contient 32 conditions dans le pire des cas.

solution plus ou moins minimale en termes de lignes de code je viens est comme ceci:

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]); 

Dans le pire des cas, il y aura 4 + 4 * 4 * 2 = 36 conditions.

solution minimale en termes de temps d'exécution pourrait ressembler à ceci:

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]); 

pire des cas 2 + 2 + 4 + 6 + 2 + 4 = 20 conditions

Comme une optimisation plus poussée:

Condition if ((a>=0) && (a<=255)) pourrait être optimisé à if ((a&~0xff) != 0) mais cela ne fonctionne que pour [0-255] gamme