How to plot the equalized histogram of an image with Python? - python

So this is my code. The variable img is the original image. The variable eq is the equalized image.
from matplotlib.pyplot import imread, imshow, show, subplot, title, get_cmap, hist
from skimage.exposure import equalize_hist
img = imread('images/city.tif')
eq = equalize_hist(img)
subplot(221); imshow(img, cmap=get_cmap('gray')); title('Original')
subplot(222); hist(img.flatten(), 256, range=(0,256)); title('Histogram of origianl')
subplot(223); imshow(eq, cmap=get_cmap('gray')); title('Histogram Equalized')
subplot(224); hist(eq.flatten(), 256, range=(0,256));
show()
Now when I run, the code, I get the histogram of the original just fine. But the histogram of the equalized is incorrect. This is all of my output
What am I doing wrong ?!?!
EDIT: The builtin matlab commands from the answer works fine for the particular image

It looks like it's converting the image from uint8 format (integer values between 0 and 255 inclusive) to a float32 or float64 format (floating point values between 0 and 1 inclusive). Try eq = np.asarray(equalize_hist(img) * 255, dtype='uint8').

Related

Python skimage image with one value for color definition

I just started working with skimage and I am using it in python.3.6 with the skimage-version: 0.17.2
And I started using the example form: https://scikit-image.org/docs/stable/user_guide/numpy_images.html
There I found something that I did not understand. The color of this image is only defined by one singe value in the numpy-array. How can that be? Is it nit using RBG or something like this?
My code looks like this:
from skimage import data
camera = data.camera()
print(camera.shape)
print(camera[0,0])
And the output is:
(10, 100)
0.0
What is driving me crazy is the 0.0 shouldn't it be something like [0,0,0] for white in this example ?
When I show the image I get following result :
Can anybody please help me ?
The color is defined by a single value because it's not RGB, it's greyscale. So the image shape is (512, 512), and not (512, 512, 3). As a result, if you pick a single white point it will be [255] and not [255, 255, 255].
If you're confused because the picture isn't black and white, it's just because the default colormap of matplotlib is viridis, so green and yellow. This doesn't change the pixel values, it's essentially just a "theme" or camera filter. If you changed the colormap to grays, you will get:
import matplotlib.pyplot as plt
plt.imshow(255 - camera, cmap='Greys')
plt.show()
If you don't specify the colormap, even a random array of pixels will get the yellowish tint:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots(figsize=(4, 4))
plt.imshow(np.random.randint(0, 256, (512, 512)))
plt.show()
There is one thing I don't understand, though. The pic seems inverted. I had to subtract the pixel values from 255 to get the normal camera pic.

Python-Why does imshow() yield a blank image for a non-zero array?

My goal is to display a 2D Array as a image in Python. The array doesn't contain zero elements, and therefore I would expect an image in which imshow() automatically sets the color scale according to the array values. However, when I run the code, the image is blank.
The csv file is: https://ufile.io/urk5m
import numpy as np
import matplotlib.pyplot as plt
data_ = np.loadtxt(open("new_file.csv", "rb"), delimiter=",")
plt.imshow(data_)
My result is this: https://imgur.com/jMNnF0h
Always remember, but really always, that images works on 8bit integers. Thats why there is 2^8 shades of gray and why most commmon number of CS colors is (2^8)^3= 16.7 mil. colors. 3 because there are 3 color channels - RGB, each having 256 shades.
Everybody is counting with it and mainly the image processing libraries.
Therefore ALWAYS make sure you pass correct matrix datatype into image processing functions:
image_8bit = np.uint8(data_)
plt.imshow(image_8bit)
plt.show()

Unexpected behavior in local binary pattern - python skimage

