提高图像对比度---直方图均衡化

238 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

在做瑕疵检测时,往往需要对拍摄后的图像进行增强,从而提高感兴趣区域的可区分性,为了提高目标区域的可区分性,提高图像的对比度是非常必要的,在灰度图像中,在一定程度上提高目标区域的像素值,在后面的边缘检测、阈值分割时就相对容易检测出完成的目标轮廓。

所以直方图均衡化是非常必要的存在,首先灰度直方图反应的是每个灰度级集中像素的分布范围,均衡化目的是提高图像的对比度,其原理是将原来的灰度值通过一系列映射,将其灰度值提高的一种方式,在背景复杂度较低的图像中,使用均衡化会获得较好的收益。

下面是对灰度图像进行均衡化的代码

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import time


print(time.time())
IN_FILE = "../img0/edge_red.bmp"
OUT_FILE = "./resultImage/hist_process.jpg"

def make_histogram(img):
    # 给灰度图像创建直方图
    histogram = np.zeros(256, dtype=int)
    for i in range(img.size):
        histogram[img[i]] += 1
    return histogram


def make_cumsum(histogram):
    # 创建一个表示直方图累积和的数组
    cumsum = np.zeros(256, dtype=int)
    cumsum[0] = histogram[0]
    for i in range(1, histogram.size):
        cumsum[i] = cumsum[i-1] + histogram[i]
    return cumsum


'''
    创建映射,将每个原来灰度值映射到新的灰度值(0到255之间)。
    - M(i) = max(0, round((grey_levels*cumsum(i))/(h*w))-1)
'''
def make_mapping(cumsum):
    mapping = np.zeros(256, dtype=int)
    grey_levels = 256
    for i in range(grey_levels):
        mapping[i] = max(0, round((grey_levels*cumsum[i])/(IMG_H*IMG_W))-1)
    return mapping


def apply_mapping(img, mapping):
    new_image = np.zeros(img.size, dtype=int)
    for i in range(img.size):
        new_image[i] = mapping[img[i]]
    return new_image

pillow_img = Image.open(IN_FILE)
IMG_W, IMG_H = pillow_img.size
img = np.array(pillow_img).flatten()
histogram = make_histogram(img)
cumsum = make_cumsum(histogram)
mapping = make_mapping(cumsum)
new_image = apply_mapping(img, mapping)
output_image = Image.fromarray(np.uint8(new_image.reshape((IMG_H, IMG_W))))
output_image.save(OUT_FILE)
# 将均衡化前后的直方图分布进行对比
x_axis = np.arange(256)
fig = plt.figure()
fig.add_subplot(1, 2, 1)
plt.bar(x_axis, histogram)
fig.add_subplot(1, 2, 2)
plt.bar(x_axis, make_histogram(new_image), color="orange")
plt.show()
print(time.time())

上述代码执行过程中存在像素便利情况,因此耗时有点高,在1920x1200大小的图像中进行实验,需要两秒多钟的时间,如下图所示,为程序运行前后的时间戳

image.png

程序运行的效果如下,首先是直方图均衡化前后的处理效果对比

image.png

前面蓝色表示处理前直方图的统计结果,橙色表示处理后的直方图统计结果。在处理后,图像灰度值分布更加均匀,整体的对比度得到提升,对于图像整体看起来较暗时,处理完成后其效果为图像显得更加明亮。