第三节:对比度增强算法总结
一: 绘制直方图
就是把各个像素值所含有的个数统计出来,然后画图表示。 可以看到在当前图像中,哪个像素值的个数最多。 同时,可以看当前图像总体的像素值大小在哪些范围。。靠近0的话,说明图像偏暗。 靠近255,说明图像偏亮。
import cv2
import numpy as np
import matplotlib.pyplot as plt
import math
# # 绘制灰度直方图
def calcGrayHist(image):
'''
统计像素值
:param image:
:return:
'''
# 灰度图像的高,宽
rows, cols = image.shape
# 存储灰度直方图
grayHist = np.zeros([256], np.uint64)
for r in range(rows):
for c in range(cols):
grayHist[image[r][c]] += 1
return grayHist
image = cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
grayHist = calcGrayHist(image)
# 采用matplotlib进行画图
x_range = range(256)
plt.plot(x_range, grayHist, 'r', linewidth=2, c='black')
plt.show()
输出结果:
总的来说,还是偏暗 。像素值几种在40到50之间。
二: 通过线性变化增强对比度
Python实现
# 通过线性变化增强对比度
in_image =cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
a = 2
out_image = float(a) * in_image
# 进行数据截断, 大于255的值要截断为255
out_image[out_image > 255] = 255
# 数据类型转化
out_image = np.round(out_image)
out_image = out_image.astype(np.uint8)
# 显示原图像和线性变化后的结果
cv2.imshow('IN', in_image)
cv2.imshow('OUT', out_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
三: 通过直方图正规化增强对比度
Python代码实现:
# 通过直方图正规化增强对比度
in_image = cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
# 求输入图片像素最大值和最小值
Imax = np.max(in_image)
Imin = np.min(in_image)
# 要输出的最小灰度级和最大灰度级
Omin, Omax = 0, 255
# 计算a 和 b的值
a = float(Omax - Omin)/(Imax - Imin)
b = Omin - a* Imin
# 矩阵的线性变化
out_image = a*in_image + b
# 数据类型的转化
out_image = out_image.astype(np.uint8)
# 显示原图和直方图正规化的效果
cv2.imshow('IN', in_image)
cv2.imshow('OUT', out_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
四: 伽马变化
python实现:
# 伽马变换增强对比度
in_image = cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
# 图像归一化
fI = in_image/255.0
# 伽马变化
gamma = 0.5
out_image = np.power(fI, gamma)
# 显示原图和伽马变化后的效果
cv2.imshow('IN', in_image)
cv2.imshow('OUT', out_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果输出:
五: 全局直方图均衡化
Python代码实现:
def calcGrayHist(image):
'''
统计像素值
:param image:
:return:
'''
# 灰度图像的高,宽
rows, cols = image.shape
# 存储灰度直方图
grayHist = np.zeros([256], np.uint64)
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[0] = 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
if q >= 0:
output_q[p] = math.floor(q)
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 = cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
grayHist = equalHist(image)
cv2.imshow('origin_image', image)
cv2.imshow('equal_image', grayHist)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果:
六: 限制对比度的自适应直方图均衡化
Python代码:
# 限制对比度的自适应直方图均衡化
image = cv2.imread('p2.jpg', cv2.IMREAD_GRAYSCALE)
# 创建ClAHE对象
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
# 限制对比度的自适应阈值均衡化
dst = clahe.apply(image)
# 显示
cv2.imshow('src', image)
cv2.imshow('dst', dst)
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果: