Python从0到100(七十六):计算机视觉-直方图和自适应直方图均衡化

举报
是Dream呀 发表于 2024/12/21 13:17:40 2024/12/21
【摘要】 Python从0到100(七十六):计算机视觉-直方图和自适应直方图均衡化(文末送书)

在这里插入图片描述

前言: 零基础学Python:Python从0到100最新最全教程 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能相关知识,成为学习学习和学业的先行者!
欢迎大家订阅专栏:零基础学Python:Python从0到100最新最全教程!

均衡化是数字图像处理中常用的一种技术,用于增强图像的视觉效果和对比度。,今天我们将实现对同一张图像的直方图均衡化自适应直方图均衡化处理,学习一下两者的的基本原理和实现过程,一起来看看吧~

一、直方图均衡化

直方图均衡化(Histogram Equalization)是一种图像处理技术,通过重新分配图像灰度级别来增强图像的对比度和视觉效果。它基于整个图像的灰度直方图来调整像素的灰度值分布。通过增加较暗区域的亮度和减少较亮区域的亮度,直方图均衡化可以使图像的灰度级别分布更均匀,从而增强图像的细节和对比度。

1.得到灰度图

通过三同道的彩色图生成单通道的灰度图
首先,我们使用PIL库中的Image.open()函数读取彩色图像,并将其转换为数组。然后,我们获取图像的高度和宽度,并创建一个与原始图像大小相同、数据类型为uint8的全黑数组gray_img,用于保存灰度图像。

接着,我们遍历每个像素,将三个通道的值求平均,并将结果保存到灰度图像中。由于RGB图像的三个通道具有相同的权重,因此将三个通道的值求平均可以得到一个比较准确的灰度值。

然后,我们将灰度图像转换为PIL图像对象,并使用Matplotlib库中的plt.imshow()函数显示彩色图像和灰度图像。最后,我们使用PIL库中的Image.save()函数将灰度图像保存为文件。

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

# 读取彩色图像
img = Image.open('image.jpg')

# 将图像转换为数组
img_arr = np.array(img)

# 获取图像的高度和宽度
h, w, _ = img_arr.shape

# 创建一个新的数组,用于保存灰度图像
gray_img = np.zeros((h, w), dtype=np.uint8)

# 遍历每个像素,将三个通道的值求平均,并保存到灰度图像中
for i in range(h):
    for j in range(w):
        gray_img[i, j] = int(np.mean(img_arr[i, j]))

# 将灰度图像转换为PIL图像对象
gray_pil_img = Image.fromarray(gray_img)
plt.imshow(img)
plt.title('imge')
plt.axis('off')
plt.show()
plt.imshow(gray_pil_img, cmap='gray')
plt.title('gray_pil_imge')
plt.axis('off')
plt.show()
# 保存灰度图像
gray_pil_img.save('gray_image.jpg')

在这里插入图片描述
在这里插入图片描述

2. 直方图统计

使用PIL库中的Image.open()函数读取灰度图像,并使用convert('L')方法将图像转换为灰度模式。然后,我们获取图像的宽度和高度,并创建一个长度为256的全0列表hist,用于保存直方图统计结果。

接着,遍历每个像素,获取其灰度值,并将对应的直方图计数器加1。最后,我们输出直方图统计结果,即每个灰度值出现的像素数。

# 读取灰度图像
gray_img = Image.open('gray_image.jpg').convert('L')
width, height = gray_img.size

# 统计直方图
hist = [0] * 256
for y in range(height):
    for x in range(width):
        pixel = gray_img.getpixel((x, y))
        hist[pixel] += 1
print(hist)
# 输出直方图统计结果
for i in range(len(hist)):
    print("灰度值 %d: %d 个像素" % (i, hist[i]))

在这里插入图片描述

3. 绘制直方图

# 绘制直方图
plt.bar(range(256), hist)
plt.show()

在这里插入图片描述

4. 直方图均衡化

使图片有更好的视觉效果,有更高的对比度,即像素的灰度分布更平均
首先,我们使用PIL库中的histogram()函数对灰度图像进行直方图统计,得到一个长度为256的列表equ_img,其中每个元素表示对应灰度级别的像素数量。

