¿Cuáles son algunos métodos para analizar el brillo de la imagen usando Python?

Me gustaría un consejo 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 de goto para hacer algo como esto. Hay una función de histogtwig incorporada.

Lo que necesito es un valor de “brillo percibido” que puedo decidir si se necesitan ajustes adicionales a la imagen. Entonces, ¿cuáles son algunas de las técnicas básicas que funcionarán en esta situación? ¿Debo trabajar con los valores RGB o el histogtwig me dará algo lo suficientemente cerca?

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

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

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

  1. Convierta la imagen a escala de grises, devuelva el brillo promedio de píxeles.

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

     def brightness( im_file ): im = Image.open(im_file).convert('L') stat = ImageStat.Stat(im) return stat.rms[0] 
  3. Promedio de píxeles, luego se transforma a “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 transforma 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. Calcule el “brillo percibido” de los píxeles, luego regrese el 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] 

Actualizar los resultados de la prueba Corrí una simulación contra 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. El método # 1 siguió de cerca al # 3, # 5 (con algunas excepciones).

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

Si utilizo ImageMagick (con los enlaces de PythonMagick ), sugeriría usar el comando de identificación con el conjunto de opciones “detallado”. Esto le proporcionará un valor medio para cada canal, lo que le ahorrará la necesidad de sumr y promediar un histogtwig; simplemente puede multiplicar cada canal directamente.

Creo que su mejor resultado provendría de convertir el RGB a escala de grises con su fórmula favorita y luego tomar el histogtwig de ese resultado. No estoy seguro de si la media o la mediana del histogtwig serían más apropiadas, pero en la mayoría de las imágenes probablemente sean 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.