In [1]:
from PIL import Image # Load PIL(Python Image Library)
import matplotlib.pyplot as plt # Load pyplot library
import numpy as np # Load Numerical Library
In [170]:
im = Image.open('2x2.jpg') # Load the image file
imarray = np.array(im) # Construct the array
In [180]:
plt.imshow(im); # Show the image;
np.array(im) # each pixel have 3 values.
Out[180]:
In [173]:
imgray = im.convert('L') # Convert the image to gray scale
In [182]:
plt.imshow(imgray); # It looks like color, but each pixels are just one values.;
np.array(imgray)
Out[182]:
In [188]:
plt.imshow(imgray, cmap=plt.cm.gray) # To show the gray scale, we use the cmap(color map);
In [190]:
plt.imshow(imgray, cmap=plt.get_cmap('gray')) # or use it;
In [192]:
imgray_array = np.array(imgray) # Let imgray_array be the array of imgray.
print imgray_array # As we know, each pixels have a value.
In [193]:
imgray_array.flatten() # To make the histogram, we use the flatten()
Out[193]:
In [197]:
plt.hist(imgray_array.flatten(), 256, [0,256]);
# Using the hist(), we can draw histogram. 256 means the count of equispaced pieces, [0, 256] is range.
Out[197]:
In [194]:
np.histogram(imgray_array.flatten(),256,[0,256]) # for the output, first array is count, second array is range of value.
Out[194]:
In [202]:
hist,bins = np.histogram(imgray_array.flatten(),256,[0,256])
# So I assign the variable 'hist' and 'bins' for count and range of pieces
In [199]:
cdf = hist.cumsum() # Cumulative Distribution Function
print 'CDF :\n', cdf
cdf_normalized = cdf * hist.max()/ cdf.max() # Normalized Cumulative Distribution Function
print 'cdf_normalized :\n', cdf_normalized
In [204]:
plt.plot(cdf_normalized, color = 'b'); # Plot the normalized CDF;
In [209]:
plt.hist(imgray_array.flatten(), 256, [0,256], color = 'r'); # Plot of histogram;
plt.plot(cdf_normalized, color = 'b'); # Plot of normalized CDF;
plt.xlim([0,256]); # range of X-axis;
plt.legend(('cdf','histogram'), loc = 'upper right'); # Attach the legend;
In [2]:
im = Image.open('flower.jpg')
imarray = np.array(im)
plt.imshow(imarray); # Image Show;
In [14]:
imgray = im.convert('L') # Convert to gray scale image
imgray_array = np.array(imgray) # Assign as array
plt.imshow(imgray, cmap=plt.get_cmap('gray')); # Image show as gray scale;
In [15]:
print np.array(imgray) # each pixel have a one value (min=0, max=255)
print 'Min : ', np.array(imgray).min()
print 'Max : ', np.array(imgray).max()
In [16]:
# Samething for 2x2 image.
hist,bins = np.histogram(imgray_array.flatten(),256,[0,256])
plt.hist(imgray_array.flatten(), 256, [0,256], color = 'r'); # Plot Histogram
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b'); # Plot normalized CDF
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
In [17]:
h = (256-1)*(cdf - cdf.min())/(cdf.max()-cdf.min()) # all values are integer. So this is automatic round.
# Each cdf value in (0, 255) has transformed value h[#].
In [35]:
transformed_img = h[imgray_array] # the value of imgray_array is index of h.
In [28]:
imgray_array # For example, the first value of imgray_array is 230.
Out[28]:
In [34]:
h[230] # h[230] is 227 which is transformed value by equalization formula.
Out[34]:
In [43]:
fig = plt.figure()
fig.set_size_inches(15,10)
a=fig.add_subplot(1,2,1)
plt.title('Original Image');
plt.imshow(imgray, cmap=plt.get_cmap('gray'));
a=fig.add_subplot(1,2,2)
plt.title('Transformed Image');
plt.imshow(transformed_img, cmap=plt.get_cmap('gray'));
In [47]:
fig = plt.figure()
fig.set_size_inches(15,10)
# Original Image
a=fig.add_subplot(1,2,1)
plt.title('Histogram, CDF of Original Image');
hist,bins = np.histogram(imgray_array.flatten(),256,[0,256])
plt.hist(imgray_array.flatten(), 256, [0,256], color = 'r'); # Plot Histogram
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b'); # Plot normalized CDF
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
# Transformed Image
a=fig.add_subplot(1,2,2)
plt.title('Histogram, CDF of Transformed Image');
hist,bins = np.histogram(img2.flatten(),256,[0,256])
plt.hist(img2.flatten(), 256, [0,256], color = 'r');
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b');
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
In [73]:
""" Total Comparison """
fig = plt.figure()
fig.set_size_inches(15,10)
a=fig.add_subplot(2,2,1)
plt.title('Original Image');
plt.imshow(imgray, cmap=plt.get_cmap('gray'));
a=fig.add_subplot(2,2,2)
plt.title('Transformed Image');
plt.imshow(transformed_img, cmap=plt.get_cmap('gray'));
# Original Image
a=fig.add_subplot(2,2,3)
plt.title('Histogram, CDF of Original Image');
hist,bins = np.histogram(imgray_array.flatten(),256,[0,256])
plt.hist(imgray_array.flatten(), 256, [0,256], color = 'r'); # Plot Histogram
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b'); # Plot normalized CDF
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
# Transformed Image
a=fig.add_subplot(2,2,4)
plt.title('Histogram, CDF of Transformed Image');
hist,bins = np.histogram(img2.flatten(),256,[0,256])
plt.hist(img2.flatten(), 256, [0,256], color = 'r');
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b');
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
In [68]:
def equalization(im):
fig = plt.figure()
fig.set_size_inches(15,10)
a=fig.add_subplot(3,2,1) # Original Color Image
imarray = np.array(im)
plt.imshow(imarray)
imgray = im.convert('L')
imgray_array = np.array(imgray)
a=fig.add_subplot(3,2,3)
plt.title('Original Image');
plt.imshow(imgray, cmap=plt.get_cmap('gray'));
hist, bins = np.histogram(imgray_array.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
a=fig.add_subplot(3,2,4)
h = (256-1)*(cdf - cdf.min())/(cdf.max()-cdf.min())
transformed_img = h[imgray_array]
plt.title('Transformed Image');
plt.imshow(transformed_img, cmap=plt.get_cmap('gray'));
# Original Image
a=fig.add_subplot(3,2,5)
plt.title('Histogram, CDF of Original Image');
plt.hist(imgray_array.flatten(), 256, [0,256], color = 'r'); # Plot Histogram
plt.plot(cdf_normalized, color = 'b'); # Plot normalized CDF
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
# Transformed Image
a=fig.add_subplot(3,2,6)
plt.title('Histogram, CDF of Transformed Image');
hist, bins = np.histogram(transformed_img.flatten(),256,[0,256])
plt.hist(transformed_img.flatten(), 256, [0,256], color = 'r');
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'b');
plt.xlim([0,256]);
plt.legend(('cdf','histogram'), loc = 'upper right');
In [69]:
# Case 1
image = Image.open('unist.jpg')
equalization(image)
In [70]:
# Case 2
image = Image.open('IU.jpg')
equalization(image)
In [71]:
# Case 3
image = Image.open('guitar.jpg')
equalization(image)
In [72]:
# Case 4
image = Image.open('cycle.jpg')
equalization(image)
The general histogram equalization formula is not golden key. For the landscape photos, the performance is good. But people photo and monotone color photo(actually darked image) has a bad performance. So we need to try the various approaches with other transformation idea. Or for instance, after detect the edge of object, try the locally adaptive histogram equalization. This will be adapt method for case 4 motor cycle maybe. I'm not sure, I don't know the edge detection. But these approaches are so interesting to me.