pythonimageopencvhistogramcontrast

Histogram Equalization Python (No Numpy and No Plotting)


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. enter image description here

Thank you in advance.


Solution

  • Here is a solution with some modifications. It gives the following output

    Original: original

    Equalized: histequalized

    Major Modifications:

    1. The 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 give
    2. The equalize_image() function equalizes the image by interpolating from the normal pixel range (which is range(0,256)) to your cumulative distribution function

    Here'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)