opencv-python学习笔记5-灰度变换和直方图修正

目录

一、点运算:

 (1)点运算的基本概念:

a.基于灰度值的操作:

b.数学模型:

c.饱和运算与模运算:

d.点运算的类型:

e.应用:

 (2)点运算的目标与分类 :

a.目标:

b.分类:

(3)点运算的特点和应用 :

a.特点:

b.应用:

 二、灰度变换:

(1)灰度变换的基本概念:

(2)灰度变换的作用:

(3)灰度变换的方法:

(4)灰度化:

(5)对比度:

(6)灰度的线性变换:

 (7)分段式线性变换:

 (8)对数变换和反对数变换:

(9)幂律变换: 

 三、直方图修正:

(1)直方图的概念:

(2)绘制BRG直方图:

 (3)原始计算灰度直方图的方法:

(4)直方图均衡化:                

(5)灰度直方图均衡化:

​编辑(6)彩色图像直方图均衡化:                                                                                         


一、点运算:

        点运算,也称为像素级运算或灰度变换,是数字图像处理中的一类基本操作。它们直接作用于图像的每一个像素点,通过改变像素的灰度值来实现图像的变换或增强。

 (1)点运算的基本概念:

a.基于灰度值的操作:
  • 灰度值:在灰度图像中,每个像素点的值通常表示为介于0(黑色)和255(白色)之间的整数,这个值称为灰度值。
  • 操作:点运算对每个像素的灰度值进行数学运算,如加法、减法、乘法、除法等。
b.数学模型:
  • 线性变换:最简单的点运算是线性变换,可以用公式 s=a⋅r+bs=a⋅r+b 表示,其中 ss 是输出图像的像素值,rr 是输入图像的像素值,aa 是增益系数(或对比度),bb 是偏移量(或亮度)。
  • 非线性变换:更复杂的点运算可能涉及非线性函数,如对数、幂律(伽马校正)等。
c.饱和运算与模运算:
  • 饱和运算:在进行加法或乘法运算时,如果结果超出了数据类型的表示范围,就会进行饱和处理,即限制结果值不超过最大或最小可能值。例如,当两个像素值相加超过255时,结果将被设置为255。
  • 模运算:在某些图像处理库中,如Numpy,运算结果可能会进行模运算,这意味着结果会“环绕”。例如,两个像素值相加超过255时,结果可能会从0开始计数。
d.点运算的类型:
  • 加法:将一个常数加到图像的每个像素上,或将两个图像的像素值相加。
  • 减法:从一个图像的每个像素值中减去另一个图像的对应像素值或一个常数。
  • 乘法:逐像素相乘,通常用于调整图像的对比度。
  • 除法:逐像素相除,用于增强图像中的低灰度值特征。
  • 阈值处理:将图像分割成不同的区域,通常用于二值化或提取特定区域。
  • 直方图均衡化:通过调整图像的直方图分布来改善图像的对比度。
e.应用:
  • 图像增强:通过调整亮度、对比度和色彩,使图像更加清晰或突出某些特征。
  • 图像复原:减少图像退化的影响,如噪声、模糊等,恢复图像的原始状态。
  • 特征提取:在图像识别和分析中,提取有用的特征,如边缘、纹理等。

 (2)点运算的目标与分类 :

a.目标:
  • 图像增强:改善图像的视觉效果,使得图像更适合于人眼观察或自动图像分析。
  • 特征提取:从图像中提取有用的信息,如边缘、纹理、形状等,这些特征对于后续的图像分析至关重要。
  • 图像复原:减少或消除图像获取和传输过程中的退化效应,如噪声、模糊等,以恢复图像的原始状态。
  • 数据压缩:通过减少图像数据中的冗余信息来减少存储空间或传输带宽的需求。
  • 图像转换:将图像从一种形式或表示转换为另一种形式,以适应不同的处理或分析需求。
b.分类:

点运算根据对图像像素值的作用方式和效果进行分类:

  • 线性点运算:

    • 灰度变换:通过线性函数改变像素值,如亮度调整(添加或减去一个常数)和对比度调整(乘以一个系数)。
    • 阈值处理:将图像转换为二值图像,像素值高于或低于某个阈值的像素被赋予不同的灰度值。
  • 非线性点运算:

    • 对数变换:增强图像暗部的细节,通常用于增强图像的暗区域。
    • 幂律(伽马)变换:非线性地调整图像的亮度和对比度,广泛用于图像和视频的亮度调整。
    • 直方图均衡化:通过调整图像的直方图分布来改善图像的全局对比度。
  • 几何点运算:

    • 虽然不直接作用于像素值,但几何变换(如旋转、缩放、平移)也是点运算的一部分,因为它们涉及到图像中每个像素位置的变换。
  • 统计点运算:

    • 中值滤波:用像素邻域内的中值替换每个像素值,用于去除噪声。
    • 直方图规定化:调整图像的直方图以匹配特定的分布,用于改善图像的对比度和亮度。
  • 色彩空间转换:

    • RGB到灰度:将彩色图像转换为灰度图像,通常通过加权RGB通道的值来实现。
    • 色彩平衡:调整图像的色彩平衡,使得色彩更加自然或符合特定的视觉需求。
  • 形态学点运算:

    • 腐蚀和膨胀:这些运算通常用于二值图像,用于去除小的噪声或填充小的空洞。

(3)点运算的特点和应用 :

a.特点:
  • 简单性:点运算通常涉及简单的数学操作,如加法、乘法、指数和对数等,这些操作对每个像素独立执行,不需要复杂的算法或大量的计算资源。

  • 直接性:点运算直接作用于像素值,不依赖于像素之间的空间关系,因此它们是直接的并且易于实现。

  • 高效性:由于点运算的简单性,它们可以快速执行,这对于需要实时或近实时处理的应用来说非常重要。

  • 可逆性:某些点运算是可逆的,这意味着可以通过逆运算恢复原始图像。例如,如果一个图像经过了对数变换,可以通过指数变换来恢复。

  • 饱和处理:在像素值超出允许范围时,点运算通常涉及饱和处理,以确保像素值不会超出数据类型的表示范围。

  • 非空间依赖性:点运算不涉及像素之间的空间关系,因此不会改变图像的尺寸或几何结构。

  • 广泛适用性:点运算可以应用于各种类型的图像,包括灰度图像和彩色图像,以及不同的应用领域。

b.应用:
  • 图像增强:通过调整图像的亮度、对比度和色彩,使图像更适合于人眼观察或进一步的图像分析。

  • 特征提取:在图像识别和分析中,提取有用的特征,如边缘、纹理等,这些特征对于后续的图像分析至关重要。

  • 图像复原:减少或消除图像获取和传输过程中的退化效应,如噪声、模糊等,以恢复图像的原始状态。

  • 图像压缩:通过减少图像数据中的冗余信息来减少存储空间或传输带宽的需求。

  • 图像分割:使用阈值处理将图像分割成不同的区域,这对于目标检测和图像分类等应用非常有用。

  • 医学成像:在医学成像领域,点运算用于增强图像以突出特定的生物标志物或病理特征。

  • 卫星和航空摄影:在遥感图像处理中,点运算用于增强图像特征,以便于地理特征的识别和分类。

  • 视频处理:在视频监控、视频编辑和视频增强中,点运算用于改善视频质量,如调整亮度和对比度。

  • 计算机视觉:在计算机视觉系统中,点运算用于预处理图像,以提高后续算法的性能,如边缘检测、目标跟踪等。

 二、灰度变换:

灰度变换是图像处理中用于修改图像像素灰度值的技术,以达到改善图像质量、增强图像特征或适应特定应用需求的目的。

(1)灰度变换的基本概念:

  • 灰度级:图像中每个像素的亮度值,通常在0(黑色)到255(白色)之间。
  • 灰度变换函数:将原始图像的灰度值映射到新灰度值的函数。

(2)灰度变换的作用:

  • 图像增强:提高图像的视觉效果,使得细节更清晰,便于人眼观察或机器分析。
  • 特征突出:增强图像中的特定特征,如边缘、纹理等,有助于后续的图像分析。
  • 对比度调整:改善图像的对比度,使得暗区域和亮区域之间的差异更明显。
  • 数据压缩:在某些情况下,灰度变换可以减少图像数据的冗余,有助于数据压缩。
  • 图像复原:在图像受到退化(如模糊、噪声)时,灰度变换可以用于恢复图像的原始状态。

(3)灰度变换的方法:

  • 灰度化:将彩色图像转换为灰度图像,通常通过加权RGB通道的值来实现。
  • 对比度调整:通过改变图像的灰度级范围来增强图像的对比度。
  • 灰度线性变换:通过线性函数(如 s=a⋅r+b)调整图像的灰度值。
  • 非线性灰度变换:使用非线性函数(如对数、幂律变换)来调整图像的灰度值。

(4)灰度化:

灰度化(Grayscale Conversion)是将彩色图像转换为灰度图像的过程。灰度图像只有一个颜色通道,表示亮度信息,而没有颜色信息。灰度化是图像处理中的一种基本技术,它简化了图像数据,同时保留了图像的主要视觉特征。

灰度化的原理:

  • 彩色图像通常由红色(R)、绿色(G)和蓝色(B)三个颜色通道组成,每个通道的值通常在0到255之间。灰度化的过程涉及将这三个颜色通道的信息合并成一个单一的灰度值,这个过程基于人眼对不同颜色的敏感度不同。

常用的灰度化方法:

  • 平均法:

    • 将RGB三个通道的值相加后取平均,即 Gray=(R+G+B)/3。
    • 这种方法简单,但不考虑人眼对不同颜色的不同敏感度。
    • 示例代码:
import cv2
import numpy as np

# 读取彩色图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 转换为灰度图像(平均法)
gray_image_avg = np.uint8(np.mean(image, axis=2))

# 显示图像
cv2.imshow('Original Image', image)
cv2.imshow('Grayscale by Average', gray_image_avg)
cv2.waitKey(0)
cv2.destroyAllWindows()
  • 函数介绍: 
# 转换为灰度图像(平均法)
gray_image_avg = np.uint8(np.mean(image, axis=2))
  • image:这是一个使用OpenCV读取的彩色图像,它是一个NumPy数组,通常具有形状(高度, 宽度, 通道数),对于彩色图像,通道数是3(对应RGB)。
  • np.mean(...):这是NumPy库中的一个函数,用于计算沿指定轴的平均值。在这个例子中,axis=2指定了函数沿着颜色通道轴(即第三个轴,从0开始计数)计算平均值。因此,对于图像的每个像素,它计算RGB三个通道值的平均数。

  • np.uint8:这是NumPy中的数据类型,表示无符号的8位整数。图像的灰度值通常在0到255的范围内,因此使用uint8类型来确保灰度图像的像素值也在相同的范围内。

  • gray_image_avg:这是转换后的灰度图像,它是一个二维数组,其中每个元素都是原始彩色像素RGB值的平均值。

  • 加权平均法(Luminosity方法):

    • 根据人眼对不同颜色的敏感度给予不同的权重,常用的权重是 Gray=0.299R+0.587G+0.114B。
  • 代码示例:
  • 手动实现加权平均值法:
  • import cv2
    #"C:\\Users\\86173\\Desktop\\TI\\faves.png"
    import numpy as np
    
    # 读取彩色图像
    image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")
    
    # 确保图像读取成功
    if image is not None:
        # 分离彩色图像的三个通道
        B, G, R = cv2.split(image)
        # 应用加权平均值法
        gray_image = np.uint8(0.299 * R + 0.587 * G + 0.114 * B)
        # 显示原始彩色图像
        cv2.imshow('Original Image', image)
    
        # 显示转换后的灰度图像
        cv2.imshow('Grayscale Image', gray_image)
    
        # 等待按键,然后关闭所有窗口
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    else:
        print("Error: Image not found.")
  • 使用Python和OpenCV库实现加权平均值法将彩色图像转换为灰度图像的代码示例:

    import cv2
    import numpy as np
    
    # 读取彩色图像
    image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")
    
    # 确保图像读取成功
    if image is not None:
        # 使用OpenCV内置函数将彩色图像转换为灰度图像(加权平均值法)
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
        # 显示原始彩色图像
        cv2.imshow('Original Image', image)
    
        # 显示转换后的灰度图像
        cv2.imshow('Grayscale Image', gray_image)
    
        # 等待按键,然后关闭所有窗口
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    else:
        print("Error: Image not found.")
  • 最小-最大法:

    • 选择RGB三个通道中的最大值作为灰度值,即 Gray=max⁡(R,G,B)。
    • 这种方法保留了最亮的颜色,但可能会丢失其他颜色的信息。
  • 自定义方法:

    • 可以根据特定的应用需求,自定义RGB到灰度的转换公式。

灰度化的作用:

  • 简化处理:灰度图像只有一个通道,减少了数据处理的复杂性。
  • 增强分析:在很多图像分析任务中,颜色信息不是必需的,灰度化可以提高处理速度。
  • 改善视觉效果:在某些情况下,灰度图像可以更清晰地展示图像的细节和纹理。
  • 降低存储需求:灰度图像的数据量比彩色图像少,减少了存储空间的需求。

(5)对比度:

        对比度是图像中明暗区域之间差异的程度。在数字图像处理中,对比度通常是指图像中像素亮度值分布的范围以及这个范围内亮度值的相对差异。高对比度图像具有明显的明暗区域,而低对比度图像的明暗区域则较为模糊,细节不明显。

对比度的作用:

  • 增强视觉感知:高对比度可以帮助观察者更容易地区分图像中的不同对象和特征。
  • 改善图像质量:在图像显示或打印时,适当的对比度可以提高图像的视觉质量。
  • 辅助图像分析:在自动图像分析和计算机视觉系统中,对比度调整有助于突出重要的图像特征,如边缘和纹理。

对比度调整方法:

  • 线性变换:

    • 亮度调整:通过添加一个常数(偏移量)来改变图像的整体亮度。
    • 对比度调整:通过乘以一个系数(增益)来改变图像的对比度。公式为 s=a⋅r+b,其中 s 是输出像素值,r 是输入像素值,a 是对比度控制系数,b 是亮度控制系数。
  • 非线性变换:

    • 伽马校正:使用非线性函数调整图像的对比度,特别是暗部区域。公式为 ,其中 γ 是伽马值,c 是常数。
  • 直方图均衡化:

    • 通过调整图像的直方图分布来改善图像的全局对比度,使得直方图更加均匀。
  • 直方图规定化:

    • 将图像的直方图映射到一个特定的分布,如正态分布,以改善图像的对比度。
  • 局部对比度增强:

    • 对图像的局部区域进行对比度增强,如使用局部对比度增强滤波器(CLAHE)。

(6)灰度的线性变换:

        灰度的线性变换是一种简单的图像处理技术,用于增强图像的对比度或调整其亮度。这种变换基于线性函数,可以表示为:s=a⋅r+b

其中:

  • s是输出图像的灰度值。
  • r是输入图像的灰度值。
  • a 是增益系数(对比度控制),它决定了对比度的强度。
  • b是偏移量(亮度控制),它决定了整体的亮度水平。

效果:

  • 当 a>1时,图像对比度增加。
  • 当 a<1时,图像对比度减少。
  • 当 b>0时,图像变亮。
  • 当 b<0时,图像变暗。

饱和度处理:

  • 在进行线性变换时,需要注意像素值的饱和度。如果变换后的像素值超出了允许的范围(通常是0到255对于8位图像),则需要进行饱和度处理,以确保像素值不会超出这个范围。在OpenCV中,convertScaleAbs函数会自动处理这种情况。

实现示例(Python + OpenCV):

import cv2
import numpy as np

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 设置增益系数和偏移量
alpha = 1.5  # 增益系数,增加对比度
beta = 50    # 偏移量,增加亮度

# 应用线性变换
transformed_image = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)

# 显示原始图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', transformed_image)

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

 

  • cv2.convertScaleAbs函数用于对灰度图像进行线性变换。alpha参数控制对比度,beta参数控制亮度。函数会自动处理像素值的饱和度,确保它们在0到255的范围内。

注意事项:

  • 线性变换是一种简单有效的图像增强方法,但可能不适用于所有图像。在某些情况下,可能需要更复杂的方法,如直方图均衡化或伽马校正。
  • 在调整对比度和亮度时,应避免过度处理,以免失去图像的重要细节。

 (7)分段式线性变换:

        分段式线性变换(Piecewise Linear Transformation)是一种图像灰度变换方法,它将灰度值的范围分成几个段,每个段内应用不同的线性变换。这种方法可以更细致地控制图像的对比度和亮度,特别是在图像的特定灰度区域。

变换函数:

分段式线性变换可以表示为多个线性段的组合,每个段可以有不同的斜率(增益)和截距(偏移)。例如:

其中:

  • si是输出灰度值。
  • r是输入灰度值。
  • ai 是第 i段的增益系数。
  • bi是第 i 段的偏移量。
  • rj和 rj+1​ 是第 i段的灰度级范围。

实现示例(Python + OpenCV):

import cv2
import numpy as np

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png", cv2.IMREAD_GRAYSCALE)

# 定义分段式线性变换的参数
# 例如,我们将灰度级范围分成三段
segments = [
    (0, 100, (1.5, -50)),  # 对于灰度值在0到100之间的像素,增益为1.5,偏移为-50
    (100, 200, (1.0, 0)),  # 对于灰度值在100到200之间的像素,增益为1.0,偏移为0
    (200, 255, (0.5, 50))  # 对于灰度值在200到255之间的像素,增益为0.5,偏移为50
]

# 应用分段式线性变换
def piecewise_linear_transform(src, segments):
    # 创建一个与输入图像相同大小的输出图像
    dst = np.zeros_like(src)
    for i, (r1, r2, params) in enumerate(segments):
        mask = (src >= r1) & (src < r2)
        dst[mask] = params[0] * src[mask] + params[1]
        if i == len(segments) - 1:
            dst[src >= r2] = params[0] * src[src >= r2] + params[1]
    return np.clip(dst, 0, 255).astype(np.uint8)