I've been running into problems recently where the local binary pattern method in python skimage is producing unexpected results.
Have a look at the cartoon example below. It shows two flat color circles on a flat color background.
The local binary pattern (P=8 samples, Radius=1) output is:
(Image is color coded in jet colors). The gray color correctly represents 255. However, the blue color is 85 (binary 01010101).
So while the method correctly shows the background and the circle on the right as 255, it shows the left circle as 85. Apparently, the local binary pattern method in skimage thinks the region is completely noisy (hence the alternating binary pattern 01010101). This is not true, however, as I have double checked the individual pixels in the region shown in blue above and their values are identical (i.e. its flat color, just like the flat color background and other flat color circle).
Has anyone experienced a similar problem before?
Here is the code if you want to replicate this:
from skimage.feature import local_binary_pattern
from skimage.color import rgb2gray
import matplotlib.pyplot as plt
img = plt.imread('circles.png')
img = rgb2gray(img)
lbp = local_binary_pattern(img, 8, 1, 'default')
plt.imshow(lbp, cmap='nipy_spectral')
plt.title('Standard lbp (8,1)')
I guess the issue is due to numeric errors. When the color image is read using
img = plt.imread('circles.png')
you get an array of type float32 and in the subsequent conversion to grayscale
img = skimage.color.rgb2gray(img)
the resulting image is of type float64.
I recommend you to avoid the intermediate step. You could read the image with double precision (i.e. float64) from the very beginning like this:
In [63]: from skimage.feature import local_binary_pattern
In [64]: from skimage import io
In [65]: img = io.imread('circles.png', as_grey=True)
In [66]: img.dtype
Out[66]: dtype('float64')
In [67]: lbp = local_binary_pattern(img, 8, 1, 'default')
In [68]: io.imshow(lbp/255., cmap='nipy_spectral')
Out[68]: <matplotlib.image.AxesImage at 0x10bdd780>

matlplotlib with opencv gives a different image with the same pixel values

I've been trying to modify the pixels of an image slightly, but the colors are getting distorted. So, I multiplied every pixel with 1 and saw the result.
Here's my code
import numpy as np
from matplotlib import pyplot as plt
import cv2
mud1 = cv2.imread('mud.jpeg')
print mud1.shape
mask = np.random.random_integers(1,1,size=(81,81,3))
print mask.shape
print mask[21][21][2]
print mud1[21][21][2]
mud1new = np.multiply(mud1,mask)
print mud1new[21][21][2]
plt.subplot(121),plt.imshow(mud1),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(mud1new),plt.title('Masked')
plt.xticks([]), plt.yticks([])
plt.savefig('problem.jpeg')
plt.show()
The pixels remain unchanged but somehow the image I see is different.
The issue is because np.random.random_integers returns objects that are int64 whereas your loaded image is uint8 so when you multiply the two together, mud1new becomes an int64 array. When using imshow, it expects the following types
MxN – values to be mapped (float or int)
MxNx3 – RGB (float or uint8)
MxNx4 – RGBA (float or uint8)
To fix this, you should cast mud1new as a uint8 prior to display with imshow
mud1new = mud1new.astype(np.unit8)
plt.imshow(mud1new)
You could also convert mud1new to a float but that would require that all of your values should be between 0 and 1 so you'd have to divide everything by 255.
The value for each component of MxNx3 and MxNx4 float arrays should be in the range 0.0 to 1.0.
mud1new_float = mud1new.astype(np.float) / 255.0;
plt.imshow(mud1new_float)

How do I display an image in a plot using Python?

I imported matplotlib.pyplot and also NumPy
I wanted to display an image from my desktop to the plot but I get a TypeError.
code :
img = (image) ( here do we need to give the location of the file or the file directly)
imshow(img, extent=[-25,25,-25,25], cmap = cm.bone)
colorbar()
Error: TypeError: Image data can not convert to float
I am using Pycharm as my ide.
You are a bit ambiguous about
here do we need to give the location of the file or the file directly
No you don't. You need to use some imaging library to read an image. img="C:\image.jpg" does not read an image!
For example, to read a 'png' image, you could:
# Copypaste from docs
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img=mpimg.imread('myimage.png')
# end
# from now on you can use img as an image, but make sure you know what you are doing!
imgplot=plt.imshow(img)
plt.show()
Read more at Image tutorial at matplotlib's doc
Is img a numpy array of the right type?
If you read the image using pillow,etc. and have an Image object you have to get the numpy array from it ( img.getdata() )
X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4)
Display the image in X to current axes. X may be a float array, a
uint8 array or a PIL image. If X is an array, it can have the
following shapes:
MxN – luminance (grayscale, float array only) MxNx3 – RGB (float or
uint8 array) MxNx4 – RGBA (float or uint8 array)
The value for each component of MxNx3 and MxNx4 float arrays should be in the range 0.0 to 1.0;
Either normalize img so it's between 0.0 and 1.0 or convert it to uint8 ( img=np.array(img, dtype=np.uint8) ).

Categories

Resources