图像数据处理10

灰度变换

2.4 图像直方图

2.4.1频数分布表与直方图

频数与相对灰度值:参考数学中的概念,一个灰度值的频数即为是该灰度值所有像素个数之,而相对灰度值则是用频数/所有像素个数。计算相对灰度值近和计算归一化一致。

比如一个图片共有100个像素,其中灰度值为3的像素共有45个,则它的频数为45,相对频率为0.45.

直方图特点:

①图像集中在左侧:意味着图像中大部分像素的灰度值较低,整体偏暗

②图像集中在右侧:意味着图像中大部分像素的灰度值较高,整体偏亮

③ 集中在某一狭小的范围内:意味着图像中的灰度值变化不大,整体对比度较低,特征不够清晰

④图像分布均匀:意味着图像中的灰度值在各个等级上都有较为均衡的分布,图像的细节特征较为清晰。

2.4.2分组频数直方图

把图像的灰度值按照从大到小的顺序排序后进行若干分组,随后算出每个分组中的所有像素数量之和,作为分组的频数

2.4.3累积直方图

用于计算图像中小于等于某灰度值的所有像素之和,其的函数图像单调递增。

2.4.4灰度直方图的计算

① NumPy

  • np.histogram()
    此函数用于计算数据集的直方图。它接收输入数组和指定的bin数量或范围,并返回直方图的统计数据和bin的边界。

  • np.cumsum()

  • 此函数用于计算数组的累积和,用其处以像素总数,可得出累积直方图

② Scikit-image

  • exposure.histogram()
    Scikit-image库中的此函数用于计算图像数组的直方图。它提供了多种参数来定制直方图的计算,例如指定bin的数量或范围。

  • exposure.cumulative_distribution()
    此函数用于计算图像数组的累积直方图。它返回一个数组,其中包含了每个bin的累积频率。这对于图像增强和直方图均衡等非常有用。

③ OpenCV

  • cv.calcHist()
    OpenCV库中的此函数用于计算图像数组的直方图。它提供了丰富的参数来控制直方图的计算,如指定要计算直方图的图像通道、掩码的使用、bin的数量和范围等。这使得cv.calcHist()成为一个非常灵活和强大的工具,适用于各种图像处理任务。

④ Matplotlib

  • plt.hist()
    此函数用于计算图像数组的直方图并将其显示出来。它接收输入数组和一系列参数来控制直方图的外观,如bin的数量、颜色、边界等。plt.hist()非常适合在数据处理和图像分析过程中快速查看数据的分布。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
from skimage import io, exposure, color

# 读取灰度图像
img_path = 'saved_image.jpg'
img = io.imread(img_path, as_gray=True)  # 使用skimage的io模块以灰度模式读取图像
img = img.astype(np.uint8)  # 将图像数据类型转换为无符号8位整数

# 利用Matplotlib计算灰度直方图
hist_mpl, bin_edges_mpl, patches = plt.hist(img.ravel(), bins=256, range=(0, 256))  # 计算并返回直方图

# 利用Scikit-image计算直方图
hist_sk, bin_centers = exposure.histogram(img, nbins=256, source_range='dtype')  # 计算图像的直方图
# 利用Scikit-image计算累积直方图
cdf_sk, bin_centers = exposure.cumulative_distribution(img, nbins=256)  # 计算图像的累积直方图

# 利用OpenCV计算灰度直方图
hist_cv = cv.calcHist([img], [0], None, [256], [0, 256]).ravel().astype(np.uint8)  # 计算图像的直方图并转换数据类型

# 利用NumPy计算直方图与累积直方图
hist_np, bin_edges = np.histogram(img, bins=256, range=(0, 256))  # 计算图像的直方图
cdf_np = np.cumsum(hist_np) / img.size  # 计算累积分布函数(CDF)

# 显示直方图
plt.figure(figsize=(10, 8))  # 创建一个新图形并设置大小

plt.subplot(2, 3, 1)  # 创建一个子图
plt.bar(bin_edges_mpl[:-1], hist_mpl, width=1, color='gray')  # 绘制Matplotlib直方图
plt.title('Matplotlib Histogram')  # 设置子图标题

plt.subplot(2, 3, 2)  # 创建另一个子图
plt.bar(bin_centers, hist_cv, width=1, color='gray')  # 绘制OpenCV直方图
plt.title('OpenCV Histogram')  # 设置子图标题

plt.subplot(2, 3, 3)  # 创建另一个子图
plt.bar(bin_edges[:-1], hist_np, width=1, color='gray')  # 绘制NumPy直方图
plt.title('NumPy Histogram')  # 设置子图标题

plt.subplot(2, 3, 4)  # 创建另一个子图
plt.bar(bin_centers, hist_sk, width=1, color='gray')  # 绘制Scikit-image直方图
plt.title('Scikit-image Histogram')  # 设置子图标题

plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()  # 显示图形

# 显示累积直方图(以柱状图形式)
plt.figure(figsize=(10, 4))  # 创建一个新图形并设置大小

# 为了绘制柱状图,我们需要确保x轴的值是像素强度,y轴的值是累积频率
plt.subplot(1, 2, 1)  # 创建一个子图
plt.bar(range(256), cdf_np * img.size, width=1, color='blue')  # 绘制NumPy累积直方图
plt.title('NumPy Cumulative Histogram (Bar Chart)')  # 设置子图标题
plt.xlabel('Pixel intensity')  # 设置x轴标签
plt.ylabel('Cumulative count')  # 设置y轴标签

plt.subplot(1, 2, 2)  # 创建另一个子图
plt.bar(range(256), cdf_sk * img.size, width=1, color='red')  # 绘制Scikit-image累积直方图
plt.title('Scikit-image Cumulative Histogram (Bar Chart)')  # 设置子图标题
plt.xlabel('Pixel intensity')  # 设置x轴标签
plt.ylabel('Cumulative count')  # 设置y轴标签

plt.tight_layout()  # 自动调整子图参数,使之填充整个图像区域
plt.show()  # 显示图形

注,本人为在校学生,博客是边学边写的,主要是为了巩固知识,如有错误请积极指正。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值