关于#python#的问题:PCA如何对单张照片提取特征

Python,用LBP提取了100张照片的特征,得到了100行59列的数组。之后用pca降维到了9维,到这都没什么问题。但是对单张照片使用LBP并且降维时却提示我这是个一维数组,该如何解决?LBP对单张照片提取的数据是1行59列的(一维),有办法给他弄成59维吗

  • 这篇博客: 基于LBP的图像特征提取并PCA降维后的分类研究中的 1.LBP特征的描述 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  •         原始的 LBP 算子定义为在 3*3 的窗口内,以窗口中心像素为阈值,将相邻的 8 个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为 1,否则为 0。这样,3*3 邻域内的 8 个点经比较可产生 8 位二进制数(通常转换为十进制数即 LBP 码,共 256 种),即得到该 窗口中心像素点的 LBP 值,并用这个值来反映该区域的纹理信息。如下图所示:

  • 以下回答由chatgpt基于相关博客总结生成:

    根据参考资料中的描述,LBP特征提取是在一个固定的窗口内提取特征值,而对于单张照片,没有固定的窗口,因此需要先将单张照片划分成一定的窗口进行特征提取。

    具体步骤如下:

    1. 将单张照片按照窗口大小划分成多个子图,这样每个子图都可以作为一个独立的窗口来提取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)
    
    1. 将多个子图的特征拼接成一个59维的特征向量,这可以直接通过对每个子图的特征进行拼接实现。

    代码示例:

    # 定义窗口大小、采样点数、邻域半径等参数
    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:]
    
    1. 将拼接后的特征向量进行PCA降维,这可以使用sklearn中的PCA模块来实现。

    代码示例:

    from sklearn.decomposition import PCA
    
    # 定义PCA模型,将特征降至9维
    pca_model = PCA(n_components=9)
    # 对拼接后的特征向量进行PCA降维
    pca_feat_vec = pca_model.fit_transform(feat_vec)
    
    1. 对单张照片的LBP特征进行降维,使用的操作和上一步一样,只不过需要将单张照片的LBP特征直接拼接到一个1行59列的特征向量中。

    代码示例:

    # 读取单张照片
    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模型。