hist = cv2.calcHist(images, channels, mask, histSize, ranges, …) # hist是一个256*1的矩阵,其中每一个值代表了一个灰度值对应的像素点数目
plt.hist(x, bins=None, range=None, …) # 直方图,一种特殊的柱状图
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()
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()
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()
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()
图像A的像素分布如下所示:
均衡化过程:
灰度值 | 像素个数 | 概率 | 累积概率 | 根据函数映射后的灰度值 | 取整 |
---|---|---|---|---|---|
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 |
均衡化后得到的图像B的像素分布如下所示:
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()
res = cv2.hconcat((img, equ))
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
equalizeHist这种全局的均衡化也会存在一些问题,由于整体亮度的提升,可能会使得局部图像的细节变得模糊,因此有时我们需要进行分块的局部均衡化操作,称之为自适应直方图均衡化。
clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None) # 自适应直方图均衡化
cla = clahe.apply(img)
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()