Histogram & Histogram Equalization

Histogram definition

hist = cv2.calcHist(images, channels, mask, histSize, ranges, …) # hist is a 256*1 matrix, where each value represents the number of pixels corresponding to a gray value

  • images: The original image format is uint8 or float32; when passing in the function, brackets should be used, such as [img]
  • channels: Also enclosed in square brackets, it will tell the function to count the image channels of the histogram; if the input is a grayscale image, its value is [0], if the input is a color image, its value can be It is [0], [1], [2], corresponding to BGR respectively
  • mask: mask image, if the statistics are the whole image, its value is None
  • histSize: The number of BINs, which should also be enclosed in square brackets
  • ranges: pixel value range, generally [0, 256], left closed and right open

plt.hist(x, bins=None, range=None, …) # Histogram, a special histogram

  • x: The data required for the histogram must be a one-dimensional array. Multi-dimensional arrays can be flattened before drawing
  • bins: the number of columns in the histogram, that is, the number of groups to be divided into, the default is 10
  • range: tuple or None, if None, the default is (x.min(), x.max()), which is the range of the x-axis
import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'F:/aixin.jpg', 0)  # 0表示灰度图
plt.hist(img.ravel(), 256)  # 横轴表示数值(这里是像素值),纵轴表示一个数值出现的次数;img.ravel()可以将二维矩阵img展平成一维数组
plt.show()

insert image description here

import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'F:/aixin.jpg')
color = ('b', 'g', 'r')

for i, col in enumerate(color):
    hist = cv2.calcHist([img], [i], None, [256], [0, 256])
    plt.plot(hist, col)
    plt.xlim([0, 256])

plt.show()

insert image description here

mask operation

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

img = cv2.imread(r'F:/aixin.jpg', 0)  # 0表示灰度图
mask = np.zeros(img.shape[:2], np.uint8)  # 创建一个与二维图像shape相同的0值矩阵
mask[350:700, 350:700] = 255  # 将mask的一部分赋值为255,[H, W]
masked_img = cv2.bitwise_and(img, img, mask=mask)  # 与操作

plt.subplot(1, 3, 1)
plt.axis('off')  # 设置无坐标
plt.title('source')
plt.imshow(img, 'gray')  # 以灰度方式呈现

plt.subplot(1, 3, 2)
plt.axis('off')
plt.title('mask')
plt.imshow(mask, 'gray')

plt.subplot(1, 3, 3)
plt.axis('off')
plt.title('masked_img')
plt.imshow(masked_img, 'gray')

plt.show()

insert image description here

hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])
hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])

plt.plot(hist_full, 'b')
plt.plot(hist_mask, 'g')

plt.show()

insert image description here

Histogram equalization

The pixel distribution of image A is as follows:

insert image description here

Equalization process:

grayscale value Number of pixels probability cumulative probability The gray value after mapping according to the function Rounding
50 4 0.25 0.25 0.25*(255-0)=63.75 64
128 3 0.1875 0.4375 0.4375*(255-0)=111.5625 112
200 5 0.3125 0.75 0.75*(255-0)=191.25 191
255 4 0.25 1 1*(255-0)=255 255

The pixel distribution of image B obtained after equalization is as follows:

insert image description here

equalization effect

import cv2
import matplotlib.pyplot as plt

img = cv2.imread(r'F:/aixin.jpg', 0)  # 0表示灰度图
equ = cv2.equalizeHist(img)  # 均衡化

plt.subplot(1, 2, 1)
plt.title('source')
plt.hist(img.ravel(), 256)

plt.subplot(1, 2, 2)
plt.title('equalized')
plt.hist(equ.ravel(), 256)

plt.show()

insert image description here

res = cv2.hconcat((img, equ))

cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

insert image description here

Adaptive Histogram Equalization

The global equalization of equalizeHist also has some problems. Due to the improvement of the overall brightness, the details of the local image may be blurred. Therefore, sometimes we need to perform a local equalization operation of blocks, which is called an adaptive histogram. equalization.

clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None) # adaptive histogram equalization
cla = clahe.apply(img)

  • clipLimit: contrast limit threshold
  • tileGridSize: The input image will be split into rectangular blocks of equal size, tileGridSize defines the number of blocks in rows and columns
img = cv2.imread(r'F:/aixin.jpg', 0)  # 原图
equ = cv2.equalizeHist(img)  # 均衡化(全局均衡化)
clahe = cv2.createCLAHE(clipLimit=2, tileGridSize=(8, 8))  # 自适应均衡化(分块均衡化)
cla = clahe.apply(img)

res = cv2.hconcat((img, equ, cla))

cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

insert image description here

Guess you like

Origin blog.csdn.net/weixin_48158964/article/details/131722343