25

I have tried to use the imshow function from matplotlib.pyplot and it works perfectly to show grayscale images. When I tried to represent rgb images, it changes the colors, showing a more blue-ish color.

See an example:

import cv2
import matplotlib.pyplot as plt
lena=cv2.imread("lena.jpg")
plt.imshow(lena)
plt.show()

The resulting image is something like this

While the original image is this

If it is something related to the colormap, there is any way to make it work with rgb images?

rayryeng
  • 102,964
  • 22
  • 184
  • 193
dberga
  • 363
  • 1
  • 3
  • 6

2 Answers2

41

This worked for me:

plt.imshow(lena[:,:,::-1]) # RGB-> BGR

Same idea but nicer and more robust approach is to use "ellipsis" proposed by @rayryeng:

plt.imshow(lena[...,::-1])
AGN Gazer
  • 8,025
  • 2
  • 27
  • 45
  • 6
    You can also do `lena[...,::-1]`. The ellipsis at the beginning automatically collects all dimensions prior to the last one. – rayryeng May 31 '18 at 18:53
  • @rayryeng True. Thanks! – AGN Gazer May 31 '18 at 18:54
  • @rayryeng Ah, I only now saw your comment https://stackoverflow.com/questions/50630825/matplotlib-imshow-distorting-colors/50630968?noredirect=1#comment88271840_50630920 I think credit for this should go to you. If you post it as an answer, I will delete mine. – AGN Gazer May 31 '18 at 18:56
  • Haha nah, don't worry. I didn't think it was worthy enough to be an answer so I didn't post it. Let's leave it as is. – rayryeng May 31 '18 at 18:57
  • @rayryeng Well, this seems to me as the simplest method of all. You should have posted this... – AGN Gazer May 31 '18 at 18:58
  • True, but considering the rep difference I have with yours, I'd rather the rep go to you ;). – rayryeng May 31 '18 at 18:59
  • 1
    @rayryeng Thanks! I am on SO for fun. All this rep is for adrenaline only . – AGN Gazer May 31 '18 at 19:03
  • 1
    :D. I used to answer quite often but work and life got in the way... still, I'm looking forward to getting 100k rep. [I want that swag!](https://meta.stackoverflow.com/questions/291791/what-do-i-get-with-100k-reputation). – rayryeng May 31 '18 at 19:03
  • 1
    @rayryeng _"still, I'm looking forward to getting 100k rep"_. Congrats! I just saw you got it! – AGN Gazer Jul 09 '22 at 00:00
  • Haha wow, this answer was made almost 4 years ago. Thanks for remembering and hope all is well! – rayryeng Jul 10 '22 at 18:07
24

OpenCV represents the images in BGR as opposed to the RGB we expect. Since it is in the reverse order, you tend to see the blue color in images. Try using the following line (below comment in code) for converting from BGR to RGB:

import cv2
import matplotlib.pyplot as plt
lena=cv2.imread("lena.jpg")
#plt.imshow(lena)
#plt.axis("off")
#Converts from BGR to RGB
plt.imshow(cv2.cvtColor(lena, cv2.COLOR_BGR2RGB))
plt.show()
rayryeng
  • 102,964
  • 22
  • 184
  • 193
pragmaticprog
  • 550
  • 2
  • 15
  • 1
    You can also reverse the channels yourself using NumPy syntax: `image[...,::-1]`. – rayryeng May 31 '18 at 18:50
  • That is definitely another option. Since OpenCV was being used, I thought introducing a relevant function for converting color would be useful. – pragmaticprog May 31 '18 at 18:51
  • Certainly and in fact if you want to stay in the OpenCV space, that's more verbose, but reversing the channels yourself provides less overhead. It depends on the use case. If you intend on doing this repeatedly, then the slicing may be better but if you're just doing this once, the call to `cvtColor` is more explicit. Either way, good job nailing the problem! – rayryeng May 31 '18 at 18:52
  • That is true. Also, Thank you! – pragmaticprog May 31 '18 at 19:25