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()
Related
Seems like cv2.imread() or Image.fromarray() is changing original image color to a bluish color. What i am trying to accomplish is to crop the original png image and keep the same colors but the color changes. Not sure how to revert to original color. Please help! ty
`
# start cropping logic
img = cv2.imread("image.png") # import cv2
crop = img[1280:, 2250:2730]
cropped_rendered_image = Image.fromarray(crop) #from PIL import Image
cropped_rendered_image.save("newImageName.png")
`
tried this and other fixes but no luck yet
https://stackoverflow.com/a/50720612/13206968
There is no "changing" going on. It's simply a matter of channel order.
OpenCV natively uses BGR order (in numpy arrays)
PIL natively uses RGB order
Numpy doesn't care
When you call cv.imread(), you're getting BGR data in a numpy array.
When you repackage that into a PIL Image, you are giving it BGR order data, but you're telling it that it's RGB, so PIL takes your word for it... and misinterprets the data.
You can try telling PIL that it's BGR;24 data. See https://pillow.readthedocs.io/en/stable/handbook/concepts.html
Or you can use cv.cvtColor() with the cv.COLOR_BGR2RGB flag (because you have BGR and you want RGB). For the opposite direction, there is the cv.COLOR_RGB2BGR flag.
I am trying to view a tif satellite image which has 4 bands. I want to remove the last band (NIR) and view the RGB image only, so I am trying to split the NIR from the rest of the image. Here is my code
import rasterio
from rasterio.plot import show
from matplotlib import pyplot as plt
from rasterio import plot
import numpy as np
#to display RGB
dataset = rasterio.open('2.tif')
%matplotlib inline
plot.show(dataset.read([1,2,3]), cmap="gray")
#to display just the red band
%matplotlib inline
plot.show(dataset.read(4), cmap="gray")
I provided a screen shot of the code and the output I am getting
Displaying just 1 band seems fine, but any idea why I keep seeing an image with a yellow and white color scheme when I try to display RGB bands together? I thought it's a cmap issue at the beginning, but even when I add 'cmap="gray"' the color of the image remains the same.
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()
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)
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))