您的位置:

LBPH算法:从原理到实现

一、LBPH算法是什么?

LBPH算法(local binary patterns histogram)是一种用于图像处理与分析的特征提取算法。它能够对图像中的局部纹理特征进行提取、描述和匹配,因此在人脸识别、物体检测等领域被广泛应用。

LBPH算法的基本思想是选取一定大小的邻域像素,并将该邻域中的像素值与其中心像素值进行比较,根据比较结果产生二进制编码来表示该邻域的纹理特征。然后,将所有的邻域特征值作为特征向量的维度,并构建以该维度为坐标轴的直方图进行表示,形成了LBPH特征向量,完成特征提取过程。

二、LBPH算法的实现步骤

1.离散化图像

由于LBPH算法能够提取图像局部纹理特征,因此在对图像进行处理前,先需要对图像进行离散化操作。具体的做法是将灰度图像中的像素值分成不同的像素等级,以便于于后续的计算。假设将灰度图像的像素值分成8个等级,则可以得到以下代码:

def discretize_image(img): 
  num_lbp = 8 #离散化为8个区间
  pixel = (256 / num_lbp) * np.array(range(num_lbp+1))
  img = np.digitize(img, pixel) - 1
  return img

2.计算LBPH编码

在计算LBPH编码时,需要对图像中的每个像素点进行处理。我们可以以像素点为中心点,选取一定大小的邻域像素,然后将该邻域中的像素值与中心像素值进行比较,根据比较结果产生二进制代码。

LBPH算法的二进制编码规则如下:若相邻的像素点的像素值大于中心像素点的像素值,则该像素点的二进制编码为1;否则为0。将所有邻域像素的二进制编码拼接起来,即可得到LBPH编码,如下所示:

def compute_lbp(pixel, img, radius=1):
  lbp = 0
  for i, j in radius_circle(radius):
    row, col = pixel[0] + i, pixel[1] + j
    if img[row, col] >= img[pixel]:
      lbp = (lbp << 1) + 1
    else:
      lbp = lbp << 1
  return lbp

3.计算LBPH直方图

计算LBPH直方图时,需要将全图中的LBPH编码分别存储在直方图中的对应位置中,并进行累加操作。假设直方图的维度为256,则可以使用下列代码进行实现:

def compute_histogram(img, radius=1, n_sample=8):
  img = cv2.GaussianBlur(img, (5,5), 0)
  hist = np.zeros((2 ** (n_sample * radius * 2)), dtype=np.float32)
  for i in range(radius, img.shape[0] - radius):
    for j in range(radius, img.shape[1] - radius):
      lbp_code = compute_lbp((i, j), img, radius)
      hist[lbp_code] += 1
  return hist

三、LBPH算法的优缺点

1.优点

LBPH算法能够克服众多面部表情和光照变化的影响,对于模糊、复杂背景和人脸姿态不正的人脸识别问题有很好的效果。

同时,其计算复杂度相对较低,易于实现;也具有较高的鲁棒性和可靠性。

2.缺点

LBPH算法相对于其他的人脸识别算法而言,分类效果相对较差。部分原因是因为LBPH算法仅从局部图像维度来表示人脸特征,因此容易受局部区域的噪声影响而与全局特征差异大。

同时在实际应用中,当人脸尺寸较小时,一些重要的纹理信息可能会被忽略而导致人脸识别效果较差。

四、总结

LBPH算法是一种用于图像处理与分析的特征提取算法。它能够对图像中的局部纹理特征进行提取、描述和匹配,因此在人脸识别、物体检测等领域被广泛应用。其基本思想是选取一定大小的邻域像素,并将该邻域中的像素值与其中心像素值进行比较,根据比较结果产生二进制编码来表示该邻域的纹理特征。随后,以所有邻域特征值作为特征向量的维度,构建以该维度为坐标轴的直方图进行表示,从而完成特征提取过程。

虽然LBPH算法能够克服众多面部表情和光照变化的影响,对于模糊、复杂背景和人脸姿态不正的人脸识别问题有很好的效果,但其相对于其他人脸识别算法而言分类效果较差,同时需要保证人脸样本库中有足够丰富和多样的样本,以提高识别正确率。