Hace un tiempo necesitaba convertir unas imágenes que estaban en color a escalas de grises utilizando python. Buscando en internet encontré un sitio donde explicaban las fórmulas que se utilizan en el GIMP para realizar la conversión.
Estas son:
- Lightness: Método que calcula la media de los colores extremos.
- (max(R,G,B) + min(R,G,B)) / 2
- Average: Media de cada unos de los colores que componen la imagen.
- (R, G, B) / 3
- Luminosity: Media ponderada que considera la forma en que los humanos percibimos los colores.
- 0.21 R + 0.71 G + 0.07 B
La implementación es bastante sencilla y se muestra a continuación:
Para lightness:
def color2gray_lightness(image): if np.rank(image) == 3: image_gray = (np.max(image.astype(np.int), axis=2) + np.min(image.astype(np.int), axis=2)) / 2.0 elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray
Para average:
def color2gray_average(image): if np.rank(image) == 3: image_gray = np.sum(image.astype(np.int), axis=2) / 3.0 elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray
Para luminosity:
def color2gray_lightness(image): if np.rank(image) == 3: R = image[:,:,0] G = image[:,:,1] B = image[:,:,2] image_gray = 0.21*R + 0.71*G + 0.07*B elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray
Si utilizamos una imagen de prueba como esta:
El resultado será el siguiente.
Lightness
Average
Luminosity
Como se puede observar la imagen convertida en gris con el algoritmo lightness ofrece un menor contraste que los otros dos algoritmos.
La ejecución de las funciones definidas en python las he ejecutado de la siguiente manera:
import numpy as np from matplotlib.pyplot import figure, imshow, imread, gray, imsave def color2gray_average(image): if np.rank(image) == 3: image_gray = np.sum(image.astype(np.int), axis=2) / 3.0 elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray def color2gray_lightness(image): if np.rank(image) == 3: image_gray = (np.max(image.astype(np.int), axis=2) + np.min(image.astype(np.int), axis=2)) / 2.0 elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray def color2gray_luminosity(image): if np.rank(image) == 3: R = image[:,:,0] G = image[:,:,1] B = image[:,:,2] image_gray = 0.21*R + 0.71*G + 0.07*B elif np.rank(image) == 2: image_gray = image else: raise NameError('The image isnt gray or color.') return image_gray #This function invert the image. The function imread read image like a matrix. def invert_image(image): if np.rank(image) == 3: image = image[::-1, :, :] elif np.rank(image) == 2: image = image[::-1, :] else: raise NameError('The image isnt gray or color.') return image if __name__ == '__main__': #Read image from disk image = imread('/home/mydirectory/atacama-flora99.jpg') img = color2gray_average(image) img = invert_image(img) gray() imshow(img)
Referencias:
- http://www.welcomechile.com/antofagasta/
- http://www.johndcook.com/blog/2009/08/24/algorithms-convert-color-grayscale/
- http://elviajehaciael2012.forochile.org/t1571-desierto-florido-atacama-chile
Comentarios
Y = 0.3R + 0.59G + 0.11B