Estoy tratando de usar matplotlib
para leer una imagen RGB y convertirla a escala de grises.
En matlab uso esto:
img = rgb2gray(imread('image.png'));
En el tutorial matplotlib no lo cubren. Acaban de leer en la imagen
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
y luego cortan la matriz, pero eso no es lo mismo que convertir RGB a escala de grises de lo que entiendo.
lum_img = img[:,:,0]
Me resulta difícil creer que numpy o matplotlib no tengan una función incorporada para convertir de rgb a gris. ¿No es esta una operación común en el procesamiento de imágenes?
Escribí una función muy simple que funciona con la imagen importada usando imread
en 5 minutos. Es terriblemente ineficiente, pero es por eso que esperaba una implementación profesional integrada.
Sebastian ha mejorado mi función, pero todavía espero encontrar el integrado.
Implementación de matlab (NTSC / PAL):
import numpy as np
def rgb2gray(rgb):
r, g, b = rgb[:,:,0], rgb[:,:,1], rgb[:,:,2]
gray = 0.2989 * r + 0.5870 * g + 0.1140 * b
return gray
fuente
gray = np.mean(rgb, -1)
. Tal vezrgb[...,:3]
allí si en realidad es rgba.gray = np.mean(rgb, -1)
funciona bien Gracias. ¿Hay alguna razón para no usar esto? ¿Por qué usaría las soluciones en las respuestas a continuación?np.mean(rgb, -1)
.0.2989 * R + 0.5870 * G + 0.1140 * B
Supongo que es la forma estándar de hacerlo.Respuestas:
¿Qué tal hacerlo con Pillow :
Usando matplotlib y la fórmula
Podrías hacerlo:
fuente
matplotlib
por alguna otra razón, debería poder usar el builtincolorsys.rgb_to_yiq()
para transformar más un corte para obtener solo el canal luma..convert('LA')
? ¿por qué no.convert('gray')
? Parece innecesariamente críptico. La documentación PIL no menciona nada sobre 'LA' para la función de conversión.cannot write mode LA as JPEG
necesitaba usar el modo L, no LAimg = Image.open('image.png').convert('LA')
tiene que serimg = Image.open('image.png').convert('L')
LA
modo tiene luminosidad (brillo) y alfa. Si usa elLA
modo,greyscale.png
será una imagen RGBA con el canal alfa deimage.png
preservado. Si usa elL
modo,greyscale.png
será una imagen RGB (sin alfa).También puede usar scikit-image , que proporciona algunas funciones para convertir una imagen
ndarray
, comorgb2gray
.Notas : Los pesos utilizados en esta conversión están calibrados para fósforos CRT contemporáneos: Y = 0.2125 R + 0.7154 G + 0.0721 B
Alternativamente, puede leer la imagen en escala de grises de la siguiente manera:
fuente
cmap
comogray' then only the image is shown as gray in
pyplot.imshow () `? Alguna idea ? Donde me equivocoSe probó la velocidad de tres de los métodos sugeridos con 1000 imágenes PNG RGBA (224 x 256 píxeles) ejecutándose con Python 3.5 en Ubuntu 16.04 LTS (Xeon E5 2670 con SSD).
Tiempos de ejecución promedio
pil :
1.037 segundosscipy:
1.040 segundossk :
2.120 segundosPIL y SciPy dieron
numpy
matrices idénticas (que van de 0 a 255). SkImage proporciona matrices de 0 a 1. Además, los colores se convierten ligeramente diferentes, consulte el ejemplo del conjunto de datos CUB-200.SkImage:
PIL :
SciPy :
Original:
Diff :
Código
Actuación
fuente
Siempre puede leer el archivo de imagen como escala de grises desde el principio utilizando
imread
OpenCV:Además, en caso de que desee leer la imagen como RGB, realice un procesamiento y luego conviértalo a Escala de grises que podría usar
cvtcolor
desde OpenCV:fuente
0
bandera escv2.CV_LOAD_IMAGE_GRAYSCALE
.La forma más rápida y actual es usar Pillow , instalado a través de
pip install Pillow
.El código es entonces:
fuente
convert
devuelve una copia convertida de la imagenEl tutorial es engañoso porque comienza con una imagen en escala de grises codificada en RGB, por lo que solo cortan un solo canal de color y lo tratan como escala de grises. Los pasos básicos que debe hacer son transformar del espacio de color RGB a un espacio de color que codifique con algo que se aproxime al modelo luma / croma, como YUV / YIQ o HSL / HSV, luego corte el canal similar a luma y úselo como tu imagen en escala de grises.
matplotlib
no parece proporcionar un mecanismo para convertir a YUV / YIQ, pero le permite convertir a HSV.Intente usar y
matplotlib.colors.rgb_to_hsv(img)
luego cortar el último valor (V) de la matriz para su escala de grises. No es lo mismo que un valor de luma, pero significa que puede hacerlo todomatplotlib
.Antecedentes:
Alternativamente, puede usar PIL o el incorporado
colorsys.rgb_to_yiq()
para convertir a un espacio de color con un verdadero valor de luma. También podrías entrar y rodar tu propio convertidor solo de luma, aunque eso probablemente sea exagerado.fuente
Usando esta fórmula
Podemos hacer
Sin embargo, el software de conversión de color GIMP a imagen en escala de grises tiene tres algoritmos para realizar la tarea.
fuente
Si ya estás usando NumPy / SciPy, también puedes usar :
scipy.ndimage.imread(file_name, mode='L')
fuente
scipy.ndimage.imread()
yscipy.misc.imread()
están formalmente en desuso en SciPy 1.0.0 y se eliminarán permanentemente en SciPy 1.2.0. Si bien la documentación de SciPy recomiendaimageio.imread()
como un reemplazo adecuado, la API de esta función es básica hasta el punto de lo absurdo. Proporciona sin soporte para la conversión de escala de grises y por lo tanto sigue siendo inadecuada para muchas aplicaciones - incluyendo el nuestro.</sigh>
Podrías hacerlo:
fuente
Use img.Convert (), admite "L", "RGB" y "CMYK". modo
Salida:
fuente
img = img.convert('L')
?Llegué a esta pregunta a través de Google, buscando una forma de convertir una imagen ya cargada en escala de grises.
Aquí hay una manera de hacerlo con SciPy:
fuente
img_gray = numpy.average(img, weights=[0.299, 0.587, 0.114], axis=2)
numpy.average
es un poco más rápido pero no prácticamente diferente. Su solución es clara y tiene información relevante sobre R, G, B, por lo que la conservaría. Mi comentario fue más una opción adicional, no un reemplazo.scipy.ndimage.imread()
yscipy.misc.imread()
están formalmente en desuso en SciPy 1.0.0 y se eliminarán permanentemente en SciPy 1.2.0. Probablemente solo desee utilizar el soporte de conversión de escala de grises incorporado de Pillow ( la respuesta de ala unutbu ), en su lugar.Puede usar
greyscale()
directamente para la transformación.fuente