Выравнивание гистограммы: не получается выходное изображение - PullRequest
0 голосов
/ 17 октября 2019

Я пытался реализовать функцию выравнивания гистограммы сам, но не получил требуемого выходного изображения.

import numpy as np
import cv2
import matplotlib.pyplot as plt
import math
%matplotlib inline

def freq(lst):
    d = {}
    for i in lst:
        for j in i:
            if d.get(j):
                d[j] += 1
            else:
                d[j] = 1

    return d
def probability(d,total_pixels):
    l = {}
    for i in range(256):
        value = d.get(i)
        if value != None:
            l[i] = value/total_pixels
    return l
def equalizer(d, l):
    f_dic = {}
    last_sum = 0
    for i in range(l):
        if d.get(i):
            prob = d.get(i)
            last_sum = last_sum+((l-1)*prob)
            f_dic[i] = math.floor(last_sum)
    return f_dic
def replace_values(f_dic, img):
    print(f_dic)
    for i in range(len(img)):
        for j in range(len(img)):
            vv = f_dic.get(img[i][j])
            if vv != None:
                img[i][j] = vv
    return img
def histogramEqualization(img):
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    freqq = freq(img)
    area = img.shape
    total_pixels = area[0]*area[1]
    prob = probability(freqq, total_pixels)
    f_dic = equalizer(prob,len(img))
    new_img = replace_values(f_dic,img)
    return new_img
pollen_dark = cv2.imread("/home/ahmed/Downloads/dip/DIP_A1_Fall2019/pollen_dark.tif")
new = histogramEqualization(pollen_dark)
plt.imshow(new, cmap='gray')

Я получаю это изображение: output_image

входное изображение это: input_image

требуется выходное изображение: required_output_image. Формула реализации для решения этой проблемы

Formula implementing

1 Ответ

0 голосов
/ 17 октября 2019

Один из способов сделать это с NumPy - это использовать np.unique(), чтобы найти изменяемые значения, и их функцию распределения вероятности (pdf), которая в основном является гистограммой. Это можно использовать для генерации соответствующих нормализованных значений в соответствии с кумулятивной функцией распределения (cdf), полученной из np.cumsum() в pdf, по формуле:

round((cdf - min_cdf) / (num_voxels - min_cdf) * (depth - 1))

ВесьИдея (так же как и формула) наглядно описана в Wikipedia .

Обычно это более чистый подход, чем циклический просмотр массива:

DEPTH = 2 ** 8


def hist_equalization(arr, depth=DEPTH):
    vals, pdf = np.unique(arr, return_counts=True)
    cdf = np.cumsum(pdf)
    min_cdf = min(cdf)
    new_vals = (
        np.round((cdf - min_cdf) / (arr.size - min_cdf) * (depth - 1))
        .astype(int))
    result = np.empty_like(arr)
    for i, val in enumerate(vals):
        result[np.nonzero(arr == val)] = new_vals[i]
    return result


plt.imshow(arr, cmap='gray', vmin=0, vmax=DEPTH - 1)
plt.imshow(hist_equalization(arr), cmap='gray', vmin=0, vmax=DEPTH - 1)

Вход:

img_input

Вывод:

img_output

(полный сценарий доступен здесь . Обратите внимание, что для удобства ввода / вывода я использовал PIL вместо cv, но это не имеет отношения к проблеме.)


EDIT

В вашем коде есть ряд сбоев (некоторые менее серьезные, некоторые более серьезные), но тот, который мешает вам получить правильный результат, заключается в том, что equalizer() в корне неверен.

Если вы замените свою версию equalizer() на:

def equalizer(pdf, l, depth=2 ** 8):
    min_cdf = pdf[min(pdf)]
    result = {}
    accumulator = 0
    for k, v in sorted(pdf.items()):
        accumulator += v
        result[k] = int(round((accumulator - min_cdf) / (l - min_cdf) * (depth - 1)))     
    return result

для вызова с:

f_dic = equalizer(freqq, total_pixels)

Тогда остальная часть вашего кода должна работать. Обратите внимание, что probability() совершенно не требуется, и вам действительно нужно total_pixels (или img.size), поскольку len(img), примененный к N-мерному массиву, даст вам его длину вдоль 0-го измерения , а не общее количество пикселей.

(сюда также входит .)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...