Python,用LBP提取了100张照片的特征,得到了100行59列的数组。之后用pca降维到了9维,到这都没什么问题。但是对单张照片使用LBP并且降维时却提示我这是个一维数组,该如何解决?LBP对单张照片提取的数据是1行59列的(一维),有办法给他弄成59维吗
原始的 LBP 算子定义为在 3*3 的窗口内,以窗口中心像素为阈值,将相邻的 8 个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为 1,否则为 0。这样,3*3 邻域内的 8 个点经比较可产生 8 位二进制数(通常转换为十进制数即 LBP 码,共 256 种),即得到该 窗口中心像素点的 LBP 值,并用这个值来反映该区域的纹理信息。如下图所示:
根据参考资料中的描述,LBP特征提取是在一个固定的窗口内提取特征值,而对于单张照片,没有固定的窗口,因此需要先将单张照片划分成一定的窗口进行特征提取。
具体步骤如下:
代码示例:
import cv2
# 读取单张照片
img = cv2.imread('path/to/image.jpg')
# 定义窗口大小,这里假设为30*30
win_size = (30, 30)
# 划分子图并提取特征
features = []
for i in range(0, img.shape[0] - win_size[0], win_size[0]):
for j in range(0, img.shape[1] - win_size[1], win_size[1]):
# 获取子图
sub_img = img[i:i+win_size[0], j:j+win_size[1]]
# 计算LBP特征
lbp_feat = calculate_lbp(sub_img)
# 将特征拼接到一起
features.append(lbp_feat)
代码示例:
# 定义窗口大小、采样点数、邻域半径等参数
win_size = (30, 30)
num_points = 8
radius = 1
def calculate_lbp(img):
# 将图像转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 计算LBP特征
lbp = cv2.LBP(gray, num_points, radius, cv2.LBP_UNIFORM)
# 统计特征值出现的次数
hist, _ = np.histogram(lbp.ravel(), bins=np.arange(0, num_points+3), density=True)
return hist
# 定义一个空的特征向量
feat_vec = np.zeros((1, 59))
# 遍历每个子图的特征并拼接到一起
for feat in features:
feat_vec = np.concatenate((feat_vec, feat), axis=1)
# 去除空白的第一列
feat_vec = feat_vec[:, 1:]
代码示例:
from sklearn.decomposition import PCA
# 定义PCA模型,将特征降至9维
pca_model = PCA(n_components=9)
# 对拼接后的特征向量进行PCA降维
pca_feat_vec = pca_model.fit_transform(feat_vec)
代码示例:
# 读取单张照片
img = cv2.imread('path/to/image.jpg')
# 计算LBP特征
lbp_feat = calculate_lbp(img)
# 将LBP特征拼接到一个1行59列的特征向量中
feat_vec = np.zeros((1, 59))
feat_vec[0, :] = lbp_feat
# 对特征进行PCA降维
pca_feat_vec = pca_model.transform(feat_vec)
注意:在使用PCA降维时,需要先在100张照片的特征向量上进行fit操作,然后使用fit_transform对照片的特征向量进行降维;而对于单张照片的LBP特征,只需要使用已经fit好的PCA模型(即上面的pca_model)进行transform操作即可,不需要重新fit模型。