第三节:对比度增强算法总结

一: 绘制直方图

        就是把各个像素值所含有的个数统计出来,然后画图表示。 可以看到在当前图像中,哪个像素值的个数最多。 同时,可以看当前图像总体的像素值大小在哪些范围。。靠近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()

输出结果: