12

Question

With an image loaded into Python as shown below, how do I know which order the channels are in? (e.g. BGR or RGB)

Code

from PIL import Image
import numpy as np

image_pil = Image.open("Stonehenge.jpg")
image_np = np.array(image_pil)
image_np[0][0]

Result

array([ 52, 123, 155], dtype=uint8)

Specific question

How do I know whether the 52 corresponds to the red channel, the blue channel, or a different channel? Or does this question not make sense on a conceptual level?


Notes

In a similar question for Java instead of Python, one person claims:

If you are reading in the image file, or you have access to the code that reads in the file, know it is:

  • BGR order if you used cv2.imread(),
  • RGB order if you used mpimg.imread(), (assuming import matplotlib.image as mpimg)

If you don't know how the file was opened, the accepted answer BufferedImage is great for Java.

Community
  • 1
  • 1
Matt Kleinsmith
  • 1,017
  • 3
  • 13
  • 24
  • Not versed in the specifics of the PIL library, but the following classes may help:http://pillow.readthedocs.io/en/3.4.x/reference/ImageColor.html,http://pillow.readthedocs.io/en/3.4.x/reference/PixelAccess.html – silent Oct 23 '17 at 22:41
  • 1
    PIL/Pillow will *always* use R,G,B order. P.S. that's not color space - color space is which pixel values correspond to which physical colors, and will usually have names like sRGB, Adobe RGB, etc. – Mark Ransom Oct 23 '17 at 23:08
  • 1
    If you have access to the code, you can see which function was used. All the popular packages mention in their documentation whether the order is RGB or BGR. If a black box has handed over a numpy array to you, the only thing I can think of is zeroing the 2nd and 3rd colour planes, save that to a file, load it with a package you know the order and check whether R or B is non-zero. I don't know if this answers your question, so I leave it as a comment. – Reti43 Oct 23 '17 at 23:20
  • 1
    Pixels are often composed of data from multiple color channels all being display together, so your question doesn't make much sense in that regard. Data in a given image file can be stored in one or more formats, which is image file format specific. You may need a third party module that provides you with that information for a specific file in question. – martineau Oct 23 '17 at 23:23
  • 1
    It seems one needs to know the default order used for each package with respect to a file format, with some packages (e.g. PIL) defaulting to one order for all file formats. I removed "color space" from the question. – Matt Kleinsmith Oct 23 '17 at 23:39
  • Too unclear, impossible to answer. Is the question about the order in a file (which formats?)? In a library's internal memory representation (which library/which formats/why does it matter?)? A library's interface (again, which library/which formats?)? All/some of the above? "An image loaded into Python" has no specific meaning, there are tons of possible technical meanings for "load", "picture" and "into Python". – ivan_pozdeev Oct 24 '17 at 04:26
  • Thanks, Ivan. I updated the question to make it more clear. I have the feeling that I'm misunderstanding this situation on a conceptual level. I feel like I might be asking something like, "How do I save my laptop into my computer?" – Matt Kleinsmith Oct 24 '17 at 05:35

1 Answers1

13

Since you use PIL and you don't specify any other mode to load the Image with, you get R G B.

You could verify that by checking the "mode" attribute on the Image instance:

image_pil.mode   # should return the string 'RGB'

Pillow supports the array interface, via image_pil.__array_interface__ magic method, so when when you create the ndarray numpy just uses that. i.e., it doesn't know anything about the colour channel order. If you have an image file stored as BGR, and you load it like this, you will get blue data in the red channel and vice-versa, and it would look wrong when you display it.

wim
  • 338,267
  • 99
  • 616
  • 750