LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子,具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen, 和 D. Harwood 在1994年提出,用于纹理特征提取,且提取的特征是图像的局部的纹理特征。
代码放在了最下面,也可访问Github。
LBP的应用中,一般都不将LBP图谱作为特征向量用于分类识别,而是采用LBP特征谱的统计直方图作为特征向量用于分类识别。本示例便是使用统计直方图作为分类依据。
对LBP特征向量进行提取的步骤:
(1)首先将检测窗口划分为16×16的小区域(cell);
(2)对于每个cell中的一个像素,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数,即得到该窗口中心像素点的LBP值;
(3)其次计算每个cell的直方图,即每个数字出现的频率;然后对该直方图进行归一化处理;
(4)最后将得到的每个cell的统计直方图进行连接成为一个特征向量,也即整幅图的LBP纹理特征向量。
# 下图为该条件下得到的LBP纹理图像
radius = 3
n_point = radius * 16
from skimage import feature
from PIL import Image
import numpy as np
import time
import os
import pandas as pd
from sklearn.metrics import accuracy_score, f1_score, recall_score, confusion_matrix, classification_report, precision_score
from PIL import Image
def read_image(img_name):
im = Image.open(img_name).convert('L')
data = np.array(im)
return data
images = []
for fn in os.listdir('D:/data'):
if fn.endswith('.jpg'):
fd = os.path.join('D:/data',fn)
images.append(read_image(fd))
print('load data success!')
X = np.array(images)
print (X.shape)
y = np.loadtxt('label.txt')
print (y.shape)
# the data, split between train and test sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.5, random_state= 3)
print (X_train.shape)
print (X_test.shape)
print (y_train.shape)
print (y_test.shape)
radius = 2
n_point = radius * 8
def lbp_texture(train_data, test_data):
train_hist = np.zeros((len(X_train), 256))
test_hist = np.zeros(((len(X_train), 256))
for i in np.arange((len(X_train)):
# 使用skimage LBP方法提取图像的纹理特征
lbp = feature.local_binary_pattern(train_data[i],n_point,radius,'default')
# 统计图像直方图256维
max_bins = int(lbp.max() + 1)
# hist size:256
train_hist[i], _ = np.histogram(lbp, normed=True, bins=max_bins, range=(0, max_bins))
for i in np.arange((len(X_train)):
lbp = feature.local_binary_pattern(test_data[i],n_point,radius,'default')
max_bins = int(lbp.max() + 1)
test_hist[i], _ = np.histogram(lbp, normed=True, bins=max_bins, range=(0, max_bins))
return train_hist, test_hist
from sklearn import svm
X_train, X_test = lbp_texture(X_train, X_test)
clf = svm.SVC(C=0.8, kernel='rbf', gamma=20, decision_function_shape='ovr')
clf.fit(X_train, y_train)
p_test = clf.predict(X_test)
from sklearn.metrics import f1_score, accuracy_score, precision_score, recall_score
print(clf.score(X_train, y_train)) # 训练精度
print(clf.score(X_test, y_test)) # 测试精度
print('decision_function:\n', clf.decision_function(x_train))
print(precision_score(y_test, p_test, average='macro'))
print(recall_score(y_test, p_test, average='macro'))
print(f1_score(y_test, p_test, average='macro'))
print(accuracy_score(y_test, p_test))