2012-05-10 20 views

Antwort

7

in Java Iterierte auf jedem Pixel und bestimmen Farbe

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

Ebene mit Hilfe von Java können Sie einfach über jedes Pixel durchlaufen und zählen, wie oft jede Farbe enthalten ist ...

Pseudo-Code:

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

vorausgesetzt, Sie verwenden additive Farbschema, wobei (0,0,0) ist schwarz und (255, 255, 255) ist weiß (korrigieren Sie mich, wenn ich mich irre). Auch wenn Sie nur die dominante Farbe aus RGB finden wollen:

Eine Idee, die ich habe, die jeder von euch frei zu hinterfragen ist, hat 3 Variablen, die jeweils einen der RGB-Werte speichern und zu jedem hinzufügen Geben Sie den entsprechenden Wert für jedes Pixel im Bild ein und dividieren Sie dann durch (255 * numOfPixels), um ein Farbverhältnis zu erhalten. Dann vergleiche die 3 Verhältnisse: .60 für Rot und .5 für Grün bedeutet, dass Rot dominanter ist.

Dies ist nur eine Idee und könnte zwicken müssen ...

+0

ich benutzte jamagick für die Farbe als RGB-Typ verwendet wird, aber auf diese Weise kann ich nur durchschnittliche Bildgröße finden. Aber ich habe eine Idee, ich kann Bild der Mitte zuschneiden, also kann ich durchschnittliche Farbe dieses Teils finden, es wird fast dieselbe Farbe wieder geben. Ich finde nur dominante Farbe:/ –

+0

@ ErçinAkçay Wenn Sie das Bild zuschneiden möchten, möchten Sie sicherlich die Hauptfarbe an den Rändern. z.B. sagen Sie, Sie haben ein großes Quadrat, das von Weiß umgeben ist. Sie möchten die Farbe des Weiß erkennen, um das zu schneiden, nicht das Quadrat. –

4

Dies ist ein heikles Problem. Zum Beispiel, wenn Sie eine kleine Fläche mit genau der gleichen Farbe und eine große Fläche von etwas anderen Schattierungen einer anderen Farbe haben, dann ist es wahrscheinlich unwahrscheinlich, dass Sie nur nach der Farbe suchen, die am meisten verwendet wird, um Ihnen das gewünschte Ergebnis zu geben. Sie würden ein besseres Ergebnis erzielen, wenn Sie eine Reihe von Farben und für jeden Bereich die RGB-Werte definieren, die Sie für diese Farbe halten.

Dieses Thema wird ausführlich auf dem ImageMagick Diskurs Server diskutiert, zum Beispiel: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

Siehe auch Fast way of getting the dominant color of an image

6

ich nur einen sehr einfachen Algorithmus veröffentlicht, die trivialerweise in Java übersetzt werden kann. Es heißt color-finder und funktioniert in JavaScript.

Die vorgeschlagenen Lösungen in diesem Thread kann durch ein paar weiße Zeichen im Bild abgeworfen werden, während meins wirklich versucht, die prominenteste Farbe zu finden, auch wenn alle Pixel nicht wirklich genau die gleiche Farbe haben.

Here is a live demo.

Lassen Sie mich wissen, wenn Sie das nützlich finden.

1

In anderer Weise können wir diesen Job mit Color Thief-Bibliothek erledigen. Weitere Informationen finden Sie unter here und here.

Kredit an @svenwoltmann und @lokeshdhakar.

Verwandte Themen