2012-05-10 13 views

risposta

7

in java iterare su ogni pixel e determinare il colore

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
import javax.imageio.ImageIO; 
import javax.imageio.ImageReader; 
import javax.imageio.stream.ImageInputStream; 


public class ImageTester { 


    public static void main(String args[]) throws Exception { 
     File file = new File("C:\\Users\\Andrew\\Desktop\\myImage.gif"); 
     ImageInputStream is = ImageIO.createImageInputStream(file); 
     Iterator iter = ImageIO.getImageReaders(is); 

     if (!iter.hasNext()) 
     { 
      System.out.println("Cannot load the specified file "+ file); 
      System.exit(1); 
     } 
     ImageReader imageReader = (ImageReader)iter.next(); 
     imageReader.setInput(is); 

     BufferedImage image = imageReader.read(0); 

     int height = image.getHeight(); 
     int width = image.getWidth(); 

     Map m = new HashMap(); 
     for(int i=0; i < width ; i++) 
     { 
      for(int j=0; j < height ; j++) 
      { 
       int rgb = image.getRGB(i, j); 
       int[] rgbArr = getRGBArr(rgb);     
       // Filter out grays....     
       if (!isGray(rgbArr)) {     
         Integer counter = (Integer) m.get(rgb); 
         if (counter == null) 
          counter = 0; 
         counter++;         
         m.put(rgb, counter);     
       }     
      } 
     }   
     String colourHex = getMostCommonColour(m); 
     System.out.println(colourHex); 
    } 


    public static String getMostCommonColour(Map map) { 
     List list = new LinkedList(map.entrySet()); 
     Collections.sort(list, new Comparator() { 
       public int compare(Object o1, Object o2) { 
       return ((Comparable) ((Map.Entry) (o1)).getValue()) 
        .compareTo(((Map.Entry) (o2)).getValue()); 
       } 
     });  
     Map.Entry me = (Map.Entry)list.get(list.size()-1); 
     int[] rgb= getRGBArr((Integer)me.getKey()); 
     return Integer.toHexString(rgb[0])+" "+Integer.toHexString(rgb[1])+" "+Integer.toHexString(rgb[2]);   
    }  

    public static int[] getRGBArr(int pixel) { 
     int alpha = (pixel >> 24) & 0xff; 
     int red = (pixel >> 16) & 0xff; 
     int green = (pixel >> 8) & 0xff; 
     int blue = (pixel) & 0xff; 
     return new int[]{red,green,blue}; 

    } 
    public static boolean isGray(int[] rgbArr) { 
     int rgDiff = rgbArr[0] - rgbArr[1]; 
     int rbDiff = rgbArr[0] - rgbArr[2]; 
     // Filter out black, white and grays...... (tolerance within 10 pixels) 
     int tolerance = 10; 
     if (rgDiff > tolerance || rgDiff < -tolerance) 
      if (rbDiff > tolerance || rbDiff < -tolerance) { 
       return false; 
      }     
     return true; 
    } 
} 
1

utilizzando Java pianura si può semplicemente iterare su ogni pixel e contare quante volte ogni colore è contenuto ...

pseudo-codice:

Map<Color, Integer> color2counter; 
for (x : width) { 
    for (y : height) { 
     color = image.getPixel(x, y) 
     occurrences = color2counter.get(color) 
     color2counter.put(color, occurrences + 1) 
    } 
} 
0

assumendo l'uso di combinazioni di colori additivi, dove (0,0,0) è nero e (255, 255, 255) è bianco (correggimi se mi sbaglio). Inoltre, se vuoi solo trovare il colore dominante di RGB:

Un'idea che ho, che ognuno di voi è libero di esaminare è di avere 3 variabili che memorizzano ciascuno uno dei valori RGB e aggiungono a ciascuno di loro il valore appropriato di ogni pixel nell'immagine e quindi dividi per (255 * numOfPixels) per ottenere un rapporto di colore. Quindi confrontare i 3 rapporti: 0,6 per il rosso e 0,5 per il verde significherebbe che il rosso è più dominante.

Questa è solo un'idea, e potrebbe essere necessario tweaking ...

+0

ho usato jamagick per il quale il colore è usato come tipo RGB ma con questo modo posso solo trovare il colore medio dell'immagine. Ma ho un'idea di poter ritagliare l'immagine di mezzo in modo da poter trovare il colore avarage di quella parte che darà di nuovo quasi lo stesso colore. Trovo solo il colore dominante:/ –

+0

@ ErçinAkçay Se vuoi ritagliare l'immagine, sicuramente vuoi il colore principale ai bordi. per esempio. dì che hai una grande piazza circondata dal bianco. Vuoi rilevare il colore del bianco per ritagliarlo, non il quadrato. –

4

Questo è un problema difficile. Ad esempio, se si dispone di una piccola area di esattamente lo stesso colore e una vasta area di tonalità leggermente diverse di un colore diverso, è improbabile che la ricerca del colore che viene utilizzato di più sia in grado di fornire il risultato desiderato. Otterrai un risultato migliore definendo un set di colori e, per ciascuno, gli intervalli di valori RGB che consideri essere "quel colore".

Questo argomento è discusso a lungo sul server discorso ImageMagick, ad esempio: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

Vedi anche Fast way of getting the dominant color of an image

6

Ho appena rilasciato un algoritmo molto semplice che può essere tradotto in Java banalmente. Si chiama color-finder e funziona in JavaScript.

Le soluzioni proposte in questo thread possono essere eliminate da alcuni caratteri bianchi nell'immagine, mentre il mio cerca davvero di trovare il colore più evidente, anche se tutti i pixel non sono esattamente dello stesso colore.

Here is a live demo.

Fammi sapere se lo trovi utile.

1

In altro modo, possiamo fare questo lavoro con la libreria Color Thief. Ulteriori informazioni possono essere trovate here e here.

Credito a @svenwoltmann e @lokeshdhakar.

Problemi correlati