transformed_image = piecewise_linear_transform(image, segments)

# 显示原始图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Transformed Image', transformed_image)

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

 

  • 定义了一个名为 piecewise_linear_transform 的函数,它接受输入图像和变换参数。函数内部,为每个灰度级段应用不同的增益和偏移,然后使用 np.clip 函数确保像素值在0到255的范围内。

 (8)对数变换和反对数变换:

        对数变换和反对数变换是图像处理中常用的技术,用于扩展图像的暗区域细节,同时压缩亮区域的细节。这些变换特别适用于处理具有高动态范围的图像,即图像中同时存在非常亮和非常暗的区域。

对数变换:

对数变换是一种非线性变换,它通过取图像灰度值的对数来扩展暗区域的细节。对数变换的公式可以表示为:

其中:

  • s 是输出的灰度值。
  • r是输入的灰度值。
  • c是一个常数,用于控制变换的强度。

对数变换可以使得暗区域的对比度增加,因为暗区域的灰度值较小,对数变换后的变化更加显著。

反对数变换:

反对数变换是对数变换的逆过程,它通过指数函数来恢复原始的灰度值。反对数变换的公式可以表示为:

其中:

  • s是变换后的灰度值。
  • c 是与对数变换中相同的常数。

反对数变换通常用于在对数变换后恢复图像的原始灰度值。

实现示例(Python + OpenCV):

import cv2
#"C:\\Users\\86173\\Desktop\\TI\\faves.png"
import numpy as np
# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png", cv2.IMREAD_GRAYSCALE)

# 对数变换
c = 25
log_image = c * np.log1p(np.array(image, dtype=np.float32))  # np.log1p(x) = log(1 + x)

# 反对数变换
inv_log_image = np.expm1(log_image / c)  # np.expm1(x) = exp(x) - 1

# 显示原始图像、对数变换后的图像和反对数变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Log Transformed Image', np.uint8(log_image))
cv2.imshow('Inverse Log Transformed Image', np.uint8(inv_log_image))

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 首先对图像进行对数变换,然后使用反对数变换来恢复图像。需要注意的是,对数变换可能会导致一些像素值超出图像数据类型的表示范围,因此可能需要对结果进行缩放或转换。此外,对数变换通常用于灰度图像,对于彩色图像,可以对每个颜色通道分别进行变换。

(9)幂律变换: 

        幂律变换(也称为伽马变换或伽马校正)是一种非线性灰度变换,用于调整图像的对比度。它在图像处理中非常有用,尤其是在调整图像的亮度和对比度时。幂律变换的公式可以表示为:

其中:

  • s是输出的灰度值。
  • r是输入的灰度值。
  • c 是常数,通常取1。
  • γ 是幂律变换的参数,称为伽马值。

伽马值的不同会影响图像的对比度:

  • 当 γ<1 时,图像的暗区域会变亮,而亮区域会变暗,从而增加图像的对比度。
  • 当 γ>1 时,图像的暗区域会变暗,而亮区域会变亮,从而减少图像的对比度。
  • 当 γ=1 时,幂律变换不会改变图像。

幂律变换在图像处理中的应用包括:

  • 调整显示器的亮度和对比度。
  • 改善图像的视觉效果,特别是在暗区域的细节增强。
  • 用于彩色图像处理时,通常对每个颜色通道分别进行幂律变换。

实现示例(Python + OpenCV):

import cv2
import numpy as np

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png", cv2.IMREAD_GRAYSCALE)

# 设置伽马值
gamma = 2.2

# 应用幂律变换
gamma_corrected = np.array(255 * (image / 255) ** gamma, dtype='uint8')

# 显示原始图像和变换后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Gamma Corrected Image', gamma_corrected)

# 等待按键,然后关闭所有窗口
cv2.waitKey(0)
cv2.destroyAllWindows()

  • 首先读取一个灰度图像,然后应用幂律变换。伽马值设置为2.2,通常用于降低对比度。变换后的图像会显示在窗口中。
  • 需要注意的是,幂律变换通常在图像的灰度值被归一化到[0, 1]区间内进行。在变换后,我们需要将结果缩放回0到255的范围,并转换回uint8类型,以便正确显示图像。

 三、直方图修正:

