Используйте OpenCV, Numpy для расчета гистограммы, Matplot для рисования гистограммы и анализа

задняя часть

Используйте OpenCV, Numpy для расчета гистограммы, Matplot для рисования гистограммы и анализа

В этом блоге рассказывается, как использовать функции Python, OpenCV, Numpy для расчета гистограмм, а также использовать функции OpenCV и Matplotlib для рисования и анализа гистограмм.

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

1. Рендеринг

Исходное изображение выглядит следующим образом:

在这里插入图片描述

Эффект гистограммы в оттенках серого выглядит следующим образом:

Вы можете видеть, что область слева показывает количество более темных пикселей в изображении, а область справа показывает количество более светлых пикселей. Из гистограммы видно, что темных участков, светлых участков не много, а количество полутонов (значения пикселей в среднем диапазоне, например, около 170/210) очень велико.

在这里插入图片描述 Эффект гистограммы трех каналов BGR выглядит следующим образом: 在这里插入图片描述 Исходное изображение VS Mask mask VS Mask image VS смешанная гистограмма выглядит следующим образом:На 4-й гистограмме синяя линия представляет собой гистограмму полного изображения, а красная линия — гистограмму замаскированной области.在这里插入图片描述

2. Принцип

Гистограмма может помочь получить полное представление о распределении интенсивности изображения.Самая простая гистограмма представляет собой гистограмму изображения в градациях серого, график со значениями пикселей (в диапазоне от 0 до 255) по оси x и соответствующим количеством пикселей в изображении по оси y.

3 способа расчета гистограммы:

  • hist = cv2.calcHist([img],[0],None,[256],[0,256])
  • hist,bins = np.histogram(img.ravel(),256,[0,256])
  • np.bincount(img.ravel(),minlength=256)

Метод cv2 в 40 раз быстрее, чем np.histogram;

np.bincount в 10 раз быстрее, чем np.histogram, поэтому предпочтительным является метод cv2.calHist();

2 способа нарисовать гистограмму:

  • matplot вычисляет гистограмму и рисует ее: plt.hist(img.ravel(),256,[0,256]); plt.show()
  • Простой метод рисования матплота: histr = cv2.calcHist([img],[i],None,[256],[0,256]) plt.plot (истр, цвет = столбец) plt.xlim([0,256])

3. Исходный код

3.1 3 метода расчета и 2 метода построения гистограммы

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('ml.jpg', 0)

# cv计算直方图
# cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])
# - img:要计算直方图的图像
# - channels:通道值,如果传入灰度图为0,彩色图[0][1][2]分别计算BGR通道
# - mask:蒙版,并非为整个图计算直方图
# - histSize:x轴分多少个范围
# - ranges: 值的范围,通常是[0,256]
hist = cv2.calcHist([img], [0], None, [256], [0, 256])

# numpy计算直方图
#  np.bincount() 比 np.histogram() 大概快10倍
#  cv2.calHist() 比 np.histogram() 大概快40倍
hist, bins = np.histogram(img.ravel(), 256, [0, 256])
hist = np.bincount(img.ravel(), minlength=256)

# 绘制直方图法1:matplot
img = cv2.imread('ml.jpg', 0)
plt.hist(img.ravel(), 256, [0, 256])
plt.show()

# 绘制直方图法2:matplot普通绘制方式
img = cv2.imread('ml.jpg')
color = ('b', 'g', 'r')
for i, col in enumerate(color):
    histr = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(histr, color=col)
    plt.xlim([0, 256])
plt.show()

3.2 Гистограмма изображения маски

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('ml.jpg', 0)

# 构造一个mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img, img, mask=mask)

# 计算整个图直方图以及mask的直方图
hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_mask = cv2.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, color='b'), plt.plot(hist_mask, color='r')
plt.xlim([0, 256])

plt.show()

Ссылаться на