资讯动态

Python掌纹识别实战:PCA、CNN与分类器融合源码解析

发布时间:2026/9/23 5:39:07 来源:尧图企业网站定制
简介这份资源是面向计算机、人工智能、通信工程等专业学生与教师的高分机器学习大作业参考包围绕Python掌纹识别任务展开可用于课程设计、毕业设计、项目立项演示或自学进阶。压缩包共18个文件约201KB以11个ipynb交互式笔记和5个py脚本为主另含license与gitignore覆盖图像预处理、特征提取、滤波器PCA、海明距离、分类与认证、结果评估等完整流程并包含CNN分类掌纹、预训练模型CNN、分类器融合及多进程时间对比等进阶实验。已有183人学习下载说明其具备一定参考价值。读者可据此获得一套可运行的掌纹识别方案理解从数据预处理到模型训练、分类器融合与性能评估的完整链路同时借助多进程脚本体会效率优化思路适合在现有代码基础上修改扩展完成自己的作业或课题。1. 从一份能跑通的掌纹识别源码说起它到底解决了什么问题如果你正在为机器学习大作业或者课程设计发愁大概率会遇到一个尴尬局面网上开源的代码要么跑不起来要么缺数据集说明要么只有模型没有评估。这份基于 Python 实现的掌纹识别项目恰好卡在一个很实用的位置上——它把从图像预处理、特征提取、分类器训练到结果评估的完整链路都拆成了独立的 notebook 和脚本并且附带了文档说明和训练好的模型。掌纹识别本身属于生物特征识别的一个分支和指纹、人脸相比它的纹理特征更稳定对光照和姿态的敏感度相对低一些适合用来做模式识别课程的综合实践。这个资源适合计算机、人工智能、通信工程等专业的在校学生也适合想快速了解传统特征工程加深度学习两条路线怎么对比的从业者。你拿到手之后能直接看到 PCA、滤波器、海明距离这些经典方法怎么落地也能看到 CNN 分类和预训练模型怎么接入省去了自己从零搭框架的时间。2. 拆开源码包文件结构与两条技术路线的分工2.1 从文件清单看项目的组织逻辑拿到machine-learning-master (2).zip之后先别急着运行。我一般会先把目录树看一遍因为这个项目的文件命名已经把技术路线暴露得很清楚了。根目录下既有.ipynb的 notebook也有.py的脚本还有LICENSE和.gitignore说明它原本是一个完整的代码仓库不是随手丢出来的几个文件。核心文件可以分成四组第一组是数据准备和特征提取包括大数据集中的特征提取.ipynb、feature_extraction.py、图像预处理.ipynb、PCA.py、滤波器PCA.ipynb第二组是分类与认证包括构建CNN分类掌纹.ipynb、预训练模型CNN.ipynb、classify.py、分类与认证.ipynb、分类器融合.ipynb第三组是评估与对比包括结果评估.ipynb、海明距离.ipynb、两个任务的对比.ipynb第四组是性能相关的辅助脚本包括多进程.py、多进程的时间对比.py。这种分法不是随意的它对应了掌纹识别里两条并行的技术路线一条是传统方法靠手工特征加距离度量另一条是深度学习方法靠 CNN 自动学特征。两条路线各有各的 notebook最后再用两个任务的对比.ipynb做汇总逻辑上是闭环的。2.2 传统路线与深度学习路线的选型理由为什么这个项目要同时保留两条路线因为掌纹识别这个任务本身就有两种典型的解题思路。传统路线通常先做图像预处理把掌纹区域从背景里分割出来然后用 Gabor 滤波器或者 PCA 做降维和特征提取最后用海明距离或者欧氏距离做匹配。这条路线的好处是可解释性强计算量小适合数据量不大的场景。深度学习路线则是直接把预处理后的图像送进 CNN让网络自己学特征最后接全连接层做分类。这条路线在数据量充足时效果更好但需要调参和算力。项目里滤波器PCA.ipynb和PCA.py对应传统路线构建CNN分类掌纹.ipynb和预训练模型CNN.ipynb对应深度学习路线分类器融合.ipynb则是尝试把两者的输出结合起来。如果你只是做课程作业建议先把传统路线跑通因为它的依赖少、调试快如果你要做毕设或者想冲高分再把 CNN 那条线加进来用两个任务的对比.ipynb做消融实验。2.3 运行前的环境准备与依赖检查这个项目用的是 Pythonnotebook 和脚本混用所以环境配置要稍微注意一下。我一般会先建一个干净的虚拟环境避免和系统里的包冲突。常见做法是用 conda 或者 venv然后根据 notebook 里 import 的包来装依赖。从文件命名和常见技术栈推断大概率会用到 numpy、opencv-python、scikit-learn、matplotlib、torch 或者 tensorflow。下面这段命令是我习惯的初始化流程你可以照着走一遍。# 创建虚拟环境Python 版本建议 3.8 到 3.10太新可能有些包不兼容 conda create -n palmprint python3.9 conda activate palmprint # 安装基础科学计算和图像处理包 pip install numpy opencv-python scikit-learn matplotlib pandas # 安装深度学习框架项目里 CNN 相关 notebook 需要二选一即可 pip install torch torchvision # 或者 pip install tensorflow装完之后先打开图像预处理.ipynb跑一遍看看能不能正常读取图片并显示。如果这一步就报错大概率是数据集路径不对或者 opencv 的版本和代码里的 API 不匹配。注意notebook 里的路径经常是作者本机的绝对路径你需要改成自己的相对路径。我一般会在项目根目录下建一个data文件夹把掌纹数据集放进去然后把代码里的路径统一改成./data/xxx。这一步虽然简单但却是最多人翻车的地方后面避坑章节会细说。3. 把传统路线跑通PCA、滤波器与海明距离的实操细节3.1 图像预处理ROI 提取与归一化的关键参数掌纹识别的第一步永远是把感兴趣区域ROI从原始手掌图像里切出来。这个项目里图像预处理.ipynb应该就是干这个的。常见做法是先用肤色分割或者边缘检测找到手掌轮廓然后根据关键点定位把掌心区域裁成一个固定大小的矩形。我一般会关注几个参数裁剪后的尺寸、是否做灰度化、是否做直方图均衡化。尺寸通常取 128x128 或者 256x256太小会丢纹理太大计算量上去但收益不明显。灰度化是必须的因为掌纹的纹理信息主要在亮度通道里。直方图均衡化可以增强对比度让后面的滤波器和 PCA 更稳定。如果你发现预处理后的图像噪点很多可以加一步高斯模糊核大小取 3x3 或 5x5别太大否则纹理会被抹掉。这个 notebook 里应该会有可视化输出跑完记得看一眼中间结果确认 ROI 切得对不对。3.2 PCA 降维与滤波器特征提取的代码拆解PCA.py和滤波器PCA.ipynb是传统路线的核心。PCA 的作用是把高维的掌纹图像投影到低维空间保留方差最大的方向这样既能降维又能去噪。滤波器通常是 Gabor 滤波器组不同方向和频率的 Gabor 核可以捕捉掌纹的纹理走向。下面这段代码是我根据常见实现整理的 PCA 部分你可以对照项目里的PCA.py看逻辑是否一致。import numpy as np from sklearn.decomposition import PCA from sklearn.preprocessing import StandardScaler # 假设 X 是展平后的掌纹图像矩阵形状为 (样本数, 像素数) # 先做标准化让每个像素维度均值为 0方差为 1 scaler StandardScaler() X_scaled scaler.fit_transform(X) # 保留 95% 的方差这个参数可以根据效果调整 pca PCA(n_components0.95) X_pca pca.fit_transform(X_scaled) # 查看降维后的维度以及主成分解释的方差比例 print(原始维度:, X.shape[1]) print(降维后维度:, X_pca.shape[1]) print(累计方差贡献率:, np.cumsum(pca.explained_variance_ratio_)[-1])这段代码的逻辑很直接先标准化再拟合 PCA。n_components0.95表示自动选择能解释 95% 方差的主成分个数这个值可以改成 0.90 或 0.99取决于你对精度和速度的权衡。如果你发现降维后维度还是很高可以手动指定一个整数比如 50 或 100。滤波器部分通常是在 PCA 之前做的用 Gabor 核卷积图像然后把滤波响应拼成特征向量。项目里滤波器PCA.ipynb应该是把这两步串起来了跑的时候注意看滤波器的方向和频率参数常见的是 4 个方向、3 个频率一共 12 个核。3.3 海明距离匹配与分类认证的评估方式海明距离.ipynb和分类与认证.ipynb对应的是匹配阶段。海明距离原本用于二值特征向量的比较在掌纹识别里通常是把特征二值化后计算不同位的比例。这个距离越小说明两个掌纹越相似。项目里应该会先算类内距离和类间距离然后画分布图看两者是否可分。如果类内距离和类间距离重叠严重说明特征区分度不够需要回到预处理或者特征提取阶段调参。分类与认证.ipynb可能把任务分成了两类分类是判断这个掌纹属于哪个人认证是判断这个掌纹是不是声称的那个人。这两个任务的评估指标不一样分类看准确率认证看误识率和拒识率。跑完这个 notebook你会得到一组 ROC 曲线或者 DET 曲线这些图在答辩的时候很能说明问题。3.4 多进程加速时间对比脚本的使用场景多进程.py和多进程的时间对比.py这两个文件容易被忽略但如果你要处理大规模数据集它们能省不少时间。掌纹识别的特征提取和匹配阶段有很多循环单进程跑起来很慢。常见做法是用multiprocessing把数据分块每个进程处理一部分最后合并结果。下面是一个简化的多进程模板你可以对照项目里的实现看差异。import multiprocessing as mp import time def process_chunk(chunk): # 这里放实际的特征提取或匹配逻辑 result [x * 2 for x in chunk] return result if __name__ __main__: data list(range(1000000)) chunk_size len(data) // 4 chunks [data[i:ichunk_size] for i in range(0, len(data), chunk_size)] start time.time() with mp.Pool(processes4) as pool: results pool.map(process_chunk, chunks) end time.time() print(f多进程耗时: {end - start:.2f} 秒) print(f结果总数: {sum(len(r) for r in results)})这段代码的关键参数是processes4一般设成 CPU 核心数。pool.map会把 chunks 分发到各个进程返回结果顺序和输入一致。注意Windows 下用 multiprocessing 必须把入口放在if __name__ __main__:里面否则会报错。项目里的多进程的时间对比.py应该是跑了单进程和多进程的对比你可以直接运行看加速比。如果加速比不明显可能是任务本身太小进程创建的开销盖过了并行收益。4. 深度学习路线CNN 分类与预训练模型的接入方式4.1 构建 CNN 分类掌纹的网络结构与训练参数构建CNN分类掌纹.ipynb是深度学习路线的起点。这个 notebook 里应该定义了一个卷积神经网络输入是预处理后的掌纹图像输出是类别数。常见的结构是两到三个卷积块每个块包含卷积层、激活函数、池化层最后接全连接层。卷积核大小通常取 3x3 或 5x5通道数从 32 开始逐层翻倍。激活函数用 ReLU池化用最大池化窗口 2x2。训练参数方面batch size 一般取 32 或 64学习率从 0.001 开始优化器用 Adam。如果你发现训练 loss 震荡可以把学习率降到 0.0001或者加一个学习率衰减策略。这个 notebook 里应该会有训练过程的 loss 和 accuracy 曲线跑完记得看曲线是否收敛。如果训练集准确率很高但验证集很低那就是过拟合了需要加 dropout 或者数据增强。4.2 预训练模型迁移学习的加载与微调预训练模型CNN.ipynb走的是迁移学习路线。常见做法是加载一个在 ImageNet 上预训练好的模型比如 ResNet18 或 VGG16把最后的全连接层改成掌纹的类别数然后冻结前面的卷积层只训练全连接层。如果数据量还可以也可以解冻最后几个卷积块做微调。下面这段代码是 PyTorch 下的典型流程你可以对照项目里的实现看用的是哪个模型。import torch import torch.nn as nn from torchvision import models # 加载预训练模型这里以 ResNet18 为例 model models.resnet18(pretrainedTrue) # 冻结所有卷积层参数 for param in model.parameters(): param.requires_grad False # 替换最后的全连接层输出类别数根据你的数据集调整 num_classes 100 model.fc nn.Linear(model.fc.in_features, num_classes) # 只训练全连接层的参数 optimizer torch.optim.Adam(model.fc.parameters(), lr0.001) criterion nn.CrossEntropyLoss() # 打印可训练参数数量确认冻结生效 trainable_params sum(p.numel() for p in model.parameters() if p.requires_grad) print(f可训练参数数量: {trainable_params})这段代码的关键点是requires_grad False和替换model.fc。冻结卷积层可以防止在小数据集上过拟合同时大幅减少训练时间。如果你发现效果不够好可以解冻最后一个卷积块把学习率设小一点比如 0.0001。注意预训练模型的输入尺寸通常是 224x224如果你的掌纹图像不是这个尺寸需要在预处理阶段 resize或者修改模型的输入层。项目里应该会处理这个细节跑之前先确认一下。4.3 分类器融合把传统特征和 CNN 输出拼起来分类器融合.ipynb是这个项目的一个亮点。它尝试把传统路线的手工特征和 CNN 学到的特征结合起来常见做法有两种一种是在特征层面拼接把 PCA 降维后的向量和 CNN 全连接层的输出 concat 在一起再送进一个分类器另一种是在决策层面融合比如对两个分类器的输出概率做加权平均。特征层面拼接更简单但要注意量纲问题最好先做归一化。决策层面融合更灵活但需要调权重。这个 notebook 里应该会有对比实验你可以看融合后的准确率是否比单一路线高。如果没高多少可能是两条路线的特征冗余了或者权重没调好。5. 避坑与排查跑这份源码时最容易翻车的五个地方5.1 数据集路径写死导致 FileNotFoundError现象打开 notebook 直接运行第一行读取图片就报FileNotFoundError提示找不到某个路径。原因作者在自己机器上用的是绝对路径比如/home/user/data/palm/001.jpg你拿到之后没有对应的目录结构。解决在项目根目录下建一个data文件夹把数据集按 notebook 里的相对路径放好然后用编辑器的全局替换功能把绝对路径改成相对路径。我一般会先搜一下代码里所有的open(、imread(、read_csv(确认路径都改干净了。5.2 OpenCV 版本差异导致 API 报错现象预处理 notebook 里调用cv2.findContours返回值的个数不对或者cv2.imread读出来是 None。原因OpenCV 4.x 和 3.x 的 API 有变化findContours在 4.x 里只返回两个值3.x 返回三个。另外imread如果路径里有中文或者空格也可能读不到。解决先确认cv2.__version__如果是 4.x把代码里_, contours, _ cv2.findContours(...)改成contours, _ cv2.findContours(...)。路径问题就统一用英文路径或者用cv2.imdecode配合np.fromfile读中文路径。5.3 深度学习框架版本不匹配导致模型加载失败现象运行预训练模型CNN.ipynb时加载预训练权重报错提示KeyError或者size mismatch。原因PyTorch 或 TensorFlow 的版本和作者用的不一致预训练权重的键名或者形状对不上。解决先看 notebook 开头有没有指定版本如果没有就装一个较稳定的版本比如 PyTorch 1.12 或 2.0。如果还是不行就手动下载对应的预训练权重文件用model.load_state_dict(torch.load(path), strictFalse)跳过不匹配的层。注意strictFalse会忽略缺失的键但你要确认忽略的是不是关键层。5.4 多进程在 Windows 下直接崩溃现象运行多进程.py时Windows 下报RuntimeError提示需要if __name__ __main__:保护。原因Windows 的进程启动方式是 spawn不是 fork子进程会重新导入主模块导致无限递归。解决把多进程的入口代码全部放到if __name__ __main__:下面包括Pool的创建和map的调用。另外传给子进程的函数必须是可序列化的不能是 lambda 或者嵌套函数。如果还是有问题可以把processes设成 1 先跑通再逐步增加。5.5 评估指标理解偏差导致结论错误现象结果评估.ipynb跑出来的准确率很高但实际测试时效果很差。原因可能把训练集和测试集混了或者用了不合适的评估指标。掌纹识别里分类任务看准确率没问题但认证任务要看误识率和拒识率这两个指标和阈值有关。解决先确认数据划分是否正确训练集、验证集、测试集要分开。然后看评估代码里用的指标是什么如果是认证任务要画 ROC 曲线计算等错误率EER。如果 EER 很高说明特征区分度不够需要回到特征提取阶段调参。6. 进阶技巧用两个任务的对比 notebook 做消融实验两个任务的对比.ipynb这个文件很多人跑完就关了其实它是最能出成果的地方。我一般会用它来做消融实验也就是控制变量看每个模块对最终效果的贡献。具体做法是先跑一个基线只用 PCA 加海明距离记录准确率和 EER然后加上 Gabor 滤波器看指标有没有提升再把 CNN 单独跑一遍记录指标最后跑分类器融合看融合后的指标。这样你就能得到一张对比表答辩的时候直接放出来评审一看就知道你做了系统性实验不是随便跑了个模型。下面是一个对比表的模板你可以根据实际跑出来的数字填。方法准确率EER训练时间推理时间PCA 海明距离待填待填待填待填Gabor PCA 海明距离待填待填待填待填CNN 单独待填待填待填待填分类器融合待填待填待填待填填完这张表你就能看出哪条路线更适合你的数据集。如果 CNN 单独效果最好但训练时间太长你可以考虑用预训练模型微调或者减少卷积层数。如果融合后提升不明显可能是两条路线的特征太相似了可以试试换不同的滤波器参数或者用不同的 CNN 架构。我自己的习惯是每次改完参数都重新跑一遍这个对比 notebook把结果记在表格里这样调参就不会乱。从那以后我每次做课程设计或者毕设都会强制走一遍消融实验不然心里没底。希望这个资源能帮你把大作业顺利跑通少走点弯路。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价