接着,我们创建一个空列表lut,用于保存灰度级别的映射表。然后,通过遍历equ_img列表,将每个灰度级别的像素数量除以255得到一个步长step,表示每个灰度级别在均衡化后的直方图中所占的比例。接下来,我们定义一个变量n,初始化为0,用于记录当前累积的像素数量。

在内层循环中,我们遍历256个灰度级别,并将当前累积的像素数量除以步长step得到一个映射值n / step。这个映射值表示当前灰度级别在均衡化后的直方图中所对应的灰度级别。

最后,我们使用PIL库中的point()方法,根据映射表lut将灰度图像进行映射,得到均衡化后的图像equ_img。在这里,lut列表中的值被用作灰度级别的映射,'L'参数表示输出图像的模式为灰度模式。

这样,经过直方图均衡化处理后,图像的灰度分布将更加均匀,增强了图像的对比度和细节。

# 直方图均衡化
equ_img = gray_img.histogram()
lut = []
for b in range(0, len(equ_img), 256):
    step = sum(equ_img[b:b+256]) / 255
    n = 0
    for i in range(256):
        lut.append(n / step)
        n += equ_img[b+i]
equ_img = gray_img.point(lut, 'L')

# 显示原始图像和均衡化后的图像
plt.imshow(gray_img, cmap='gray')
plt.title('Original Image')
plt.axis('off')
plt.show()

plt.imshow(equ_img, cmap='gray')
plt.title('Equalized Image')
plt.axis('off')
plt.show()

# 保存原始图像和均衡化后的图像
gray_img.save('Original.jpg')
equ_img.save('Equalized.jpg')

# 统计均衡化后的直方图
hist_equ = equ_img.histogram()

# 绘制均衡化前后的直方图
plt.hist(gray_img.histogram(), 256, [0, 256])
plt.title('Original Image')
plt.xlim([0, 256])
plt.show()

plt.hist(hist_equ, 256, [0, 256])
plt.title('Equalized Image')
plt.xlim([0, 256])
plt.show()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、自适应直方图均衡化

自适应直方图均衡化(Adaptive Histogram Equalization)是直方图均衡化的一种变体,它考虑到图像中不同区域的局部差异。与直方图均衡化不同,自适应直方图均衡化将图像分成多个小块,并在每个小块内独立地应用直方图均衡化。通过这种方式,自适应直方图均衡化可以更好地保留图像的细节,并避免过度增强噪声。自适应直方图均衡化可以根据图像的局部特征自动调整每个小块的灰度级别,以实现更精细的图像增强。

1.自适应直方图均衡化(AHE)

AHE是一种局部直方图均衡化方法,它将图像分成若干个小区域,对每个小区域进行直方图均衡化处理,从而增强图像的对比度。该算法的核心思想是在每个小区域内计算直方图,并将其变换为累积分布函数(CDF),然后将CDF拉伸以增加对比度。因此,AHE可以有效地增强图像中的局部细节信息。
在此处,我们的输入参数包括原始图像img和窗口大小window_size。首先,函数遍历每个像素,获取以该像素为中心的大小为window_size的窗口。如果窗口越界,则跳过该像素。然后,计算窗口的直方图,并计算其累积分布函数。接着,将CDF归一化并拉伸,以增加窗口内像素的对比度。最后,将均衡化后的像素值放回原图中,得到均衡化后的结果。

