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 ответа

Решение

Вот решение с некоторыми изменениями. Это дает следующий вывод

Оригинал: оригинал

Откорректированная: histequalized

Основные модификации:

  1. df() а также cdf() функции были сделаны простыми. Напечатайте их вывод на выполнение, чтобы проверить, соответствует ли это тому, что вы ожидаете
  2. 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
Другие вопросы по тегам