图像的直方图:
直方图是图像中像素值分布的图形表达方式。它统计了每一个颜色值在图像中出现的个数。
直方图是用来统计一维数据的统计方式,所以一般要把图像转换为灰度图或者YUV图取一个元素进行直方图计算展示。
在应用上,直方图一般用来查看图像曝光度如何来进行适当的调整;或者可以对颜色区域比较接近的图像通过拉伸颜色范围来进行提高图像内容的对比度(直方图均衡化处理)
直方图的实现方式:
方式1:利用matplotlib提供的工具函数实现
import cv2
import dlib
from matplotlib import pyplot as plt
import numpy as np
image = cv2.imread("lena.tiff");
gray1 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
plt.hist(gray1.ravel(), 256, [0, 256])
plt.show()
方式2:利用cv2的函数实现
image = cv2.imread("lena.tiff");
gray1 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
hist = cv2.calcHist([gray1], [0], None, [256], [0, 256])
plt.figure()
plt.plot(hist)
plt.show()
方式3:自定义实现
import cv2
import dlib
from matplotlib import pyplot as plt
import numpy as np
def calHist(img):
# hist = np.arange(256)
# for i in hist:
# hist[i] = 0
hist = np.zeros(256)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
for i in range(0,width):
for j in range(0,height):
r = img[i,j]
hist[r] = hist[r]+1
return hist;
image = cv2.imread("lena.tiff");
gray1 = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
histData = calHist(gray1);
plt.figure()
plt.plot(histData)
plt.show()
效果图:
后面涉及到的累计直方图效果图:
递增,最大值为1…
默默的引进直方图均衡化概念:
直方图均衡化的作用:使得图像灰度级跨越更宽的灰度级范围,从而提高图像对比度;
直方图均衡化的另一个优势是:不需要额外参数,整个过程是自动的;
直方图均衡化的缺点是:拉伸后有些灰度级可能不被映射到,造成图像观感上的颗粒感;
直方图均衡化流程:
a.求灰度图的直方图,结果为有256个元素的数组
b.求每一个颜色值在图像中出现的频率(次数),然后归一化(除以总像素个数)
c.求每一个颜色值次数的累计分布函数
d.求出直方图均衡化计算公式,求出颜色映射表lut
e.根据d求出的lut对原始灰度图做颜色映射,得出直方图均衡化后的效果图
equ = cv2.equalizeHist(img)
cv2.imshow('equalization', np.hstack((img, equ))) # 并排显示
cv2.waitKey(0)
附算法代码:
import cv2
import dlib
from matplotlib import pyplot as plt
import numpy as np
#note:参数必须为灰度图,未对其他格式图做兼容处理
def histogram_equalization(grayImage):
hist = np.zeros(256)
histLut = np.zeros(256)
imgInfo = grayImage.shape
height = imgInfo[0]
width = imgInfo[1]
for i in range(0, width):
for j in range(0, height):
r = grayImage[i, j]
hist[r] = hist[r] + 1
index = 0
while hist[index] < 0:
++index;
pixelCount = width * height
scale = (256 - 1.) / (pixelCount - hist[index]);
sum = 0
for i in range(index, hist.size):
sum = sum + hist[i]
histLut[i] = (sum * scale + 0.5)
dst = np.zeros((height, width, 3), np.uint8)
for u in range(0, width):
for v in range(0, height):
c = histLut[grayImage[u, v]]
dst[u, v] = [c, c, c]
return dst
image = cv2.imread("lena.tiff");
gray1 = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray',histogram_equalization(gray1))
效果图:
灰度图:
均衡化后的灰度图:
直方图均衡化已知的方法有个缺点,均衡化会对图像全局做亮度对比度调整,这样会造成原本比较亮的地方更亮,丢失亮度比较高的部分的细节。如下图,雕像人脸在均衡化后变得整个太白了。这时候就需要做优化了。
参考:https://www.jianshu.com/p/19ff65ac3844
自适应均衡化就是用来解决这一问题的:它在每一个小区域内(默认8×8)进行直方图均衡化。当然,如果有噪点的话,噪点会被放大,需要对小区域内的对比度进行了限制,所以这个算法全称叫:对比度受限的自适应直方图均衡化CLAHE Contrast Limited Adaptive Histogram Equalization
# 自适应均衡化,参数可选
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
cl1 = clahe.apply(img)
自适应均衡化效果图:(阔以发现雕像人脸可以看清细节了,其他地方也都提高对比度了,优秀的算法?)
总结对比图:
参考链接:
https://baike.baidu.com/item/概率密度函数/5021996
https://baike.baidu.com/item/累积分布函数/7763383?fr=aladdin
https://www.cnblogs.com/yoyo-sincerely/p/6159101.html
https://blog.csdn.net/xuan_zizizi/article/details/82747897
https://blog.csdn.net/fengbingchun/article/details/79188021
https://blog.csdn.net/piaoxuezhong/article/details/78269439
https://www.jianshu.com/p/19ff65ac3844
直方图相机相关介绍
https://baijiahao.baidu.com/s?id=1621984130964189747&wfr=spider&for=pc