# 自适应直方图均衡化(AHE)
def adaptive_histogram_equalization(img, window_size):
    # 获取图像大小
    height, width = img.shape[:2]
    # 创建一个全黑的图像
    result = np.zeros((height, width), dtype=np.uint8)
    # 遍历每个像素
    for i in range(height):
        for j in range(width):
            # 获取窗口中心点
            center_x, center_y = i + window_size // 2, j + window_size // 2
            # 如果窗口越界,则跳过
            if center_x < window_size // 2 or center_x >= height - window_size // 2 or center_y < window_size // 2 or center_y >= width - window_size // 2:
                continue
            # 获取窗口
            window = img[center_x - window_size // 2:center_x + window_size // 2 + 1, center_y - window_size // 2:center_y + window_size // 2 + 1]
            # 计算窗口的直方图
            hist, _ = np.histogram(window.ravel(), 256, [0, 256])
            # 计算累积分布函数
            cdf = hist.cumsum()
            # 归一化
            cdf_normalized = cdf * 255 / cdf[-1]
            # 将均衡化后的像素值放回原图中
            result[i][j] = cdf_normalized[img[i][j]]
    return result

2.限制对比度自适应直方图均衡化(CRHE)

CRHE是在AHE的基础上增加了对比度限制。它通过在AHE之后对像素值进行限制,以避免过度增加对比度而导致噪声的出现。该算法的核心思想是先使用AHE增强图像的对比度,然后使用限制对比度的方法对像素值进行截断,从而控制对比度的增加。
在代码中,输入参数包括原始图像img、窗口大小window_size和对比度限制因子clip_limit。首先,调用自己实现的自适应直方图均衡化函数adaptive_histogram_equalization对原始图像进行直方图均衡化处理,得到均衡化后的结果。接着,使用OpenCV库中的cv2.createCLAHE函数创建一个限制对比度的CLAHE对象,并将均衡化后的图像作为输入进行处理。

# 限制对比度自适应直方图均衡化(CRHE)
def contrast_limited_adaptive_histogram_equalization(img, window_size, clip_limit):
    # 使用自己实现的自适应直方图均衡化
    ahe_img = adaptive_histogram_equalization(img, window_size)
    # 使用OpenCV库实现限制对比度自适应直方图均衡化
    clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(window_size, window_size))
    result = clahe.apply(ahe_img)
    return result

3.读取图片

# 读取图片
img = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)

4.自适应直方图均衡化

首先创建一个与原始图像img相同大小的全黑图像ahe_result,用于保存处理后的结果。然后,使用一个循环遍历多个窗口尺寸,依次调用自适应直方图均衡化函数adaptive_histogram_equalization对原始图像进行处理,并将处理后的结果加到ahe_result中。最后得到多个尺寸的均衡化结果的平均值,作为最终的均衡化结果。

我们使用了不同尺寸的窗口,分别为50、100、150和200。最后将这四个结果取平均值作为最终结果,这种方法可以提高均衡化的效果,因为不同尺寸的窗口可以捕捉到图像中不同尺度的局部细节信息,从而增强图像的对比度和细节信息,避免过大或过小的窗口对结果产生较大影响。

# 自适应直方图均衡化
# 创建一个和原始图像大小相同的全零数组ahe_result,用于存储最终的自适应直方图均衡化结果

ahe_result = np.zeros_like(img)

# 遍历不同的窗口大小,从50到200,步长为50
for window_size in range(50, 201, 50):
    # 对原始图像img进行自适应直方图均衡化操作,使用当前窗口大小window_size
    ahe_img = adaptive_histogram_equalization(img, window_size)
    # 将每次处理后的图像ahe_img累加到ahe_result中
    ahe_result += ahe_img

# 将ahe_result除以4取整,得到最终的自适应直方图均衡化结果
ahe_result //= 4

5.限制对比度自适应直方图均衡化

首先创建一个与原始图像img相同大小的全黑图像crhe_result,用于保存处理后的结果。然后,使用一个循环遍历多个窗口尺寸,依次调用限制对比度自适应直方图均衡化函数对原始图像进行处理,并将处理后的结果加到crhe_result中。在本例中,设置对比度限制因子clip_limit为2.0。
我们使用了不同尺寸的窗口,分别为50、100、150和200。最后将这四个结果取平均值作为最终结果,避免过大或过小的窗口对结果产生较大影响。

# 限制对比度自适应直方图均衡化
# 创建一个和原始图像大小相同的全零数组crhe_result,用于存储最终的限制对比度自适应直方图均衡化结果

crhe_result = np.zeros_like(img)

# 遍历不同的窗口大小,从50到200,步长为50
for window_size in range(50, 201, 50):
    # 对原始图像img进行限制对比度自适应直方图均衡化操作,使用当前窗口大小window_size和对比度限制参数2.0
    crhe_img = contrast_limited_adaptive_histogram_equalization(img, window_size, 2.0)
    # 将每次处理后的图像crhe_img累加到crhe_result中
    crhe_result += crhe_img

