3 views
in Python
closed

I'm attempting to work on a code for expanding the difference on grayscale pictures to make them more clear. I can't get this code to work. I'm attempting to get the distribution frequency of each worth (without utilizing any modules besides cv2) in the pixel and get the aggregate distribution frequency so I would then be able to change the worth utilizing the condition beneath. Any thought about what's going on with my code?

import cv2

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

Below was the example, which I'm trying to do.

closed

by (19k points)

import cv2

import numpy as np

img = cv2.imread(input("Enter the image file path: "))

row, col, _ = img.shape

def df(img):

values = np.bincount(img[:,:,0].flatten(), minlength=256)

return values

def cdf(img):

freq = df(img)

cdf_values = np.cumsum(freq)

return cdf_values

def h(img):

cdf_values = cdf(img)

h = ((cdf_values - 1) / ((row * col) - 1)) * 255

return h.astype(np.uint8)

new_image = h(img)

cv2.imwrite('a.png', new_image)

In this the changes include:

Using np.bincount() in the df() function to count the frequency of each pixel value in a flattened array.

Removing the unnecessary shape variable by directly unpacking the shape in row, col, _.

Adjusting the cv2.imwrite() function call to save the new image correctly.

Note: This code assumes the input image is a grayscale image (single channel). If it's a colored image, further modifications may be necessary.
by (26.4k points)

Look at the solution with some small modifications.

Original:

Equalized:

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

Look at the code:

import cv2

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)

Are you pretty much interested to learn python in detail? Come and join the python training course to gain more knowledge.

by (25.7k points)
The code you provided has several issues that need to be addressed. Here are the corrections:

import cv2

import numpy as np

img = cv2.imread(input("Enter the image file path: "))  # Use input() instead of raw_input()

shape = img.shape

row = shape[0]

col = shape[1]

def df(img):

values = np.zeros(256)  # Initialize an array to store frequencies

for i in range(row):

for j in range(col):

pixel_value = img[i, j, 0]  # Assuming it's a grayscale image

values[pixel_value] += 1

return values

def cdf(img):

freq = df(img)

cdf_values = np.cumsum(freq)

return cdf_values

def h(img):

cdf_values = cdf(img)

h = ((cdf_values - 1) / ((row * col) - 1)) * 255

return h.astype(np.uint8)  # Convert values to unsigned 8-bit integers

new_image = h(img)

cv2.imwrite('a.png', new_image)
by (15.4k points)
The code you provided has several issues that need to be addressed. Here are the corrections:

import cv2

import numpy as np

img = cv2.imread(input("Enter the image file path: "))  # Use input() instead of raw_input()

shape = img.shape

row = shape[0]

col = shape[1]

def df(img):

values = np.zeros(256)  # Initialize an array to store frequencies

for i in range(row):

for j in range(col):

pixel_value = img[i, j, 0]  # Assuming it's a grayscale image

values[pixel_value] += 1

return values

def cdf(img):

freq = df(img)

cdf_values = np.cumsum(freq)

return cdf_values

def h(img):

cdf_values = cdf(img)

h = ((cdf_values - 1) / ((row * col) - 1)) * 255

return h.astype(np.uint8)  # Convert values to unsigned 8-bit integers

new_image = h(img)

cv2.imwrite('a.png', new_image)

Changed raw_input() to input() for Python 3 compatibility.

Added import numpy as np to use NumPy arrays and functions.

In the df() function, initialized an array values of size 256 to store the frequencies of each pixel value.

Fixed the loop ranges in df() and h() to iterate over the image dimensions correctly.

Modified the calculation of pixel_value in df() to access the correct channel of the grayscale image (assuming it's the first channel, i.e., index 0).

In the cdf() function, used np.cumsum() to calculate the cumulative sum of frequencies.

Added astype(np.uint8) in h() to convert the values to unsigned 8-bit integers since image pixel values should be in that format.

Corrected the cv2.imwrite() function call to save the new image.

Please note that this code assumes the input image is grayscale (single channel). If you're working with a colored image, you may need to modify the code accordingly.