Один из способов сделать это с 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)
Вход:
Вывод:
(полный сценарий доступен здесь . Обратите внимание, что для удобства ввода / вывода я использовал 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-го измерения , а не общее количество пикселей.
(сюда также входит .)