J'essaie d'utiliser matplotlib
pour lire une image RVB et la convertir en niveaux de gris.
Dans matlab, j'utilise ceci:
img = rgb2gray(imread('image.png'));
Dans le tutoriel matplotlib , ils ne le couvrent pas. Ils viennent de lire dans l'image
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
et puis ils coupent le tableau, mais ce n'est pas la même chose que convertir RVB en niveaux de gris d'après ce que j'ai compris.
lum_img = img[:,:,0]
J'ai du mal à croire que numpy ou matplotlib n’ait pas de fonction intégrée permettant de convertir de rgb en gris. N'est-ce pas une opération courante dans le traitement d'images?
J'ai écrit une fonction très simple qui fonctionne avec l'image importée avec imread
en 5 minutes. C'est horriblement inefficace, mais c'est pourquoi j'espérais une implémentation professionnelle intégrée.
Sebastian a amélioré ma fonction, mais j'espère toujours trouver celui qui est intégré.
mise en œuvre 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
Pourquoi ne pas le faire avec Pillow :
from PIL import Image
img = Image.open('image.png').convert('LA')
img.save('greyscale.png')
Utiliser matplotlib et la formule
Y' = 0.2989 R + 0.5870 G + 0.1140 B
vous pourriez faire:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
def rgb2gray(rgb):
return np.dot(rgb[...,:3], [0.2989, 0.5870, 0.1140])
img = mpimg.imread('image.png')
gray = rgb2gray(img)
plt.imshow(gray, cmap=plt.get_cmap('gray'), vmin=0, vmax=1)
plt.show()
Vous pouvez également utiliser scikit-image , qui fournit certaines fonctions pour convertir une image en ndarray
, comme rgb2gray
.
from skimage import color
from skimage import io
img = color.rgb2gray(io.imread('image.png'))
Remarques : Les poids utilisés dans cette conversion sont étalonnés pour les luminophores CRT contemporains: Y = 0,2125 R + 0,7154 G + 0,0721 B
Alternativement, vous pouvez lire une image en niveaux de gris en:
from skimage import io
img = io.imread('image.png', as_gray=True)
Trois des méthodes suggérées ont été testées en termes de vitesse avec 1000 images PNG RGBA (224 x 256 pixels) exécutées avec Python 3.5 sur Ubuntu 16.04 LTS (Xeon E5 2670 avec SSD).
Temps moyens d'exécution
pil :
1.037 secondes
scipy:
1.040 secondes
sk :
2.120 secondes
PIL et SciPy ont donné des tableaux numpy
identiques (allant de 0 à 255). SkImage donne les tableaux de 0 à 1. De plus, les couleurs sont converties légèrement différentes, voir l'exemple du jeu de données CUB-200.
Code
Performance
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)
</ code>
pour k, v dans run_times.items (): print ('{: 5}: {: 0.3f} seconds'.format (k, sum (v)/len (v)))
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))
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'))
import skimage.color
import skimage.io
import random
import time
from PIL import Image
import numpy as np
import scipy.ndimage
import IPython.display
skimage.version
0.13.0
scipy.version
0.19.1
np.version
1.13.1
Vous pouvez toujours lire le fichier image en niveaux de gris dès le début en utilisant imread
à partir de OpenCV:
img = cv2.imread('messi5.jpg', 0)
De plus, si vous souhaitez lire l’image en RVB, effectuez un traitement, puis convertissez-la en échelle de gris que vous pouvez utiliser cvtcolor
à partir d’OpenCV:
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
La méthode la plus rapide et la plus courante consiste à utiliser Oreiller , installé via pip install Pillow
.
Le code est alors:
from PIL import Image
img = Image.open('input_file.jpg').convert('L')
img.save('output_file.jpg')
Le didacticiel est une triche, car il commence par une image en niveaux de gris encodée en RVB. Ils découpent donc un seul canal de couleur et le traitent en niveaux de gris. Les étapes de base que vous devez faire sont de passer de l’espace colorimétrique RVB à un espace colorimétrique codant avec un élément proche du modèle luma/chroma, tel que YUV/YIQ ou HSL/HSV, puis de découper le canal en forme de luma et de l’utiliser comme votre image en niveaux de gris. matplotlib
ne semble pas fournir de mécanisme pour convertir en YUV/YIQ, mais vous permet de convertir en HSV.
Essayez d'utiliser matplotlib.colors.rgb_to_hsv(img)
puis découpez la dernière valeur (V) du tableau pour votre échelle de gris. Ce n'est pas tout à fait la même chose qu'une valeur de luma, mais cela signifie que vous pouvez tout faire en matplotlib
.
Contexte:
Vous pouvez également utiliser PIL ou la fonction intégrée colorsys.rgb_to_yiq()
pour convertir un espace colorimétrique avec une valeur de luminosité réelle. Vous pouvez également vous lancer et lancer votre propre convertisseur de luminance seule, bien que ce soit probablement excessif.
Si vous utilisez déjà NumPy/SciPy, vous pouvez tiliser également :
scipy.ndimage.imread(file_name, mode='L')
Utiliser cette formule
Y' = 0.299 R + 0.587 G + 0.114 B
Nous pouvons faire
import imageio
import numpy as np
import matplotlib.pyplot as plt
pic = imageio.imread('(image)')
gray = lambda rgb : np.dot(rgb[... , :3] , [0.299 , 0.587, 0.114])
gray = gray(pic)
plt.imshow(gray, cmap = plt.get_cmap(name = 'gray'))
Toutefois, le logiciel GIMP convertissant les couleurs en logiciel d’image en niveaux de gris dispose de trois algorithmes pour effectuer cette tâche.
Utilisez img.Convert (), prend en charge les modes “L”, “RVB” et “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)
Sortie:
[[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]]
vous pourriez faire:
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()
Je suis arrivé à cette question via Google, cherchant un moyen de convertir une image déjà chargée en niveaux de gris.
Voici une façon de le faire avec 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)