OpenCV-Python Histogram-2: Выравнивание гистограммы | 27

глубокое обучение

Цель

В этой секции,

  • Мы изучим концепцию выравнивания гистограммы и используем ее для улучшения контрастности изображений.

теория

Рассмотрим изображение, значения пикселей которого ограничены определенным диапазоном значений. Например, более яркое изображение ограничит все пиксели высокими значениями. Но хорошее изображение будет иметь пиксели из всех областей изображения. Таким образом, вам нужно растянуть эту гистограмму на оба конца (как показано на изображении ниже из Википедии), что и делает выравнивание гистограммы (просто говоря). Обычно это увеличивает контрастность изображения.

Я предлагаю вам прочитать страницу Википедии о выравнивании гистограммы для получения более подробной информации об этом. Он так хорошо объясняет примеры, что вы можете понять почти все после прочтения. Вместо этого здесь мы увидим его реализацию Numpy. После этого мы увидим функции OpenCV.

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('wiki.jpg',0)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf * float(hist.max()) / cdf.max()
plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

Вы можете видеть, что гистограмма находится в более светлых областях. Нам нужен полный спектр. Для этого нам нужна функция преобразования, которая сопоставляет входные пиксели яркой области с выходными пикселями всей области. Это то, что делает выравнивание гистограммы.

Теперь мы находим наименьшее значение гистограммы (исключая 0) и применяем уравнение выравнивания гистограммы, приведенное на вики-странице. Но я использовал здесь концептуальный массив замаскированного массива из Numpy. Для маскированных массивов все операции выполняются над немаскированными элементами. Вы можете узнать больше о маскированных массивах из документации Numpy.

cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')

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

img2 = cdf[img] 

Теперь мы вычисляем его гистограмму и cdf, как и раньше (вы делаете это), и результат выглядит следующим образом:

Еще одна важная особенность заключается в том, что хоть изображение и более темное (вместо того, которое мы использовали, более яркое), после эквализации мы получим почти такое же изображение. Поэтому он используется в качестве «справочного инструмента», чтобы все изображения имели одинаковые условия освещения. Это полезно во многих ситуациях. Например, при распознавании лиц перед обучением на данных лица выполняется процесс выравнивания гистограммы на изображениях лиц, чтобы они имели одинаковые условия освещения.

Выравнивание гистограммы в OpenCV

В OpenCV для этого есть функция cv.equalizeHist(). Его вход — это просто изображение в градациях серого, а выход — наше изображение, выровненное по гистограмме. Ниже приведен простой фрагмент кода, показывающий его использование с тем же изображением, которое мы используем:

img = cv.imread('wiki.jpg',0)
equ = cv.equalizeHist(img)
res = np.hstack((img,equ)) #stacking images side-by-side
cv.imwrite('res.png',res)

Так что теперь вы можете делать разные снимки в разных условиях освещения, выравнивать их и проверять результат.

Выравнивание гистограммы хорошо работает, когда гистограмма изображения ограничена определенной областью. Это не работает, когда гистограмма покрывает большую площадь (т. е. есть как яркие, так и темные пиксели) с большими вариациями интенсивности. Пожалуйста, проверьте ссылки SOF на других ресурсах.

CLAHE (адаптивное выравнивание гистограммы с ограниченным контрастом)

Первое выравнивание гистограммы, которое мы только что видели, учитывает общую контрастность изображения. Во многих случаях это не очень хорошая идея. Например, на рисунке ниже показано входное изображение и его результат после глобального выравнивания гистограммы.

Контраст фона действительно улучшается после выравнивания гистограммы. Но сравните лицо статуи на обоих изображениях. Мы потеряли там большую часть информации из-за высокой яркости. Это связано с тем, что его гистограмма не ограничена определенной областью, как мы видели в предыдущем случае (попробуйте построить гистограмму входного изображения, и вы получите больше интуиции).

Поэтому для решения этой проблемы используйтеАдаптивная коррекция гистограммы. В этом случае изображение разделено на маленькие части, называемые «плитками» (в OpenCV tileSize по умолчанию равен8x8). Затем каждый из этих блоков, как обычно, выравнивается по гистограмме. Следовательно, в меньшей области гистограмма будет ограничена меньшей областью (если нет шума). Если есть шум, он будет усилен. Чтобы избежать этого, применяется предел контрастности. Если какие-либо ячейки гистограммы превышают указанный предел контрастности (по умолчанию 40 в OpenCV), эти пиксели обрезаются и равномерно распределяются по другим ячейкам перед применением выравнивания гистограммы. После выравнивания для удаления артефактов на границах тайлов применяется билинейная интерполяция.

В следующем фрагменте кода показано, как применить CLAHE в OpenCV:

import numpy as np
import cv2 as cv
img = cv.imread('tsukuba_l.png',0)
# create a CLAHE object (Arguments are optional).
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)
cv.imwrite('clahe_2.jpg',cl1)

Посмотрите на результаты ниже и сравните их с результатами выше, особенно область статуи:

Дополнительные ресурсы

  1. Страница Википедии об выравнивании гистограммы: http://en.wikipedia.org/wiki/Histogram_equalization
  2. Маскированные массивы в Numpy: http://docs.scipy.org/doc/numpy/reference/maskedarray.html)

Вопросы о регулировке контраста: `

  1. Как настроить контраст в OpenCV на C? http://stackoverflow.com/questions/10549245/how-can-i-adjust-contrast-in-opencv-in-c
  2. Как выровнять контрастность и яркость изображения с помощью opencv? http://stackoverflow.com/questions/10561222/how-do-i-equalize-contrast-brightness-of-images-using-opencv)

Сводная станция блога о технологиях искусственного интеллекта Panchuang: http://docs.panchuang.net/PyTorch, официальная учебная станция на китайском языке: http://pytorch.panchuang.net/OpenCV, официальный китайский документ: http://woshicver.com/