Python выравнивания гистограммы (без кучи и без печати)
Я пытаюсь работать над кодом для повышения контрастности изображений в градациях серого, чтобы сделать их более четкими. Я не могу заставить этот код работать. Я пытаюсь получить частоту распределения каждого значения (без использования каких-либо модулей, кроме cv2) в пикселе и получить кумулятивную частоту распределения, чтобы затем я мог изменить значение, используя уравнение ниже. Есть идеи, что не так с моим кодом?
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')
Это пример того, что я пытаюсь сделать.
Заранее спасибо.
2 ответа
Вот решение с некоторыми изменениями. Это дает следующий вывод
Основные модификации:
df()
а такжеcdf()
функции были сделаны простыми. Напечатайте их вывод на выполнение, чтобы проверить, соответствует ли это тому, что вы ожидаетеequalize_image()
Функция выравнивает изображение путем интерполяции из нормального диапазона пикселей (которыйrange(0,256)
) к вашей кумулятивной функции распределения
Вот код:
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)
Если вы не знаете, opencv предоставляет встроенную функцию для выравнивания историограммы, описанную здесь.
Также касательно вашего кода:
Частота распределения (или гистограмма) не рассчитана должным образом, так как вы учитываете только частоту цветов, которые появляются на изображении. Вы должны посчитать появление всех значений цвета, даже если они не появляются. Также каждый раз, когда ваш цвет появляется снова, вы добавляете новый элемент этого цвета в свой список, который не имеет большого смысла. Я не совсем уверен, откуда взято +=3.
Что бы я сделал, это что-то вроде этого:
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