web-dev-qa-db-fra.com

PIL faire pivoter les couleurs de l'image (BGR -> RGB)

J'ai une image où les couleurs sont BGR. Comment puis-je transformer mon image PIL pour échanger efficacement les éléments B et R de chaque pixel?

31
Claudiu

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

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

Modifier:

Hmm ... Il semble que PIL présente quelques bugs à ce sujet ... im.split() ne semble pas fonctionner avec les versions récentes de PIL (1.1.7). Cela peut (?) Fonctionner avec 1.1.6, bien que ...

Alternativement, si vous avez numpy disponible, vous pouvez l'utiliser pour ceci: (Encore une fois, je suppose une image RVB ici, non une image RVBA!):

data = np.asarray(im)
im = Image.fromarray(np.roll(data, 1, axis=-1))

Si im.split() fonctionne, c’est certainement une option plus simple et plus lisible!

15
Joe Kington

Juste pour ajouter une réponse plus à jour:

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

Le moyen le plus simple de convertir consiste à utiliser openCV cvtColor.

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

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

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

C'était ma meilleure réponse. Soit dit en passant, 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)
6
sberry
import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR,cv2.COLOR_BGR2RGB)

Juste pour clarifier la solution de Martin Beckets, car je suis incapable de commenter. Vous avez besoin de cv2. devant la constante de couleur.

3
user2692263

En utilisant les idées expliquées précédemment ... en utilisant numpy, vous pourriez.

bgr_image_array = numpy.asarray(bgr_image)
B, G, R = bgr_image_array.T
rgb_image_array = np.array((R, G, B)).T
rgb_image = Image.fromarray(rgb_image_array, mode='RGB')

De plus, il peut supprimer le canal Alpha.

assert bgra_image_array.shape == (image_height, image_width, 4)
B, G, R, _ = bgra_image_array.T
rgb_image_array = np.array((R, G, B)).T
1
BlaZerTech

Vous devriez pouvoir le faire avec le module ImageMath .

Modifier:

La solution de Joe est encore meilleure, j'y pensais trop. :)

0
Amber
im = Image.frombuffer('RGB', (width, height), bgr_buf, 'raw', 'BGR', 0, 0)
0
Andrei Antonov