自定义直方图均衡化函数:
import math
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 计算图像灰度直方图
def calcGrayHist(image):
rows, cols = image.shape # 获取图像的行数和列数(高和宽)
grayHist = np.zeros([256], np.uint32) # 新建大小为256的一维数组,元素用0填充,用于存储直方图信息
# 计算灰度直方图
for r in range(rows):
for c in range(cols):
grayHist[image[r, c]] += 1
return grayHist
# 直方图均衡化
def equalHist(image):
rows, cols = image.shape # 获取图像的行数和列数(高和宽)
grayHist = calcGrayHist(image) # 获取图像的灰度直方图
zeroCumuMoment = np.zeros([256], np.uint32) # 新建数据,存储累加直方图信息
# 计算累加直方图
for p in range(256):
if p == 0:
zeroCumuMoment[p] = grayHist[0]
else:
zeroCumuMoment[p] = zeroCumuMoment[p - 1] + grayHist[p] # 累加
# 均衡化
outPut_q = np.zeros([256], np.uint8) # 存储均衡化后的新灰度级信息
cofficient = 256.0 / (rows * cols) # 映射工具(运算因子)
for p in range(256): # 映射
q = cofficient * float(zeroCumuMoment[p]) - 1 # q存储运算后的结果
if q >= 0:
outPut_q[p] = math.floor(q) # Math.floor(x)返回小于等于x的最大整数
else:
outPut_q[p] = 0
# 获取均衡化后的图像
equalHistImage = np.zeros(image.shape, np.uint8) # 存储均衡化后的图像
for r in range(rows):
for c in range(cols):
equalHistImage[r][c] = outPut_q[image[r][c]]
return equalHistImage
# 主函数
image = cv.imread('d:/exercise/lusi.jpg', 0) # 读入灰度图像
dst = equalHist(image) # 得到均衡化后的图像
print(dst)
cv.imshow('before', image) # 显示均衡化前图像
cv.imshow('after', dst) # 显示均衡化后图像
plt.figure('原始直方图')
plt.hist(image.ravel(), 256)
plt.figure('均衡化直方图')
plt.hist(dst.ravel(), 256)
plt.show() # 显示上面两个直方图
cv.waitKey()
cv.destroyAllWindows()
# opencv中的灰度图以uint8存储,3通道彩色图也是uint8,范围就是0~255
运行结果:
使用系统已定义好的均衡化函数:
均衡化函数,返回结果图像:
equ = cv.equalizeHist(image)
import cv2 as cv
import matplotlib.pyplot as plt
image = cv.imread('d:/exercise/lusi.jpg', 0) # 读入图像
cv.imshow('before', image) # 显示原始图像
equ = cv.equalizeHist(image) # 均衡化处理后的图像
cv.imshow('after', equ) # 显示均衡化后的图像
plt.figure('原始直方图')
plt.hist(image.ravel(), 256)
plt.figure('均衡化直方图')
plt.hist(equ.ravel(), 256)
plt.show() # 显示上面两个直方图
cv.waitKey()
cv.destroyAllWindows()
运行结果与上面的算法相同。
自适应直方图均衡化:
创建CLAHE对象:限制对比度为40,大小为8*8的矩阵:
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
执行自适应均衡化,返回结果图像:
dst = clahe.apply(image)
import cv2 as cv
import matplotlib.pyplot as plt
image = cv.imread('d:/exercise/lusi.jpg', 0) # 读入图像
cv.imshow('before', image) # 显示原始图像
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8)) # 创建CLAHE对象:限制对比度为40,大小为8*8的矩阵
dst = clahe.apply(image) # 自适应均衡化
cv.imshow('after', dst) # 显示自适应均衡化后的图像
plt.figure('原始直方图')
plt.hist(image.ravel(), 256)
plt.figure('均衡化直方图')
plt.hist(dst.ravel(), 256)
plt.show() # 显示上面两个直方图
cv.waitKey()
cv.destroyAllWindows()
运行结果: