likes
comments
collection
share

图像识别之直方图均衡化

作者站长头像
站长
· 阅读数 5

直方图均衡化是一种图像增强技术,其目的是通过调整图像的亮度和对比度来改善图像的质量和视觉效果。该技术的基本思想是将图像的像素灰度值分布变得更加均匀,从而使得图像的对比度得到增强。

直方图均衡化的具体实现步骤如下:

  1. 统计图像的灰度直方图,即计算每个灰度级别的像素点数量。
  2. 计算归一化的累计直方图,即将每个灰度级别的像素点数量除以总的像素点数,然后累加。
  3. 根据累计直方图的值和最小灰度级别得到均衡化后的灰度级别,即将每个灰度级别的累计直方图值乘以灰度级别的最大值(通常为255),然后四舍五入取整。
  4. 将均衡化后的灰度级别映射回原图像,得到均衡化后的图像。

以下是使用Python实现直方图均衡化的示例代码:

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 直方图均衡化
equ = cv2.equalizeHist(img)

# 可视化结果
cv2.imshow('Original Image', img)
cv2.imshow('Equalized Image', equ)
cv2.waitKey()
cv2.destroyAllWindows()

以上代码中,cv2.equalizeHist()函数实现了直方图均衡化的过程,将输入的灰度图像均衡化后返回。在实际使用中,可以根据需要进行调整参数以获得更好的效果。

除了基本的直方图均衡化外,还有一些改进的算法,例如自适应直方图均衡化(CLAHE)、双边滤波直方图均衡化(BBHE)等,这些算法可以在特定场景下取得更好的效果。

自适应直方图均衡化(CLAHE)

自适应直方图均衡化(Contrast Limited Adaptive Histogram Equalization,CLAHE)是直方图均衡化的一种改进算法,它可以更好地保留图像的局部特征和细节信息,避免了全局均衡化导致的过度增强和噪声放大问题。

与传统的直方图均衡化不同,CLAHE算法是在每个局部区域内进行直方图均衡化,以适应图像中不同区域的灰度分布特征。为了控制局部增强的程度,CLAHE还引入了限制对比度的机制,限制了直方图均衡化后像素值的动态范围,从而避免了过度增强。

具体实现步骤如下:

  1. 将图像划分成多个局部块,每个块内进行直方图均衡化。
  2. 在每个块内计算累计直方图,计算出每个灰度级别的像素点数量,并按照步骤3计算均衡化后的灰度级别。
  3. 对每个块内的像素进行映射,将原图像中的像素值替换为均衡化后的值。
  4. 将均衡化后的局部块重新拼合为完整的图像。

以下是使用Python实现CLAHE的示例代码:

import cv2

# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))

# 对图像进行自适应直方图均衡化
equ = clahe.apply(img)

# 可视化结果
cv2.imshow('Original Image', img)
cv2.imshow('CLAHE Image', equ)
cv2.waitKey()
cv2.destroyAllWindows()

以上代码中,我们使用cv2.createCLAHE()函数创建了一个CLAHE对象,指定了clipLimit参数来控制限制对比度的阈值,以及tileGridSize参数来指定局部块的大小。然后我们将该对象应用到输入图像上,得到了CLAHE增强后的图像。在实际使用中,可以根据需要进行调整参数以获得更好的效果。

CLAHE算法是一种广泛使用的图像增强技术,它可以在不破坏图像细节和局部特征的前提下,提高图像的对比度和清晰度。

均值迁移直方图均衡化(MSHE)

均值迁移直方图均衡化(MSHE)是一种图像直方图均衡化的改进算法,其核心思想是将图像中的每个像素点移动到与其相似的像素点的中心,然后再进行直方图均衡化,从而避免了全局均衡化可能产生的过度增强和失真问题。

具体来说,MSHE算法的步骤如下:

  1. 对于输入的灰度图像,将其转化为彩色图像(或者将其复制三次得到三通道图像)。
  2. 对于彩色图像中的每个像素点,利用均值迁移的思想将其移动到与其相似的像素点的中心,得到移动后的图像。
  3. 对于移动后的图像,分别对每个通道进行直方图均衡化。
  4. 将三个通道的均衡化结果取平均值,得到最终的均衡化结果。

其中,均值迁移的过程可以通过以下公式来实现:

图像识别之直方图均衡化

其中,pip_ipi表示像素点xi\boldsymbol{x_i}xi的移动位置,nnn为图像中像素点的总数,K(∣∣xi−xj∣∣2)K(||\boldsymbol{x_i}-\boldsymbol{x_j}||^2)K(∣∣xixj2)表示均值迁移核函数,其取值决定了像素点xi\boldsymbol{x_i}xi在移动过程中受到哪些像素点的影响。常用的核函数包括高斯核、Epanechnikov核等。

均值迁移直方图均衡化的Python代码如下:

import cv2
import numpy as np

def mshe(img):
    # 将灰度图像转化为彩色图像
    img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    # 设置均值迁移参数
    sp = img_color.shape
    sr = int(sp[0]/100)
    ss = int(sp[1]/100)
    # 对每个像素点进行均值迁移
    img_shifted = np.zeros_like(img_color)
    for i in range(sr, sp[0]-sr):
        for j in range(ss, sp[1]-ss):
            center = img_color[i-sr:i+sr+1, j-ss:j+ss+1].reshape(-1, 3)
            shifted_center = cv2.pyrMeanShiftFiltering(center, 10, 30)
            img_shifted[i, j] = shifted_center[4]
    # 对移动后的图像进行直方图均衡化
    img_eq = cv2.cvtColor(img_shifted, cv2.COLOR_BGR2YCrCb)
    channels = cv2.split(img_eq)
    for i in range(3):
        cv2.equalizeHist(channels[i], channels[i])
    img_eq = cv2.merge(channels)
    img_eq = cv2.cvtColor(img_eq, cv2.COLOR_YCrCb2BGR)
    # 返回均衡化结果
    return cv2.cvtColor(img_eq, cv2.COLOR_BGR2GRAY)

其中,代码中的均值迁移参数sr和ss分别表示均值迁移的窗口大小,在实际应用中可以根据图像的大小和分辨率进行调整。cv2.pyrMeanShiftFiltering()函数是OpenCV中提供的均值迁移滤波函数,其第一个参数为输入的像素点集合,第二个参数为空间窗口大小,第三个参数为色彩窗口大小。

MSHE算法可以通过对均值迁移核函数的不同选择进行改进,例如使用局部自适应均值迁移(LAME)核函数或者非线性核函数等。

双边滤波直方图均衡化(BBHE)

双边滤波直方图均衡化(BBHE)是一种基于双边滤波和直方图均衡化的图像增强技术,可以有效地增强图像的对比度和细节。与传统的直方图均衡化相比,BBHE考虑了图像的空间信息和灰度相似度,并将这些信息与灰度直方图结合起来进行均衡化。

BBHE的具体实现步骤如下:

  1. 对原始图像进行双边滤波,以保留图像的边缘和细节。
  2. 计算双边滤波后的图像的灰度直方图。
  3. 计算归一化的累计直方图。
  4. 根据累计直方图的值和最小灰度级别得到均衡化后的灰度级别。
  5. 将均衡化后的灰度级别映射回原图像,得到均衡化后的图像。

以下是使用Python实现BBHE的示例代码:

import cv2
import numpy as np

# 读取图像
img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 双边滤波
img_bf = cv2.bilateralFilter(img, 5, 75, 75)

# 计算灰度直方图
hist, bins = np.histogram(img_bf.flatten(), 256, [0, 256])

# 计算累计直方图
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()

# 计算均衡化后的灰度级别
lut = np.interp(np.arange(256), bins[:-1], cdf_normalized)

# 映射回原图像
equ = cv2.LUT(img, lut)

# 可视化结果
cv2.imshow('Original Image', img)
cv2.imshow('BBHE Image', equ)
cv2.waitKey()
cv2.destroyAllWindows()

以上代码中,cv2.bilateralFilter()函数实现了双边滤波的过程,将输入的灰度图像进行双边滤波后返回。在计算灰度直方图和累计直方图时,可以使用Numpy库的np.histogram()函数和cumsum()方法进行计算。在计算均衡化后的灰度级别时,可以使用Numpy库的np.interp()函数进行线性插值计算。最后,使用OpenCV的cv2.LUT()函数将均衡化后的灰度级别映射回原图像,得到均衡化后的图像。

需要注意的是,BBHE算法虽然可以有效地增强图像的对比度和细节,但也容易引入噪声和伪影。在实际使用中,可以根据需要进行调整参数以获得更好的效果。