(1)直方图的概念:

        在图像处理中,直方图是一种统计工具,用于表示图像中像素强度(灰度值)的分布情况。直方图可以为图像分析和处理提供重要的信息,它显示了图像中每个强度值(对于灰度图像)或颜色值(对于彩色图像)的频率或数量。

  • 灰度直方图:对于灰度图像,直方图显示了从黑(0)到白(255)每个灰度级别的像素数量。灰度直方图是一个一维数组,其中数组的索引代表灰度值,数组的值代表该灰度值在图像中出现的次数。

  • 彩色直方图:对于彩色图像,可以为每个颜色通道(如RGB)分别计算直方图,也可以计算特定颜色空间(如HSV)的直方图。每个通道的直方图显示了该通道中每种颜色强度的频率。

  • 直方图的作用:

    • 图像分析:直方图可以帮助分析图像的亮度、对比度和颜色分布。
    • 图像增强:通过直方图均衡化等技术,可以改善图像的对比度和视觉效果。
    • 特征提取:在图像识别和分类中,直方图可以作为图像特征的一部分。
    • 图像压缩:了解直方图分布有助于图像压缩算法的设计。

直方图的计算:

直方图的计算通常涉及以下步骤:

  • 确定范围:确定直方图的灰度级范围,对于8位图像,通常是0到255。
  • 创建数组:创建一个长度等于灰度级数量的数组,用于存储每个灰度级的像素计数。
  • 计数:遍历图像的每个像素,根据其灰度值在直方图数组中对应的位置增加计数。

直方图均衡化:

  • 直方图均衡化是一种常用的图像增强技术,它通过调整图像的直方图分布来改善图像的对比度。均衡化后的图像直方图更加均匀,使得图像的亮度分布更加均衡。

直方图的绘制:

  • 直方图通常通过柱状图来表示,其中横轴代表灰度值或颜色值,纵轴代表该值的频率。在Python中,可以使用matplotlib库来绘制直方图。

示例代码:计算和绘制灰度直方图:

#"C:\\Users\\86173\\Desktop\\TI\\faves.png"
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png", cv2.IMREAD_GRAYSCALE)

# 计算直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])

# 绘制直方图
plt.plot(hist)
plt.title('Grayscale Histogram')
plt.xlabel('Grayscale Value')
plt.ylabel('Frequency')
plt.show()

 

  • 使用OpenCV的calcHist函数计算了图像的灰度直方图,并使用matplotlib绘制了直方图。

cv2.calcHist 函数: 

        在OpenCV中,cv2.calcHist 函数用于计算图像的直方图。这个函数可以用于灰度图像或彩色图像的直方图计算,并且可以指定图像的特定通道进行计算。直方图是图像中像素强度值分布的图形表示,它在图像分析和处理中非常有用,尤其是在图像增强、阈值处理和特征提取等方面。

函数原型:

double cv::calcHist(
    InputArrayOfArrays images,
    InputArray channels,
    InputArray mask,
    OutputArray histSize,
    InputArray ranges,
    double scale = 1,
    int dtype = CV_32F
)

参数:

  • images:输入图像或图像数组。
  • channels:指定要计算直方图的通道索引。对于灰度图像,这通常是单个值(例如,0)。
  • mask:可选的掩码图像,用于指定哪些像素被计算在内。如果为None,则计算整个图像。
  • histSize:输出直方图的大小(即bin的数量)。对于灰度图像,这通常是一个包含256个元素的数组。
  • ranges:像素值的范围。对于灰度图像,这通常是[0, 256]
  • scale:可选的缩放因子,用于缩放直方图的值。
  • dtype:输出直方图的数据类型,通常是CV_32F(32位浮点数)。

返回值:返回值是计算得到的直方图。

(2)绘制BRG直方图:

        在OpenCV中,绘制彩色图像的BGR直方图需要分别为蓝色、绿色和红色通道计算直方图,并将它们绘制在同一图表中。

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\cat.jpg")

# 将图像转换为浮点数,以便进行归一化
image = np.float32(image) / 255

# 计算每个通道的直方图
color = ('b', 'g', 'r')
for i, col in enumerate(color):
    hist = cv2.calcHist([image], [i], None, [256], [0, 256])
    plt.plot(hist, color=col)
    plt.xlim([0, 256])

# 设置图表标题和轴标签
plt.title('BGR Histogram')
plt.xlabel('BGR Value')
plt.ylabel('Frequency')

