matplotlib imshow distorting colors [duplicate] - python

This question already has answers here:
OpenCV giving wrong color to colored images on loading
(7 answers)
Closed 3 years ago.
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?

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

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

Related

cv2.cvtcolor bgr2gray seems get an error image

# the code is as follows, implemented, but the result is possibly wrong, it is not the grayscale i wanted, someone gonna help me with that, it's seems quite simple, but i just don't know what wrong
import cv2
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.image as mpimg
img = cv2.imread('calibration_test.png')
# i want simply convert the rgb image to grayscale and then print it out
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(gray)
print(gray.shape)
# but the outcome is a colorful image
The grayscale conversion was done correctly. The problem is in how you are displaying the image. Try this:
plt.imshow(gray, cmap='gray')
By default imshow adds it's own colour key to single channel images, to make it easier to view. A typical example is thermal images which usually show blue and red, but all the colours are only dependend on one channel.
Hope this helps!

Rendering grayscale image

Using this code :
import cv2
import matplotlib.pyplot as plt
%matplotlib inline
plt.imshow(cv2.imread('badger.jpeg' , cv2.IMREAD_GRAYSCALE))
an image is read as greyscale and plotted to screen.
The image is plotted as :
This does not appear to be grayscale as there is colour that does not range form white to grey contained in the rendered image ?
My code is correct to read the image as grayscale using the IMREAD_GRAYSCALE parameter ?
The image is located at : https://sciencing.com/difference-between-badger-wolverine-8645505.html
The image is indeed flattened to grayscale if you use cv2.IMREAD_GRAYSCALE (you can test this using cv2.imread('im.jpg', cv2.IMREAD_GRAYSCALE).shape and cv2.imread('im.jpg').shape, and see that the former is a 3-d array and the latter is a 2-d array)
The issue is with the way matplotlib chooses to map your pixel values. When using plt.imshow(), it is using the default colormap (which is viridis, for some reason). This means pixel intensities / values will be mapped to the following:
You can change cmap to gray, in order to map them to the following:
plt.imshow(cv2.imread('badger.jpeg', cv2.IMREAD_GRAYSCALE), cmap='gray')
plt.show()

Difference between plt.imshow and cv2.imshow?

Why is there a difference in the output image when calling the same image using plt.imshow & cv2.imshow()?
Here is my code:
import cv2
import numpy as np
from matplotlib import pyplot as plt
src=cv2.imread('fruits1.jpg') # Source image
plt.subplot(211),plt.imshow(src),plt.title('image')
plt.xticks([]),plt.yticks([])
plt.show()
cv2.imshow('image',src)
cv2.waitKey(0)
cv2.destroyWindow()
Here is the image from plt.imshow:
and the second one is the original image:
Is there some modification required with the plt.imshow()?
Because OpenCV stores images in BGR order instead of RGB.
Try plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
See here for an example.
OpenCV - BGR and Matplotlib - RGB
OpenCV:
https://docs.opencv.org/2.4/doc/tutorials/introduction/display_image/display_image.html
Matplotlib:
https://matplotlib.org/api/_as_gen/matplotlib.pyplot.imshow.html
you can either use :
plt.imshow(cv2.cvtColor(image,cv2.COLOR_BGR2RGB))
OR
plt.imshow(image[:,:,::-1]) # here we are reversing the channel order

Python PIL cut off my 16-bit grayscale image at 8-bit

I'm working on an python program to display images of stars. The images are 16-bit grayscale tiffs.
If I try to display them in an extern program, e.g. ImageMagick they are correct but if I load them in python and then use 'show()' or implement them in a canvas in Tkinter they are, unless a few pixel, totally white.
So I estimate python sets every pixel above 255 to white but I don't know why. If I load the image and then save it as tiff again, ImageMagick can show it correct.
Thanks for help.
Try to convert the image to a numpy array and display that:
import Image
import matplotlib.pyplot as plt
import numpy as np
img = Image.open('image.tiff')
arr = np.asarray(img.getdata()).reshape(img.size[1], img.size[0])
plt.imshow(arr)
plt.show()
You can change the color mapping too:
from matplotlib import cm
plt.imshow(arr, cmap=cm.gray)

Invert colors when plotting a PNG file using matplotlib

I'm trying to display a PNG file using matplotlib and of course, python. For this test, I've generated the following image:
Now, I load and transform the image into a multidimensional numpy matrix:
import numpy as np
import cv2
from matplotlib import pyplot as plt
cube = cv2.imread('Graphics/Display.png')
plt.imshow(cube)
plt.ion()
When I try to plot that image in matplotlib, the colors are inverted:
If the matrix does not have any modifications, why the colors in the plot are wrong?
Thanks in advance.
It appears that you may somehow have RGB switched with BGR. Notice that your greens are retained but all the blues turned to red. If cube has shape (M,N,3), try swapping cube[:,:,0] with cube[:,:,2]. You can do that with numpy like so:
rgb = numpy.fliplr(cube.reshape(-1,3)).reshape(cube.shape)
From the OpenCV documentation:
Note: In the case of color images, the decoded images will have the
channels stored in B G R order.
Try:
plt.imshow(cv2.cvtColor(cube, cv2.COLOR_BGR2RGB))
As others have pointed out, the problem is that numpy arrays are in BGR format, but matplotlib expects the arrays to be ordered in a different way.
You are looking for scipy.misc.toimage:
import scipy.misc
rgb = scipy.misc.toimage(cube)
Alternatively, you can use scipy.misc.imshow().
Color image loaded by OpenCV is in BGR mode. However, Matplotlib displays in RGB mode.
So we need to convert the image from BGR to RGB:
plt.imshow(cv2.cvtColor(cube, cv2.COLOR_BGR2RGB))

Categories

Resources