para - ¿Cómo puedo convertir una imagen RGB en escala de grises en Python?
opencv python escala de grises (11)
¿Qué tal si lo haces con Pillow ?
from PIL import Image
img = Image.open(''image.png'').convert(''LA'')
img.save(''greyscale.png'')
Usando matplotlib y la fórmula
Y'' = 0.299 R + 0.587 G + 0.114 B
Podrías hacerlo:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])
img = mpimg.imread(''image.png'')
gray = rgb2gray(img)
plt.imshow(gray, cmap = plt.get_cmap(''gray''))
plt.show()
Estoy tratando de usar matplotlib
para leer en una imagen RGB y convertirla a escala de grises.
En matlab utilizo 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 por lo que yo entiendo.
lum_img = img[:,:,0]
Encuentro difícil de 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 la incorporada.
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
El tutorial es una trampa porque está comenzando con una imagen en escala de grises codificada en RGB, por lo que solo están cortando un solo canal de color y tratándolo como escala de grises. Los pasos básicos que debe seguir son transformar el espacio de color RGB en un espacio de color que codifica algo similar al modelo luma / croma, como YUV / YIQ o HSL / HSV, luego cortar el canal tipo luma y usarlo como su imagen en escala de grises matplotlib
no parece proporcionar un mecanismo para convertir a YUV / YIQ, pero sí le permite convertir a HSV.
Intente usar matplotlib.colors.rgb_to_hsv(img)
luego corte el último valor (V) de la matriz para su escala de grises. No es lo mismo que un valor de luma, pero significa que puedes hacerlo todo en matplotlib
.
Fondo:
Alternativamente, podría usar PIL o los colorsys.rgb_to_yiq()
incorporadosys.rgb_to_yiq colorsys.rgb_to_yiq()
para convertir a un espacio de color con un verdadero valor de luma. También podría ir all-in y rodar su propio convertidor solo de luma, aunque eso probablemente sea excesivo.
La forma más rápida y actual es usar Pillow , instalado a través de pip install Pillow
.
El código es entonces:
from PIL import Image
img = Image.open(''input_file.jpg'').convert(''L'')
img.save(''output_file.jpg'')
Llegué a esta pregunta a través de Google, en busca de una forma de convertir una imagen ya cargada a escala de grises.
Aquí hay una manera de hacerlo con SciPy:
import scipy.misc
import scipy.ndimage
# Load an example image
# Use scipy.ndimage.imread(file_name, mode=''L'') if you have your own
img = scipy.misc.face()
# Convert the image
R = img[:, :, 0]
G = img[:, :, 1]
B = img[:, :, 2]
img_gray = R * 299. / 1000 + G * 587. / 1000 + B * 114. / 1000
# Show the image
scipy.misc.imshow(img_gray)
Podrías hacerlo:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def rgb_to_gray(img):
grayImage = np.zeros(img.shape)
R = np.array(img[:, :, 0])
G = np.array(img[:, :, 1])
B = np.array(img[:, :, 2])
R = (R *.299)
G = (G *.587)
B = (B *.114)
Avg = (R+G+B)
grayImage = img
for i in range(3):
grayImage[:,:,i] = Avg
return grayImage
image = mpimg.imread("your_image.png")
grayImage = rgb_to_gray(image)
plt.imshow(grayImage)
plt.show()
Si está usando NumPy / SciPy ya, también puede usar :
scipy.ndimage.imread(file_name, mode=''L'')
Hth, dtk
Siempre puede leer el archivo de imagen en escala de grises desde el principio usando imread
desde OpenCV:
img = cv2.imread(''messi5.jpg'', 0)
Además, en caso de que quiera leer la imagen como RGB, hacer algún procesamiento y luego convertirla a escala de grises, podría usar cvtcolor
desde OpenCV:
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
También puede usar scikit-image , que proporciona algunas funciones para convertir una imagen en ndarray
, como rgb2gray
.
from skimage import color
from skimage import io
img = color.rgb2gray(io.imread(''image.png''))
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 imágenes en escala de grises de la siguiente manera:
from skimage import io
img = io.imread(''image.png'', as_grey=True)
Tres de los métodos sugeridos se probaron para determinar la velocidad con 1000 imágenes RGBA PNG (224 x 256 píxeles) ejecutándose con Python 3.5 en Ubuntu 16.04 LTS (Xeon E5 2670 con SSD).
Promedio de tiempos de ejecución
pil :
1.037 segundos
scipy:
1.040 segundos
sk :
2.120 segundos
PIL y SciPy dieron matrices numpy
idénticas (que van de 0 a 255). SkImage proporciona matrices de 0 a 1. Además, los colores se convierten ligeramente diferentes, vea el ejemplo del conjunto de datos CUB-200.
Código
Actuación
run_times = dict(sk=list(), pil=list(), scipy=list()) for t in range(100): start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = skimage.color.rgb2gray(skimage.io.imread(z)) run_times[''sk''].append(time.time() - start_time)
start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = np.array(Image.open(z).convert(''L'')) run_times[''pil''].append(time.time() - start_time) start_time = time.time() for i in range(1000): z = random.choice(filenames_png) img = scipy.ndimage.imread(z, mode=''L'') run_times[''scipy''].append(time.time() - start_time)
para k, v en run_times.items (): print (''{: 5}: {: 0.3f} segundos''.formato (k, suma (v) / len (v)))
- Salida
z = ''Cardinal_0007_3025810472.jpg'' img1 = skimage.color.rgb2gray(skimage.io.imread(z)) * 255 IPython.display.display(PIL.Image.fromarray(img1).convert(''RGB'')) img2 = np.array(Image.open(z).convert(''L'')) IPython.display.display(PIL.Image.fromarray(img2)) img3 = scipy.ndimage.imread(z, mode=''L'') IPython.display.display(PIL.Image.fromarray(img3))
- Comparación
img_diff = np.ndarray(shape=img1.shape, dtype=''float32'') img_diff.fill(128) img_diff += (img1 - img3) img_diff -= img_diff.min() img_diff *= (255/img_diff.max()) IPython.display.display(PIL.Image.fromarray(img_diff).convert(''RGB''))
- Importaciones
import skimage.color import skimage.io import random import time from PIL import Image import numpy as np import scipy.ndimage import IPython.display
- Versiones
skimage.version 0.13.0 scipy.version 0.19.1 np.version 1.13.1
Use img.Convert (), admite el modo "L", "RGB" y "CMYK".
import numpy as np
from PIL import Image
img = Image.open("IMG/center_2018_02_03_00_34_32_784.jpg")
img.convert(''L'')
print np.array(img)
Salida:
[[135 123 134 ..., 30 3 14]
[137 130 137 ..., 9 20 13]
[170 177 183 ..., 14 10 250]
...,
[112 99 91 ..., 90 88 80]
[ 95 103 111 ..., 102 85 103]
[112 96 86 ..., 182 148 114]]
image=myCamera.getImage().crop(xx,xx,xx,xx).scale(xx,xx).greyscale()
Puede usar greyscale()
directamente para la transformación.