农民身份识别挑战赛baseline(学习笔记)(一)

赛题地址:农民身份识别挑战赛
数据集如图:
在这里插入图片描述

1 图像特征统计(传统方法)个人解读

1.1 导入相关模块

import os, sys, glob, argparse
from PIL import Image
import cv2
import pandas as pd
import numpy as np
from tqdm import tqdm

from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import classification_report

os模块

sys模块

glob模块

  • glob模块可以使用Unix shell风格的通配符匹配符合特定格式的文件和文件夹,跟windows的文件搜索功能差不多。glob模块并非调用一个子shell实现搜索功能,而是在内部调用了os.listdir()和fnmatch.fnmatch()。
    python中glob库的使用_python glob_C小C的博客-CSDN博客

PIL模块

argparse模块

tqdm模块

1.2 数据收集与准备

# 读取数据集
train_path = glob.glob('./农民身份识别挑战赛公开数据/train/*')
test_path = glob.glob('./农民身份识别挑战赛公开数据/test/*')

train_path.sort()
test_path.sort()

train_df = pd.read_csv('农民身份识别挑战赛公开数据/train.csv')
train_df = train_df.sort_values(by='name')
train_label = train_df['label'].values
  • glob.glob('./农民身份识别挑战赛公开数据/train/*'):返回的是一个list列表,包含所有农民身份识别挑战赛公开数据/train文件夹里的文件路径
  • train_path.sort():对train_path列表中的所有路径名进行排序,因为前面的所属文件夹都一样,因此也就是对图片名称进行排序。
  • train_df = train_df.sort_values(by='name'):对train_df里的数据依照name进行排序。
  • train_label = train_df['label'].values:获取排序后的label值,此时的label与前面的train_path里的path是一一对应的。

1.3 特征提取

# 读取图像特征
def image_feat(path):
    img = cv2.imread(path, 0)
    img = img.astype(np.float32)
    feat = [
        (img != 0).sum(),              # 非零像素的数量
        (img == 0).sum(),              # 零像素的数量
        img.mean(),                    # 平均值
        img.std(),                     # 标准差
        len(np.where(img.mean(0))[0]), # 在列方向上平均值不为零的数量
        len(np.where(img.mean(1))[0]), # 在行方向上平均值不为零的数量
        img.mean(0).max(),             # 列方向上的最大平均值
        img.mean(1).max()              # 行方向上的最大平均值
    ]
    return feat
  • 该部分定义的image_feat()函数的主要功能是:
    1、传入图片路径path
    2、将图像数据类型转换为 np.float32,这样可以确保计算过程中的数据精度
    3、提取这张图片的相关特征
    4、以列表形式返回特征
  • 关于cv2.imread(path, 0)的第二个参数:
    cv2.IMREAD_COLOR:默认参数,读入一副彩色图片,忽略alpha通道,可用1作为实参替代
    cv2.IMREAD_GRAYSCALE:读入灰度图片,可用0作为实参替代
    cv2.IMREAD_UNCHANGED:顾名思义,读入完整图片,包括alpha通道,可用-1作为实参替代
    PS:alpha通道,又称A通道,是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度复信息,定义透明、不透明和半透明区域,其中黑表示全透明,白表示不透明,灰表示半透明。
  • np.where(img.mean(0))[0]
    numpy.where(condition, x, y):当满足的时候执行x,不满足执行y
    np.where(condition)np.asarray(condition).nonzero()的简写
    python用np.where遍历图像像素(更快的遍历)_np.where 图像像素值_YH_24H的博客-CSDN博客
  • np.array里的0和1
    np.where()[0] 表示行的索引;
    np.where()[1] 则表示列的索引。
  • img != 0
    网上未找到相关博客,经过个人试验,返回的是一个与灰度图img的shape相同的列表,若img在该位置上的灰度值不为0则是True,否则为False。

1.4 模型训练、评估与优化

# 训练集特征
train_feat = []
for path in tqdm(train_path):
    train_feat += [image_feat(path)]

# 测试集特征
test_feat = []
for path in tqdm(test_path):
    test_feat += [image_feat(path)]
    
# 训练集交叉验证
train_pred = cross_val_predict(
    KNeighborsClassifier(),
    np.array(train_feat),
    train_label
)
print(classification_report(train_label, train_pred))

# 模型训练与预测
model = KNeighborsClassifier()
model.fit(
    np.array(train_feat),
    train_label
)
test_pred = model.predict(np.array(test_feat))
  • 利用之前定义的image_feat函数对训练集和测试集中每一张图片进行提取特征操作,并分别将提取到的特征收集起来。先使用交叉验证评估模型在训练集上的性能,并打印相应的报告,然后再使用整个训练集对模型进行训练。
  • 交叉验证是一种更可靠的评估模型性能的方法,因为它能够更好地利用训练数据,减少因为数据划分而引入的随机性。
  • cross_val_predict通常接受以下参数:
    • estimator: 机器学习模型(例如分类器或回归器)
    • X: 特征数据,通常是一个二维数组
    • y: 目标标签,通常是一个一维数组
    • cv: 交叉验证的迭代器或次数
    • n_jobs: 并行处理的作业数量(如果可用)
  • classification_report是用于分类模型评估的函数,它常用于机器学习任务中,特别是用于多类别分类问题的结果分析和报告生成。接受以下参数:
      • y_true:实际的目标标签
    • y_pred:模型预测的目标标签
    • target_names:类别名称,用于指定每个类别的名称,方便在报告中显示
  • test_pred = model.predict(np.array(test_feat))np.array(test_feat)将test_feat列表转化为np数组:高效计算、确保兼容。

1.5 结果输出

# 生成测试集提交结果
submit = pd.DataFrame(
    {
    
    
        'name': [x.split('/')[-1] for x in test_path],
        'label': test_pred
})
submit = submit.sort_values(by='name')
submit.to_csv('submit.csv', index=None)
  • name的生成是遍历test_path,即之前生成的训练集图片路径。列表里的元素大概像这样:./农民身份识别挑战赛公开数据/train/abcdefg.jpg,因此用/分割,并取最后一个,即:abcdefg.jpg

2 个人总结

  • 传统提取图像特征的方法在结果上表现并不好,但是仍然可以有启发作用。
  • 通过仔细阅读,我学习到了tqdm以及glob库的使用,特别是glob,极大地方便了我后续读取文件的过程。
  • 有关注到这种K最邻近算法模型的构建方法,还有训练集的交叉验证过程,都给了我很大的启发。在此之前,我都是numpy和pandas一条龙,效率低而且缺乏严谨性,花费了很多时间效果却很差。
  • 我将自己每一次的学习笔记分享出去,方便你,还有我温习。

猜你喜欢

转载自blog.csdn.net/U202113837/article/details/132115079