# 显示直方图
plt.show()

 

  • 首先读取一个彩色图像,然后使用cv2.calcHist函数分别为蓝色、绿色和红色通道计算直方图。使用matplotlib.pyplot库来绘制直方图,并将三个通道的直方图绘制在同一图表中。
  • cv2.calcHist函数的第二个参数[i]指定了要计算直方图的通道索引(蓝色通道为0,绿色通道为1,红色通道为2)。[256]指定了直方图的大小,即每个通道有256个bin。[0, 256]指定了像素值的范围。
  • 使用plt.xlim([0, 256])设置x轴的范围,以确保所有直方图都显示在相同的尺度上。使用plt.titleplt.xlabelplt.ylabel设置图表的标题和轴标签。最后,使用plt.show()显示直方图。

 (3)原始计算灰度直方图的方法:

原始计算灰度直方图的方法不依赖于任何特定的图像处理库,而是使用基本的编程和数学操作。

import numpy as np
import matplotlib.pyplot as plt

# 假设我们有一个灰度图像的数组,这里我们创建一个示例数组
# 在实际应用中,你会从文件中读取图像数据
gray_image = np.random.randint(0, 256, size=(100, 100), dtype=np.uint8)

# 计算直方图
# 初始化一个长度为256的数组,用于存储每个灰度级的计数
histogram = np.zeros(256)

# 遍历图像中的每个像素,增加相应灰度级的计数
for row in gray_image:
    for pixel in row:
        histogram[pixel] += 1

# 绘制直方图
plt.bar(range(256), histogram, color='gray')
plt.title('Grayscale Histogram')
plt.xlabel('Grayscale Value')
plt.ylabel('Pixel Count')
plt.show()

 

  • 首先创建了一个随机的灰度图像数组gray_image,其中包含了100x100的像素值。然后,初始化了一个长度为256的数组histogram来存储每个灰度级的计数。通过遍历图像中的每个像素,并在histogram数组中相应灰度级的位置上增加计数,得到了图像的直方图。
  • 最后,使用matplotlib.pyplot库的bar函数绘制直方图,其中x轴表示灰度值,y轴表示每个灰度值的像素计数。

(4)直方图均衡化:                

        直方图均衡化是一种图像处理技术,用于改善图像的对比度,特别是当图像的可用数据由于背景或前景的光照过暗或过亮而受到限制时。这种方法通过调整图像的直方图分布来实现,使得直方图更加均匀,从而增强图像的整体视觉效果。

直方图均衡化的原理:

直方图均衡化基于这样一个假设:如果图像的直方图分布均匀,则图像的对比度会更好。在灰度图像中,这意味着每个灰度级的像素数量大致相等。均衡化过程通常涉及以下步骤:

  • 计算原始图像的直方图:统计图像中每个灰度级的像素数量。
  • 计算累积分布函数(CDF):直方图的累积和,用于跟踪每个灰度级及其以下所有灰度级的总像素数量。
  • 归一化CDF:将CDF值归一化到灰度级范围内(通常是0到255)。
  • 映射灰度级:使用归一化的CDF值作为新的灰度级,替换原始图像中的每个像素。

直方图均衡化的效果:

  • 增强对比度:使图像的暗区域变得更亮,亮区域变得更暗,从而增强整体对比度。
  • 细节突出:在暗区域和亮区域中都能看到更多的细节。
  • 减少光照不均的影响:对于光照条件不理想的图像,均衡化可以减少这种不均匀性的影响。

实现示例(Python + OpenCV):

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转换为灰度图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\Gama.jpg", cv2.IMREAD_GRAYSCALE)

# 应用直方图均衡化
equalized_image = cv2.equalizeHist(image)

# 显示原始图像和均衡化后的图像
plt.subplot(121), plt.imshow(image, 'gray'), plt.title('Original Image')
plt.subplot(122), plt.imshow(equalized_image, 'gray'), plt.title('Equalized Image')
plt.show()

  • 使用cv2.equalizeHist函数对灰度图像进行直方图均衡化。均衡化后的图像会显示更多的细节,尤其是那些在原始图像中由于光照不足而不可见的细节。

直方图均衡化的步骤和公式如下:

步骤:

  • 计算直方图:

    • 对于灰度图像,计算每个灰度级(从0到255)的像素数量,得到直方图 H(r)。
  • 计算累积分布函数(CDF):

    • 累积分布函数 CDF(r)是直方图的累积和,表示灰度级 r 及以下所有灰度级的像素数量总和。
  • 归一化CDF:

    • 将CDF归一化到灰度级范围内,得到新的灰度级 s。
    • s=CDF(r)像素总数×255。
  • 映射灰度级:

    • 使用归一化的CDF值作为新的灰度级,替换原始图像中的每个像素。
  • 生成均衡化后的图像:

    • 根据映射关系,将原始图像中的每个像素值替换为新的灰度级,得到均衡化后的图像。

