PIL rotate image colors (BGR -> RGB)
Solution 1
Assuming no alpha band, isn't it as simple as this?
b, g, r = im.split()
im = Image.merge("RGB", (r, g, b))
Edit:
Hmm... It seems PIL has a few bugs in this regard... im.split()
doesn't seem to work with recent versions of PIL (1.1.7). It may (?) still work with 1.1.6, though...
Solution 2
I know it's an old question, but I had the same problem and solved it with:
img = img[:,:,::-1]
Solution 3
Just to add a more up to date answer:
With the new cv2 interface images loaded are now numpy arrays automatically.
But openCV cv2.imread() loads images as BGR while numpy.imread() loads them as RGB.
The easiest way to convert is to use openCV cvtColor.
import cv2
srcBGR = cv2.imread("sample.png")
destRGB = cv2.cvtColor(srcBGR, cv2.COLOR_BGR2RGB)
Solution 4
Adding a solution using the ellipsis
image = image[...,::-1]
In this case, the ellipsis ...
is equivalent to :,:
while ::-1
inverts the order of the last dimension (channels).
Solution 5
This was my best answer. This does, by the way, work with Alpha too.
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)
Claudiu
Graduated from Brown University. E-mail: [email protected]
Updated on July 05, 2022Comments
-
Claudiu almost 2 years
I have an image where the colors are BGR. How can I transform my PIL image to swap the B and R elements of each pixel in an efficient manner?
-
Claudiu over 13 yearsthe solution was to load the image properly in the first place =P but this seems lovely
-
Claudiu over 10 yearsAh useful, thanks. Note you can suggest an edit and you get +2 rep if it gets approved
-
user2692263 over 10 yearsthanks, Claudiu, I'll try that: """Edits must be at least 6 characters; is there something else to improve in this post?""" Well - that did not go so well ;-)
-
Zach Garner over 9 yearsPretty much the only reason you would have a BGR image is if you're using OpenCV. Your solution is the right thing to do. The other top answer is functional, but would be slow in processing large images.
-
Luke Yeager about 9 years
np.roll
will convert BGR to RBG, not RGB. If you want to do this in numpy, you can usedata[...,[2,1,0]]
to swap the channels. But if you're already using OpenCV or PIL, just go with Martin Beckett's response. -
Peter9192 over 7 yearsThe data has 3 dimensions: width, height, and color.
::-1
effectively reverses the order of the colors. The width and height are not affected. -
Wesley Ranger over 7 yearsGood, I got it following your note and my testing.
::-1
is actually a shorthand of numpy operation[start:end:step]
, andstart
/end
is decided automatically. -
DollarAkshay about 7 yearsWhy is this not on top ?
-
Ryan Soklaski almost 7 yearsBecause the simplest solution is literally just: img = img[..., ::-1]
-
Martin Beckett almost 7 yearsDoes cv2 guarantee that images are contiguous? OpencCV (at least in c++) will start each new row on a 4byte boundary so you have to be careful moving raw bytes around
-
Eliethesaiyan almost 7 yearsthanks for this...i am using them in the same codes,got me crazy for a while@RyanSoklaski that is actually more confusing without knowing which is default for opencv or PIL but very neat
-
EuWern about 6 yearsfor clarity, img = img[:, :, : :-1] is equivalent to img = img[:, :, [2,1,0]]. I think the later is better as it is more explicit.
-
Ryan Soklaski almost 6 yearsimg[:, :, : :-1] is not equivalent to img[:, :, [2,1,0]]. The former utilizes basic index and the latter uses advanced indexing. The latter will make a copy of your image while the former does not.
-
Vinícius M almost 5 yearsThis is also significantly more performant than the cv2.cvtColor function suggested in an answer above.
-
hoohoo-b over 4 yearsAnother numpy alternative to @LukeYeager's suggestion:
np.flip(image_bgr, axis=2)
-
Lewis Morris over 3 yearsThis is how I do it usually, Although if its got alpha
Image.fromarray(np.array(img)[:,:,:3][:,:,::-1])
-
Muhammad Yasirroni over 2 yearsCan you elaborate your answer? Because obviously you need to use
np.shape
or someting like that to get the dimension. Also what isbgr_buf
?