1#coding:utf-8 2''' 3直方图均衡化 4作用:通常用来增加图像局部对比度,尤其在图像的有用数据的对比度相当 5 接近时,通过直方图均衡化,图像的亮度可以更好地在直方图上分布 6基本思想:把原始图像的直方图变换为均匀分布的形式,增加了像素 7 灰度值的动态范围,从而增强图像的整体对比度效果 8 9算法实现步骤: 101、计算图像f的各个灰度级中像素出现的概率 11 p(i) = n(i) / n ,{i|0,1,...,L - 1} 12 其中:n(i)表示灰度级i出现的次数,L是图像中所有的灰度数,p实际上是图像的 13 直方图归一化到0~1范围内,如果把c作为对应p的累计概率函数,则定义为: 14 i 15 c(i) = ∑(p(x(j)) 16 j=0 17 c是图像的累计归一化直方图 18 192、创建一个形式为 y = T(x)的变化,原始图像中的每个值就生产一个y,这样 20 y的累计概率函数形式就可以在所有值范围内进行线性化,转换公式为: 21 y(i) = T(x(i)) = c(i) 22''' 23 24import cv2 25import numpy as np 26 27def hist_eq(image): 28 img_gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) 29 rows,cols = img_gray.shape 30 gray_flat = img_gray.reshape((rows*cols,)) 31 dist_flat = np.zeros_like(gray_flat) 32 33 count_pixel = np.zeros((256,),np.int32) 34 temp = np.zeros((256,),np.int32) 35 pixmap = np.zeros((256,),np.uint8) 36 image_bytes = cols * rows 37 # 计算各个灰度级数量 38 for index,value in enumerate(gray_flat): 39 count_pixel[value] += 1 40 41 # 计算灰度级的累计分布 42 for i in range(256): 43 if i == 0: 44 temp[0] = count_pixel[0] 45 else: 46 temp[i] = temp[i - 1] + count_pixel[i] 47 48 # 计算累计概率函数,并把值扩展到0~255 49 value = 255.0 * (temp[i] / image_bytes) 50 if value > 255: 51 value = 255 52 if value < 0: 53 value = 0 54 pixmap[i] = value 55 56 # 灰度等级映射转换 57 for i in range(image_bytes): 58 dist_flat[i] = pixmap[gray_flat[i]] 59 60 dist = dist_flat.reshape((rows,cols)) 61 62 return dist 63 64src = cv2.imread('datas/l1.jpg') 65gray = cv2.cvtColor(src,cv2.COLOR_RGB2GRAY) 66 67dist = hist_eq(src) 68 69# 调用OpenCV函数 70dist_cv = np.zeros_like(gray) 71cv2.equalizeHist(gray,dist_cv) 72 73cv2.imshow('src',gray) 74cv2.imshow('dist',dist) 75cv2.imshow('opencv-histeq',dist_cv) 76cv2.waitKey() 77cv2.destroyAllWindows()
