2010-08-16 27 views
14

Me gustaría obtener algunos consejos sobre cómo realizar un análisis de imagen simple en python. Necesito calcular un valor para el "brillo" de una imagen. Sé que PIL es la biblioteca goto para hacer algo como esto. Hay una función de histograma incorporada.¿Cuáles son algunos métodos para analizar el brillo de la imagen usando Python?

Lo que necesito es un "perceived brightness" valores Puedo decidir si es necesario realizar más ajustes en la imagen. Entonces, ¿cuáles son algunas de las técnicas básicas que funcionarán en esta situación? ¿Debería simplemente trabajar con los valores RGB, o el histograma me dará algo lo suficientemente cerca?

Una posible solución podría ser combinar los dos, y generar valores R, G y B promedio utilizando el histograma, luego aplicar la fórmula de "brillo percibido".

+0

¿Qué le impide implementar el algoritmo al que se ha vinculado en Python con PIL? ¿Estás preguntando sobre un algoritmo alternativo, sobre cómo usar PIL o qué? –

+0

Solo quiero asegurarme de no perderme ninguna característica/módulo obvio que ya lo haga. Parece que este tipo de cosas ya debería existir. – cmcginty

+0

Determinar el brillo percibido en una * imagen * es radicalmente diferente que encontrar el de un color simple. Al espectador le puede interesar más el brillo del sujeto, pero normalmente hay más píxeles de fondo que píxeles subjetivos. –

Respuesta

30

Usando las técnicas mencionadas en la pregunta, se me ocurrieron algunas versiones diferentes.

Cada método devuelve un valor cercano, pero no exactamente igual que los demás. Además, todos los métodos se ejecutan aproximadamente a la misma velocidad, excepto en el último, que es mucho más lento según el tamaño de la imagen.

  1. Convierte la imagen a escala de grises, devuelve el brillo de píxel promedio.

    def brightness(im_file): 
        im = Image.open(im_file).convert('L') 
        stat = ImageStat.Stat(im) 
        return stat.mean[0] 
    
  2. Convierte la imagen a escala de grises, el retorno RMS brillo de los píxeles.

    def brightness(im_file): 
        im = Image.open(im_file).convert('L') 
        stat = ImageStat.Stat(im) 
        return stat.rms[0] 
    
  3. Promedie los píxeles, luego los transforma en "brillo percibido".

    def brightness(im_file): 
        im = Image.open(im_file) 
        stat = ImageStat.Stat(im) 
        r,g,b = stat.mean 
        return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) 
    
  4. RMS de píxeles, luego se transforman en "brillo percibido".

    def brightness(im_file): 
        im = Image.open(im_file) 
        stat = ImageStat.Stat(im) 
        r,g,b = stat.rms 
        return math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) 
    
  5. Calcular "brillo percibido" de píxeles, a continuación, volver promedio.

    def brightness(im_file): 
        im = Image.open(im_file) 
        stat = ImageStat.Stat(im) 
        gs = (math.sqrt(0.241*(r**2) + 0.691*(g**2) + 0.068*(b**2)) 
         for r,g,b in im.getdata()) 
        return sum(gs)/stat.count[0] 
    

Prueba de Actualización de resultados me encontré con una simulación frente a 200 imágenes. Encontré que los métodos # 2, # 4 dieron resultados casi idénticos. También los métodos # 3, # 5 también fueron casi idénticos. Método # 1 seguido de cerca # 3, # 5 (con algunas excepciones).

+1

Solo para comentar sobre la velocidad: en mis pruebas, tomándolas tal como son, los métodos n.º 2, n.º 3 y n.º 4 fueron aproximadamente rápidos (tomar ~ 140 ms para procesar 20 imágenes de distintos tamaños), el método n.º 1 fue solo un poco más lento (~ 180 ms) y el método n.º 5 fue realmente lento (~ 3505ms). Es de esperar, pero probablemente debería seguir con el # 3 si elige entre # 1, # 3 y # 5. –

2

Dado que solo busca un promedio en toda la imagen y no valores de brillo por píxel, promediar el histograma de PIL y aplicar la función de brillo a la salida parece ser el mejor enfoque para esa biblioteca.

Si usa ImageMagick (con las vinculaciones PythonMagick), le sugiero que utilice el comando identify con la opción "verbose" establecida. Esto le proporcionará un valor medio para cada canal, lo que le ahorrará la necesidad de sumar y promediar un histograma —, simplemente puede multiplicar cada canal directamente.

+1

Como alguien que intentó mantener PythonMagick y proporcionó la versión 0.9.1, no recomendaría su uso en su estado actual. Los cambios recientes en ImageMagick han roto un montón de código PythonMagick. El autor original del paquete surgió con otras vinculaciones python de ImageMagick, http://public.procoders.net/PythonMagickWand/docs/html/index.html, es preferible a la versión actual de PythonMagick –

1

Creo que su mejor resultado vendría de convertir el RGB a escala de grises con su fórmula favorita, y luego tomar el histograma de ese resultado. No estoy seguro de si la media o la mediana del histograma sería más apropiada, pero en la mayoría de las imágenes son probablemente similares.

No estoy seguro de cómo hacer la conversión a escala de grises en PIL usando una fórmula arbitraria, pero supongo que es posible.

+0

Suena como una buena idea. Voy a intentar eso también. – cmcginty

Cuestiones relacionadas