0
votes

I learned that OpenCV color order is BGR while that of Matpotlib's Pyplot is RGB. So I started experimenting with reading and displaying an image using both libraries. Here is the Image I experimented with:enter image description here

It's just a Black and white image with red color in some parts. Now, when I used pyplot.imshow() to display the image copy read by OpenCV, the tie's and the shoes' color changes to blue. The same happened when I used cv2.imshow() to display a copy of the image read by pyplot.imread(). However, the color remains the same when I use cv2.imshow() to display the image copy read by cv2.imread() and use plt.imshow() to display a copy read by plt.imread(). I am just curious and would like to know about the things that go behind the scenes when such operations are performed. Can Anyone help me with that?

2

2 Answers

3
votes

Assume you have a vector like this: [0, 0, 255].

You know have two different color encodings: RGB and BGR. So, in the first case you have Blue, in the second system you have Red.

Now, Let's call RGB_Reader and BGR_Reader two systems to open the number and display it.

If I open the image with BGR_Reader, I have [0, 0, 255]. I pass it on to RGB_Reader, still is [0, 0, 255]. I see Blue. When I pass it around, I would pass [0, 0, 255]. I open it again with RGB_Reader, it is blue, again.

The same happens the other way around.

Does it make sense to you? The vector doesn't change, but the way it is decoded does.

Now introduce another thing, called jpg_encoder. That one is telling people where to put Blue, Red and Green, and will probably re-order things.

1
votes

That's basically dependent upon the color convention. OpenCV follows BGR convention, which means that it interprets a triplet (0, 150, 255) as B, G and R values respectively. And all other libraries follow the more obvious RGB convention. The reason for OpenCV to follow BGR convention is legacy I guess(since 1991, maybe).

I would recommend you to use OpenCV methods only such as cv2.imread(), cv2.imshow() or cv2.imwrite(), etc. to perform any operation on image(s). Because writing code in this way you will never have to worry about the underlying BGR or RGB stuff, everything will just work fine.

The problem would arise when you want to use OpenCV with matplotlib or pillow etc. In those cases you need to take extra care while passing on your image matrix to respective libraries. Since OpenCV holds the data in BGR format, while matplotlib or pillow would be expecting RGB format, so you explicitly need to convert the color order using cv2.cvtColor(img, cv2.COLOR_BGR2RGB), or you may use numpy slicing as well to swap the first and third channel as well.

You may consult this answer for a demo code which converts OpenCV images to PIL(another python image processing module) format images.