71 votes

PIL fait tourner les couleurs de l'image (BGR -> RGB)

J'ai une image où les couleurs sont BGR. Comment puis-je transformer mon image LIP pour permuter les éléments B et R de chaque pixel de manière efficace ?

133voto

Peter9192 Points 1085

Je sais que c'est une vieille question, mais j'ai eu le même problème et je l'ai résolu avec :

img = img[:,:,::-1]

2 votes

Les données ont 3 dimensions : largeur, hauteur et couleur. ::-1 inverse effectivement l'ordre des couleurs. La largeur et la hauteur ne sont pas affectées.

10 votes

Bien, je l'ai eu en suivant votre note et mes tests. ::-1 est en fait un raccourci de l'opération numpy [start:end:step] y start / end est décidée automatiquement.

3 votes

Pour plus de clarté, img = img[ :, :, : :-1] est équivalent à img = img[ :, :, [2,1,0]]. Je pense que la dernière version est meilleure car elle est plus explicite.

108voto

Martin Beckett Points 60406

Juste pour ajouter une réponse plus à jour :

Avec la nouvelle interface cv2, les images chargées sont maintenant des tableaux numpy automatiquement.
Mais openCV cv2.imread() charge les images en BGR alors que numpy.imread() les charge en RGB.

La façon la plus simple de convertir est d'utiliser openCV cvtColor.

import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR, cv2.COLOR_BGR2RGB)

3 votes

La seule raison pour laquelle vous avez une image BGR est que vous utilisez OpenCV. Votre solution est la bonne chose à faire. L'autre solution est fonctionnelle, mais elle serait lente pour le traitement des grandes images.

0 votes

Pourquoi n'est-ce pas en haut ?

19 votes

Parce que la solution la plus simple est littéralement juste : img = img[..., ::-1]

33voto

Joe Kington Points 68089

En supposant qu'il n'y ait pas de bande alpha, n'est-ce pas aussi simple que ça ?

b, g, r = im.split()
im = Image.merge("RGB", (r, g, b))

Edit :

Hmm... Il semble que PIL ait quelques bugs à cet égard... im.split() ne semble pas fonctionner avec les versions récentes de PIL (1.1.7). Il se peut ( ?) qu'il fonctionne encore avec la version 1.1.6, mais...

0 votes

La solution était de charger l'image correctement en premier lieu =P mais cela semble très bien.

14 votes

np.roll convertira BGR en RBG, pas en RGB. Si vous voulez faire cela en numpy, vous pouvez utiliser data[...,[2,1,0]] pour échanger les canaux. Mais si vous utilisez déjà OpenCV ou PIL, optez pour la réponse de Martin Beckett.

0 votes

Une autre alternative numpy à la suggestion de @LukeYeager : np.flip(image_bgr, axis=2)

14voto

azygous Points 141

Ajout d'une solution à l'aide de l'ellipse

image = image[...,::-1]

Dans ce cas, l'ellipse ... est équivalent à :,: tandis que ::-1 inverse l'ordre de la dernière dimension (canaux).

10voto

sberry Points 28742

C'était ma meilleure réponse. D'ailleurs, cela fonctionne aussi avec Alpha.

from PIL import Image
import numpy as np
import sys 

sub = Image.open(sys.argv[1])
sub = sub.convert("RGBA")
data = np.array(sub) 
red, green, blue, alpha = data.T 
data = np.array([blue, green, red, alpha])
data = data.transpose()
sub = Image.fromarray(data)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X