PIL rotate image colors (BGR -> RGB)

PythonColorsPython Imaging-Library

Python Problem Overview


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?

Python Solutions


Solution 1 - Python

I know it's an old question, but I had the same problem and solved it with:

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

Solution 2 - Python

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 3 - Python

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 4 - Python

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 - Python

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)

Solution 6 - Python

Just a quick footnote for anyone writing code that might have to deal with 4-channel images, and discovering that the simple numpy answer seems to be eating their alpha channel.

np_image[:,:,[0,1,2]] = np_image[:,:,[2,1,0]]

will preserve the alpha data if there is a fourth channel, whereas

np_image = np_image[:,:,[2,1,0]]

will overwrite the 4-channel image with only reversed 3-channel data. (And the even simpler numpy answer, img = img[:,:,::-1], will give you ARGB data, which would be bad, too. :)

Solution 7 - Python

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

Just to clarify Martin Beckets solution, as I am unable to comment. You need cv2. in front of the color constant.

Solution 8 - Python

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

Solution 9 - Python

Using the ideas explained before... using numpy you could.

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')

Additionally it can remove the Alpha channel.

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

Solution 10 - Python

Application of other solutions. Just for a temporary measure.

import numpy

im = Image.fromarray(numpy.array(im)[:,:,::-1])

Solution 11 - Python

You should be able to do this with the ImageMath module.

Edit:

Joe's solution is even better, I was overthinking it. :)

Solution 12 - Python

TLDR: Use cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) if you already import cv2.


Speed comparison:

%%timeit
img_ = Image.fromarray(img[...,::-1])
# 5.77 ms ± 12.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
img_ = Image.fromarray(img[...,[2,1,0]])
# 6.2 ms ± 2.43 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
img_ = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
# 442 µs ± 4.84 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

Problem is, OP ask if img is already in PIL image format, whereas cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) require img in numpy array format.

But, cv2.imread() is most likely the reason you got BGR image. Not Image.open().

Solution 13 - Python

If you have an alpha band, use this:

img = img[:,:, [2, 1, 0, 3]]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionClaudiuView Question on Stackoverflow
Solution 1 - PythonPeter9192View Answer on Stackoverflow
Solution 2 - PythonMartin BeckettView Answer on Stackoverflow
Solution 3 - PythonJoe KingtonView Answer on Stackoverflow
Solution 4 - PythonazygousView Answer on Stackoverflow
Solution 5 - PythonsberryView Answer on Stackoverflow
Solution 6 - PythonricklevineView Answer on Stackoverflow
Solution 7 - Pythonuser2692263View Answer on Stackoverflow
Solution 8 - PythonAndrei AntonovView Answer on Stackoverflow
Solution 9 - PythonBlaZerTechView Answer on Stackoverflow
Solution 10 - PythonplhnView Answer on Stackoverflow
Solution 11 - PythonAmberView Answer on Stackoverflow
Solution 12 - PythonMuhammad YasirroniView Answer on Stackoverflow
Solution 13 - PythonJose SolorzanoView Answer on Stackoverflow