# 将crhe_result除以4取整,得到最终的限制对比度自适应直方图均衡化结果
crhe_result //= 4

6.可视化显示结果

# 显示结果
fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(12, 8))
ax[0].imshow(img, cmap='gray')
ax[0].set_title('Original1 Image')
ax[1].imshow(ahe_result, cmap='gray')
ax[1].set_title('AHE1 Image')
ax[2].imshow(crhe_result, cmap='gray')
ax[2].set_title('CRHE1 Image')
plt.show()

在这里插入图片描述

三、对比总结

直方图均衡化(Histogram Equalization)和自适应直方图均衡化(Adaptive Histogram Equalization)都是用于图像增强的技术,目的是改善图像的对比度和视觉效果。它们的主要区别在于处理图像的方式和局部性

直方图均衡化是一种全局的方法,它基于整个图像的灰度直方图来调整像素的灰度值分布。通过使灰度级别在图像中更均匀地分布,直方图均衡化可以增强图像的对比度和细节。它使用累积分布函数将原始图像中的灰度级别映射到一个新的灰度范围,从而实现图像的均衡化。

然而,直方图均衡化是一种全局的方法,它没有考虑到图像中不同区域的局部差异。这可能会导致图像的某些区域过度增强或细节丢失的问题。为了解决这个问题,自适应直方图均衡化应运而生。

自适应直方图均衡化是一种局部的方法,在处理图像时会考虑到不同区域的灰度分布情况。它将图像分成许多小区域,对每个区域独立地应用直方图均衡化。通过这种方式,自适应直方图均衡化可以更好地保留图像细节,并避免过度放大噪声。

自适应直方图均衡化的一种常见变体是自适应直方图均衡化(CLAHE),它在每个小区域中使用对比度限制来防止过度放大噪声。CLAHE的核心思想是将图像分成许多小块,然后对每个小块进行局部直方图均衡化,并对像素值进行裁剪以限制对比度的增强程度。通过这种方式,CLAHE在增强图像细节的同时有效控制了噪声的增强。

总而言之,直方图均衡化是一种全局的方法,通过整个图像的灰度直方图来增强图像对比度。自适应直方图均衡化是一种局部的方法,通过对图像的小块进行独立的直方图均衡化来增强图像,并通过对比度限制来控制噪声的放大

文末送书

Dream送书活动——第四十八期
《AI数字人直播带货攻略》免费包邮送三本! 参与方式:

1.点赞收藏文章
2.在评论区留言:人生苦短,我用Python!(多可评论三条)
3.随机抽取3位免费送出!
4.截止时间: 2024-12-13
5.上期中奖名单:,请三天内私信我提供获奖信息

本期推荐:
《AI数字人直播带货攻略》
系统讲解AI数字人的使用技巧,让人工智能帮你24小时不间断直播,提高工作效率、节约运营成本,为企业带来更高的经济效益。在这里插入图片描述

京东:https://item.jd.com/14323363.html

全面深入,系统布局:本书全面深入地探讨了AI数字人直播带货,结构清晰,章节分明,帮助读者系统构建相关知识体系。
创新视角,实战导向:本书紧跟AI技术潮流,引入前沿科技,结合实战案例,让读者掌握理论并灵活应用于实际工作。
高效经济,广泛适用:本书强调AI数字人助力高效直播,降低成本,无论新手还是老手,都能从中受益,取得成功。
本书讲解了AI数字人在直播带货领域的应用。通过对本书的学习,电商从业者不仅可以通过AI数字人进行24小时不间断的直播带货,提高工作效率,还能通过AI技术提升运营技能,为企业节约运营成本。
本书共分为8章,主要内容包括AI数字人直播带货新模式、AI数字人直播带货的技术实现、搭建自己的AI数字人直播间、AI直播带货选品策略、AI直播带货话术设计、AI直播带货脚本设计、AI数字人直播带货营销策略、AI数字人直播带货实战指南等。
本书由AI数字人直播带货培训团队组织编写,具有丰富的实战经验,具有超强的适用性和可操作性,案例丰富,讲解思路清楚,是一本AI数字人直播带货应用实践手册,非常适合新媒体直播电商从业者,以及想进入直播电商行业通过直播进行带货的从业者学习和参考。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。