2012-05-10 11 views

Respuesta

7

en iterate java en cada píxel y determinar el color

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

Utilización de Java normal sólo puede iterar sobre cada píxel y contar con qué frecuencia se contiene cada color ...

pseudo-código:

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

asumiendo que usa un esquema de color aditivo, donde (0,0,0) es negro y (255, 255, 255) es blanco (corríjame si me equivoco). Además, si solo quiere encontrar el color dominante de RGB:

Una idea que tengo, que cualquiera de ustedes es libre de examinar es tener 3 variables que almacenan cada uno de los valores RGB y agregar a cada uno de ellos el valor apropiado de cada píxel en la imagen y luego divida por (255 * numOfPixels) para obtener una proporción de color. Luego compare las 3 proporciones: .60 para rojo y .5 para verde significaría que el rojo es más dominante.

Esto es sólo una idea, y puede ser que necesite ajustar ...

+0

utilicé jamagick para qué color se usa como tipo RGB pero de esta manera solo puedo encontrar el clor de imagen de avarage. Pero tengo una idea de que puedo recortar la imagen del medio para que pueda encontrar el color aproximado de esa parte, dará casi el mismo color otra vez. Solo encuentro el color dominante:/ –

+0

@ ErçinAkçay Si quieres recortar la imagen, seguramente querrás el color principal en los bordes. p.ej. di que tienes un cuadrado grande rodeado de blanco. Desea detectar el color del blanco para recortarlo, no el cuadrado. –

4

Este es un problema difícil. Por ejemplo, si tiene un área pequeña de exactamente el mismo color y una gran área de tonos ligeramente diferentes de un color diferente, entonces simplemente buscando el color que más se usa es poco probable que le dé el resultado que desea. Obtendrá un mejor resultado definiendo un conjunto de colores y, para cada uno, los rangos de valores RGB que considere que "son" de ese color.

Este tema se analiza en profundidad en el servidor discurso ImageMagick, por ejemplo: http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=12878

Ver también Fast way of getting the dominant color of an image

6

Me acaba de lanzar un algoritmo muy simple que se puede traducir en Java trivial. Se llama color-finder y funciona en JavaScript.

Las soluciones propuestas en este hilo pueden ser descartadas por unos pocos caracteres blancos en la imagen, mientras que la mía realmente trata de encontrar el color más prominente, incluso si todos los píxeles no son exactamente del mismo color.

Here is a live demo.

Avísame si te parece útil.

1

De otra manera, podemos hacer este trabajo con la biblioteca Color Thief. Se puede encontrar más información en here y here.

Gracias a @svenwoltmann y @lokeshdhakar.

Cuestiones relacionadas