Reputation: 63
I am trying to work on a code for increasing the contrast on grayscale images to make them clearer. I can't seem to get this code to work. I am trying to get the distribution frequency of each value (without using any modules aside from cv2) in the pixel and get the cumulative distribution frequency so I can then change the value using the equation below. Any idea what is wrong with my code?
import cv2
img=cv2.imread(raw_input())
shape=img.shape
row=shape[0]
col=shape[1]
def df(img): #to make a histogram (count distribution frequency)
values=[]
occurances=[]
for i in range (len(img)):
for j in img[i]:
values.append(j)
if j in values:
count +=3
occurances.append(count)
return occurances
def cdf (img): #cumulative distribution frequency
values2=[]
for i in values:
j=0
i=i+j
j+1
values2.append(i)
return values2
def h(img): #equation for the new value of each pixel
h=((cdf(img)-1)/((row*col)-1))*255
return h
newimage=cv2.imwrite('a.png')
This is an example of what I'm trying to do.
Thank you in advance.
Upvotes: 1
Views: 7292
Reputation: 4220
Here is a solution with some modifications. It gives the following output
Major Modifications:
df()
and cdf()
functions have been made simple. Do print their output on execution to check if it matches with what you would expect it to giveequalize_image()
function equalizes the image by interpolating from the normal pixel range (which is range(0,256)
) to your cumulative distribution functionHere's the code:
import cv2
img = cv2.imread(raw_input('Please enter the name of your image:'),0) #The ',0' makes it read the image as a grayscale image
row, col = img.shape[:2]
def df(img): # to make a histogram (count distribution frequency)
values = [0]*256
for i in range(img.shape[0]):
for j in range(img.shape[1]):
values[img[i,j]]+=1
return values
def cdf(hist): # cumulative distribution frequency
cdf = [0] * len(hist) #len(hist) is 256
cdf[0] = hist[0]
for i in range(1, len(hist)):
cdf[i]= cdf[i-1]+hist[i]
# Now we normalize the histogram
cdf = [ele*255/cdf[-1] for ele in cdf] # What your function h was doing before
return cdf
def equalize_image(image):
my_cdf = cdf(df(img))
# use linear interpolation of cdf to find new pixel values. Scipy alternative exists
import numpy as np
image_equalized = np.interp(image, range(0,256), my_cdf)
return image_equalized
eq = equalize_image(img)
cv2.imwrite('equalized.png', eq)
Upvotes: 2
Reputation: 94
In case you're not aware, opencv provides a built in function for historgram equalization, documented here.
Also concerning your code:
The distribution frequency (or histogram) isn't calculated properly, since you only count the frequency of colors that do appear in the image. You should count the appearances of all color values, even if they don't appear. Also everytime your color reappears you add a new element of that color to your list, which doesn't make a lot of sense. I'm not quite sure where the +=3 comes from either.
What I would do is something like this:
def df(img): #to make a histogram (count distribution frequency)
values = [0] * 256
for i in range(len(img)):
for j in img[i]:
values[j] += 1
Upvotes: 1