公式:

  • 直方图:

    • H(r):灰度级 r 的像素数量。
  • 累积分布函数(CDF):

    • CDF(r):灰度级 r 及以下所有灰度级的像素数量总和。
  • 归一化CDF:

 代码示例:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转换为灰度图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\Gama.jpg", cv2.IMREAD_GRAYSCALE)

# 计算直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])

# 计算累积分布函数(CDF)
cdf = hist.cumsum()
# 归一化CDF
cdf_normalized = (cdf - cdf.min()) / (cdf.max() - cdf.min()) * 255

# 映射灰度级
cdf_mapped = np.uint8(cdf_normalized)

# 应用映射
equalized_image = cdf_mapped[image]

# 显示原始图像和均衡化后的图像
cv2.imshow('Original Image', image)
cv2.imshow('Equalized Image', equalized_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

(5)灰度直方图均衡化:

equalizeHist 函数:

cv2.equalizeHist 函数是 OpenCV 库中用于执行直方图均衡化的函数。这个函数可以改善图像的对比度,特别是当图像的对比度较低或者光照不均匀时。直方图均衡化通过调整图像的直方图分布,使得每个灰度级的像素数量尽可能均匀,从而增强图像的整体视觉效果。

函数原型:

dst = cv2.equalizeHist(src)

参数:

  • src:输入图像,必须是8位单通道灰度图像。

返回值:

  • dst:输出图像,与输入图像具有相同的大小和类型。

注意事项:

  • cv2.equalizeHist 只能用于灰度图像。如果你有一个彩色图像,你需要先将其转换为灰度图像,或者对每个颜色通道分别进行直方图均衡化。
  • 直方图均衡化可能会增强图像中的噪声。在某些情况下,可能需要先对图像进行平滑处理,以减少噪声的影响。
  • 直方图均衡化是一种线性变换,它不适用于所有类型的图像。在某些情况下,可能需要考虑使用其他图像增强技术。
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像并转换为灰度图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png", cv2.IMREAD_GRAYSCALE)

# 应用直方图均衡化
equalized_image = cv2.equalizeHist(image)

# 显示原始图像和均衡化后的图像
plt.subplot(121), plt.imshow(image, cmap='gray'), plt.title('Original Image')
plt.subplot(122), plt.imshow(equalized_image, cmap='gray'), plt.title('Equalized Image')
plt.show()

(6)彩色图像直方图均衡化:

        对于彩色图像,直方图均衡化不能直接应用于整个图像,因为这样做可能会导致颜色失真。彩色图像通常由多个颜色通道组成(如RGB),每个通道的直方图均衡化需要独立进行,但这可能会导致颜色失衡。

为了在彩色图像上进行直方图均衡化,通常采用以下方法之一:

  • 在YUV或HSV颜色空间中进行均衡化:

    • 将图像从RGB颜色空间转换到YUV或HSV颜色空间。
    • 对亮度通道(Y或V)进行直方图均衡化,而保持色度通道(U, V或H, S)不变。
    • 将图像转换回RGB颜色空间。
  • 对每个颜色通道独立进行均衡化:

    • 分别对RGB颜色空间的每个通道进行直方图均衡化。
    • 然后将处理后的通道重新组合成彩色图像。
  • 使用自适应直方图均衡化(例如CLAHE):

    • 自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalization)是一种改进的直方图均衡化方法,可以减少噪声并改善图像对比度。

Python和OpenCV在YUV颜色空间中进行直方图均衡化的示例代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread("C:\\Users\\86173\\Desktop\\TI\\faves.png")

# 将图像从BGR转换到YUV颜色空间
image_yuv = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)

# 对亮度通道进行直方图均衡化
image_yuv[:, :, 0] = cv2.equalizeHist(image_yuv[:, :, 0])

# 将图像转换回BGR颜色空间
equalized_image = cv2.cvtColor(image_yuv, cv2.COLOR_YUV2BGR)

# 显示原始图像和均衡化后的图像
plt.subplot(121), plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB)), plt.title('Original Image')
plt.subplot(122), plt.imshow(cv2.cvtColor(equalized_image, cv2.COLOR_BGR2RGB)), plt.title('Equalized Image')
plt.show()

 

  • 首先将图像从BGR颜色空间转换到YUV颜色空间,然后对亮度通道(Y通道)进行直方图均衡化,最后将图像转换回BGR颜色空间。这种方法可以改善图像的对比度,同时保持颜色的真实性。
  • 直方图均衡化可能会增强图像中的噪声,特别是在亮度通道中。在实际应用中,可能需要结合其他图像处理技术(如噪声滤波)来获得最佳效果。                                                                       
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值