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 lisent juste dans l'image
import matplotlib.image as mpimg
img = mpimg.imread('image.png')
puis ils coupent le tableau, mais ce n'est pas la même chose que la conversion RVB en niveaux de gris de ce que je comprends.
lum_img = img[:,:,0]
J'ai du mal à croire que numpy ou matplotlib n'a pas de fonction intégrée pour convertir de rgb en gris. N'est-ce pas une opération courante dans le traitement d'image?
J'ai écrit une fonction très simple qui fonctionne avec l'image importée 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 celle intégrée.
Implémentation 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
la source
gray = np.mean(rgb, -1)
. Peut-êtrergb[...,:3]
là si c'est réellement rgba.gray = np.mean(rgb, -1)
marche bien. Merci. Y a-t-il une raison de ne pas l'utiliser? Pourquoi utiliserais-je plutôt les solutions des réponses ci-dessous?np.mean(rgb, -1)
.0.2989 * R + 0.5870 * G + 0.1140 * B
Je suppose que c'est la façon standard de procéder.Réponses:
Que diriez-vous de le faire avec Pillow :
Utilisation de matplotlib et de la formule
vous pourriez faire:
la source
matplotlib
pour une autre raison, il devrait pouvoir utiliser la fonction intégréecolorsys.rgb_to_yiq()
pour se transformer plus une tranche pour obtenir uniquement le canal luma..convert('LA')
? pourquoi pas.convert('gray')
? Semble inutilement cryptique. La documentation PIL ne mentionne rien sur «LA» pour la fonction de conversion.cannot write mode LA as JPEG
img = Image.open('image.png').convert('LA')
doit êtreimg = Image.open('image.png').convert('L')
LA
mode a une luminosité (luminosité) et alpha. Si vous utilisez leLA
mode, alorsgreyscale.png
sera une image RGBA avec le canal alpha deimage.png
préservé. Si vous utilisez leL
mode, alorsgreyscale.png
sera une image RVB (sans alpha).Vous pouvez également utiliser scikit-image , qui fournit certaines fonctions pour convertir une image en
ndarray
, commergb2gray
.Remarques : Les poids utilisés dans cette conversion sont calibrés pour les luminophores CRT contemporains: Y = 0,2125 R + 0,7154 G + 0,0721 B
Alternativement, vous pouvez lire l'image en niveaux de gris en:
la source
cmap
commegray' then only the image is shown as gray in
pyplot.imshow () `? Des pensées ? Où ai-je tort?Trois des méthodes suggérées ont été testées pour la vitesse avec 1000 images PNG RGBA (224 x 256 pixels) fonctionnant avec Python 3.5 sur Ubuntu 16.04 LTS (Xeon E5 2670 avec SSD).
Temps d'exécution moyens
pil :
1,037 secondesscipy:
1.040 secondessk :
2.120 secondesPIL et SciPy ont donné identique
numpy
tableaux (allant de 0 à 255). SkImage donne des 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.SkImage:
PIL :
SciPy :
Original:
Diff :
Code
Performance
la source
Vous pouvez toujours lire le fichier image en niveaux de gris dès le début en utilisant
imread
depuis OpenCV:De plus, si vous souhaitez lire l'image en RVB, effectuez un traitement puis convertissez-le en niveaux de gris que vous pourriez utiliser à
cvtcolor
partir d'OpenCV:la source
0
drapeau estcv2.CV_LOAD_IMAGE_GRAYSCALE
.Le moyen le plus rapide et le plus actuel consiste à utiliser Pillow , installé via
pip install Pillow
.Le code est alors:
la source
convert
retourne une copie convertie de l'imageLe didacticiel triche car il commence avec une image en niveaux de gris encodée en RVB, donc ils découpent simplement un canal de couleur unique 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 qui code avec quelque chose qui se rapproche du modèle luma / chroma, tel que YUV / YIQ ou HSL / HSV, puis de couper le canal de type luma et de l'utiliser comme votre image en niveaux de gris.
matplotlib
ne semble pas fournir un mécanisme pour convertir en YUV / YIQ, mais il vous permet de convertir en HSV.Essayez d'utiliser
matplotlib.colors.rgb_to_hsv(img)
puis de trancher 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 enmatplotlib
.Contexte:
Alternativement, vous pouvez utiliser PIL ou la fonction intégrée
colorsys.rgb_to_yiq()
pour convertir en un espace colorimétrique avec une véritable valeur de luma. Vous pouvez également vous lancer et lancer votre propre convertisseur luma uniquement, bien que ce soit probablement exagéré.la source
Utilisation de cette formule
Nous pouvons faire
Cependant, le logiciel de conversion de couleurs GIMP en niveaux de gris dispose de trois algorithmes pour effectuer la tâche.
la source
Si vous utilisez déjà NumPy / SciPy, vous pouvez également utiliser :
scipy.ndimage.imread(file_name, mode='L')
la source
scipy.ndimage.imread()
etscipy.misc.imread()
sont officiellement obsolètes dans SciPy 1.0.0 et seront définitivement supprimés dans SciPy 1.2.0. Alors que la documentation de SciPy recommandeimageio.imread()
comme remplacement approprié, l'API de cette fonction est nue jusqu'à l'absurdité. Il ne fournit aucun support pour la conversion en niveaux de gris et reste donc inadapté à de nombreuses applications - y compris la nôtre.</sigh>
vous pourriez faire:
la source
Utilisez img.Convert (), prend en charge «L», «RGB» et «CMYK». mode
Production:
la source
img = img.convert('L')
?Je suis arrivé à cette question via Google, à la recherche d'un moyen de convertir une image déjà chargée en niveaux de gris.
Voici une façon de le faire avec SciPy:
la source
img_gray = numpy.average(img, weights=[0.299, 0.587, 0.114], axis=2)
numpy.average
est un peu plus rapide mais pas pratiquement différent. Votre solution est claire et contient des informations pertinentes sur R, G, B, donc je la garderais. Mon commentaire était plus une option supplémentaire, pas un remplacement.scipy.ndimage.imread()
etscipy.misc.imread()
sont officiellement obsolètes dans SciPy 1.0.0 et seront définitivement supprimés dans SciPy 1.2.0. Vous voulez probablement juste utiliser le support de conversion en niveaux de gris de builtin Oreiller (ala unutbu de réponse ), au lieu.Vous pouvez utiliser
greyscale()
directement pour la transformation.la source