OpenCV-Python Histogram-1: найти, построить и проанализировать | 26

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

Цель

учиться

  • Найдите гистограмму, используя функции OpenCV и Numpy
  • Постройте гистограмму с использованием функций OpenCV и Matplotlib
  • Вы увидите следующие функции:cv.calcHist(),np.histogram()Ждать.

теория

Так что же такое гистограмма? Вы можете думать о гистограмме как о графике или графике, который дает вам общее представление о распределении интенсивности изображения. Это график со значениями пикселей (не всегда в диапазоне от 0 до 255) по оси X и соответствующим количеством пикселей в изображении по оси Y.

Это просто еще один способ понять изображения. Глядя на гистограмму изображения, вы можете получить интуитивное представление о контрасте, яркости, распределении интенсивности и т. д. этого изображения. Почти все инструменты обработки изображений сегодня предлагают функцию гистограммы. Ниже приведено изображение с веб-сайта Cambridge Color, который я рекомендую вам посетить для получения более подробной информации.

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

найти гистограмму

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

BINS: гистограмма выше показывает количество пикселей на значение пикселя, то есть от 0 до 255. То есть вам нужно 256 значений для отображения гистограммы выше. Но подумайте об этом, что, если вместо того, чтобы находить количество пикселей для всех значений пикселей по отдельности, вы находите количество пикселей в интервале значений пикселей? Например, вам нужно найти количество пикселей от 0 до 15, затем от 16 до 31, ..., 240 и 255. Для представления гистограммы требуется всего 16 значений. Это то, что показано в примере с гистограммами в учебнике OpenCV.

Итак, все, что вам нужно сделать, это разделить всю гистограмму на 16 подразделов, а значение каждого подраздела — это сумма всех подсчетов пикселей в нем. Каждый подраздел называется «БИН». В первом случае количество бинов равно 256 (по одному на пиксель), а во втором — всего 16 бинов. BINS предоставляется документацией OpenCV.histSizeпредставление термина.

DIMS: это количество параметров, по которым мы собираем данные. В этом случае мы собираем данные только об одном значении интенсивности. Так вот 1.

RANGE: это диапазон значений интенсивности, которые вы хотите измерить. Обычно это[0,256], то есть все значения интенсивности.

1. Расчет гистограммы в OpenCV

Итак, теперь мы используемcv.calcHist() для поиска гистограммы. Познакомимся с функцией и ее параметрами:

cv.calcHist (изображения, каналы, маска, histSize, диапазоны [ hist [ накапливать]])

  1. images: исходное изображение типа uint8 или float32. Он должен быть заключен в квадратные скобки, то есть «[img]».
  2. каналы: Также указывается в квадратных скобках. Это индекс канала, по которому мы вычисляем гистограмму. Например, если вход представляет собой изображение в градациях серого, его значение равно [0]. Для цветных изображений вы можете передать [0], [1] или [2] для вычисления гистограммы синего, зеленого или красного канала соответственно.
  3. маска: Маска изображения. Чтобы найти гистограмму полного изображения, укажите «Нет». Однако, если вы хотите найти гистограмму определенной области изображения, вам нужно создать для этого изображение маски и использовать его в качестве маски. (Я покажу пример позже.)
  4. histSize: представляет наш счетчик BIN. Его нужно заключить в квадратные скобки. Для полного размера мы передаем [256].
  5. диапазоны: это наш ДИАПАЗОН. Обычно [0,256].

Итак, давайте начнем с примера изображения. Просто загрузите изображение в оттенках серого и найдите его полную гистограмму.

img = cv.imread('home.jpg',0)
hist = cv.calcHist([img],[0],None,[256],[0,256])

hist представляет собой массив 256x1, каждое значение соответствует количеству пикселей в этом изображении с соответствующим значением пикселя.

2. Расчет гистограммы Numpy

Numpy также предоставляет вам функциюnp.histogram( ). Следовательно, кромеcalcHist() вы можете попробовать следующий код:

hist,bins = np.histogram(img.ravel(),256,[0,256])

Hist такой же, как мы рассчитали ранее. Но в корзине будет 257 элементов, потому что Numpy вычисляет диапазон корзины как0-0.99,1-1.99,2-2.99Ждать. Таким образом, окончательный диапазон255-255.99. Чтобы указать на это, они также добавили 256 в конце. Но нам не нужно 256. Достаточно максимум 255.

  • Кроме того
    У Numpy есть еще одна функцияnp.bincount(), что примерно в 10 раз быстрее, чем np.histogram(). Так что для одномерной гистограммы лучше попробовать. Не забудьте установить minlength=256 в np.bincount. Например,hist = np.bincount(img.ravel(),minlength = 256)

Уведомление
Функция OpenCV примерно в 40 раз быстрее, чем np.histogram(). Поэтому по возможности используйте функции OpenCV.

Теперь нам нужно нарисовать гистограмму, но как?

нарисовать гистограмму

Есть два пути,

  1. Короткий путь: использование функций построения графиков Matplotlib
  2. Немного более длинный метод: используйте функции рисования OpenCV.

1. Использование Matplotlib

Matplotlib поставляется с функциями построения гистограмм:matplotlib.pyplot.hist()Он напрямую находит гистограмму и рисует ее. вам не нужно использоватьcalcHist() или функцию np.histogram(), чтобы найти гистограмму. См. код ниже:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('home.jpg',0)
plt.hist(img.ravel(),256,[0,256]); plt.show()

Вы получите следующий результат:

В качестве альтернативы вы можете использовать обычные графики matplotlib, которые отлично подходят для графиков BGR. Для этого нужно сначала найти данные гистограммы. Попробуйте следующий код:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('home.jpg')
color = ('b','g','r')
for i,col in enumerate(color):
    histr = cv.calcHist([img],[i],None,[256],[0,256])
    plt.plot(histr,color = col)
    plt.xlim([0,256])
plt.show()

результат:

Из изображения выше вы можете сделать вывод, что у синего цвета есть некоторая область значений на изображении (очевидно, это должно быть связано с небом).

2. Использование OpenCV

Что ж, здесь вы можете настроить значения гистограммы и ее ячеек, чтобы она выглядела как координаты x, y, чтобы вы могли использоватьcv.line() или функцию cv.polyline(), чтобы нарисовать его, чтобы получить то же изображение, что и выше. Официальный пример OpenCV-Python2 уже предоставляет эту функцию. Проверьте код в examples/python/hist.py.

применение маски

мы использовалиcv.calcHist()чтобы найти гистограмму всего изображения. Что делать, если вы хотите найти гистограмму определенных областей изображения?Просто создайте изображение-маску, где вы хотите найти гистограмму как белую, иначе как черную. Затем передайте это как маску.

img = cv.imread('home.jpg',0)
# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv.bitwise_and(img,img,mask = mask)
# 计算掩码区域和非掩码区域的直方图
# 检查作为掩码的第三个参数
hist_full = cv.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv.calcHist([img],[0],mask,[256],[0,256])
plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

Посмотреть Результаты. На гистограмме синяя линия представляет собой гистограмму полного изображения, а зеленая линия представляет собой гистограмму замаскированной области.

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

  1. Веб-сайт Cambridge in Color: http://www.cambridgeincolour.com/tutorials/histograms1.htm

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