赞
踩
『youcans 的 OpenCV 例程200篇 - 总目录』
局部二值模式(LBP,Local binary patterns)是一种用来描述图像局部纹理特征的算子,它具有旋转不变性和灰度不变性的优点 。 LBP 特征计算简单、效果较好,在计算机视觉领域得到了广泛的应用。
描述纹理的常用方法是使用图像或目标区域的统计直方图。
基本 LBP 算子
基本的 LBP 算子定义在 3×3 的窗口内,以窗口中心像素为阈值,与相邻的 8 个像素的灰度值比较,大于阈值则标记为 1,否则标记为 0。从右上角开始顺时针旋转,排列 8 个 0/1标记值,得到一个 8 位二进制数,就是窗口中心像素点的 LBP 值。
L
B
P
P
,
R
(
x
c
,
y
c
)
=
∑
p
=
0
P
−
1
S
(
g
p
−
g
c
)
∗
2
p
S
(
g
p
−
g
c
)
=
{
1
,
g
p
≥
g
c
0
,
g
p
<
g
c
LBP_{P,R} (x_c,y_c) = \sum_{p=0}^{P-1} S(g_p-g_c)*2^p\\ S(g_p-g_c) = {1,gp≥gc0,gp<gc
LBP 直方图
图像可以用 LBP 特征向量来表示,但在应用中一般并不是直接使用 LBP 图谱进行分类识别,而是使用 LBP 特征谱的统计直方图进行分类识别。因为 LBP 特征是与图像中的位置紧密相关的,直接对两幅图片提取 LBP 特征进行判别分析,会由于位置没有对准而带来很大的误差。
为了解决这个问题,可以将图像划分为若干子区域,对每个子区域内提取 LBP 特征后在子区域内建立 LBP 特征的统计直方图。图片的每个子区域可以用一个统计直方图来描述,整个图片就由若干个统计直方图组成,称为 LBP 特征的统计直方图(LBPH,Local Binary Patterns Histograms)。
LBPH 将 LBP 特征与图像的空间信息结合起来。将 LBP 特征图像分成 m 个子块,提取每个子块的 LBP 特征并建立统计直方图,将这些直方图依次连接在一起,就形成 LBP 特征的统计直方图。
计算 LBP 统计直方图的步骤为:
(1)计算 LBP 特征图像;
(2)将 LBP 特征图像划分为若干块子区域(cell),默认划分 8*8=64 块子区域;
(3)计算每个子区域 LBP 特征图像的直方图(cell_LBPH),并进行归一化处理;
(4)将每个子区域的 LBP 直方图依次排列成一行,形成 LBP 特征向量;
(5)用机器学习方法对 LBP 特征向量进行训练,检测和识别目标。
例程只给出 LBP 统计直方图的构造,基于 LBP 直方图的特征检测和目标识别,将在模式识别中介绍。
# 14.10 特征描述之 LBP 直方图 def basicLBP(gray): height, width = gray.shape dst = np.zeros((height, width), np.uint8) kernelFlatten = np.array([1, 2, 4, 128, 0, 8, 64, 32, 16]) # 从左上角开始顺时针旋转 for h in range(1, height-1): for w in range(1, width-1): LBPFlatten = (gray[h-1:h+2, w-1:w+2] >= gray[h, w]).flatten() # 展平为一维向量, (9,) dst[h, w] = np.vdot(LBPFlatten, kernelFlatten) # 一维向量的内积 return dst def calLBPHistogram(imgLBP, nCellX, nCellY): # 计算 LBP 直方图 height, width = gray.shape # nCellX, nCellY = 4, 4 # 将图像划分为 nCellX*nCellY 个子区域 hCell, wCell = height//nCellY, width//nCellX # 子区域的高度与宽度 (150,120) LBPHistogram = np.zeros((nCellX*nCellY, 256), np.int) for j in range(nCellY): for i in range(nCellX): cell = imgLBP[j * hCell:(j + 1) * hCell, i * wCell:(i + 1) * wCell].copy() # 子区域 cell LBP print("{}, Cell({}{}): [{}:{}, {}:{}]".format (j*nCellX+i+1, j+1, i+1, j*hCell, (j+1)*hCell, i*wCell, (i+1)*wCell)) histCell = cv2.calcHist([cell], [0], None, [256], [0, 256]) # 子区域 LBP 直方图 LBPHistogram[(i+1)*(j+1)-1, :] = histCell.flatten() print(LBPHistogram.shape) return LBPHistogram # 特征描述之 LBP 直方图 img = cv2.imread("../images/fabric2.png", flags=1) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图像 height, width = gray.shape nCellX, nCellY = 4, 4 # 将图像划分为 nCellX*nCellY 个子区域 hCell, wCell = height//nCellY, width//nCellX # 子区域的高度与宽度 (150,120) print("img: h={},w={}, cell: h={},w={}".format(height, width, hCell, wCell)) basicLBP = basicLBP(gray) # 计算 basicLBP 特征算子 # LBPHistogram = calLBPHistogram(basicLBP, nCellX, nCellY) # 计算 LBP 直方图 (16, 256) fig1 = plt.figure(figsize=(9, 8)) fig1.suptitle("basic LBP") fig2 = plt.figure(figsize=(9, 8)) fig2.suptitle("LBP histogram") for j in range(nCellY): for i in range(nCellX): cell = basicLBP[j*hCell:(j+1)*hCell, i*wCell:(i+1)*wCell].copy() # 子区域 cell LBP histCV = cv2.calcHist([cell], [0], None, [256], [0, 256]) # 子区域 cell LBP 直方图 ax1 = fig1.add_subplot(nCellY, nCellX, j * nCellX + i + 1) ax1.set_xticks([]), ax1.set_yticks([]) ax1.imshow(cell, 'gray') # 绘制子区域 LBP ax2 = fig2.add_subplot(nCellY,nCellX,j*nCellX+i+1) ax2.set_xticks([]), ax2.set_yticks([]) ax2.bar(range(256), histCV[:, 0]) # 绘制子区域 LBP 直方图 print("{}, Cell({}{}): [{}:{}, {}:{}]".format (j * nCellX + i + 1, j + 1, i + 1, j * hCell, (j + 1) * hCell, i * wCell, (i + 1) * wCell)) plt.show()
【本节完】
版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/125681261)
Copyright 2022 youcans, XUPT
Crated:2022-7-7
227. 特征描述之 LBP 纹理特征算子
228. 特征描述之 extendLBP 改进算子
229. 特征描述之 LBP 算子比较(skimage)
230. 特征描述之 LBP 统计直方图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。