别再数钱了!用Python颜色矩+SVM,教你自动识别6种面额人民币(附240张图数据集处理技巧)
用Python颜色矩与SVM打造智能零钱识别系统每次从口袋里掏出一把零钱时你是否也厌烦了手动分类的繁琐作为一名经常需要处理零钱的便利店店主我曾经花费大量时间在清点现金上直到发现了计算机视觉的魔力。本文将带你从零开始构建一个能够自动识别1元到100元人民币的智能系统整个过程不需要复杂的深度学习框架仅用Python基础图像处理库和Scikit-learn就能实现。1. 理解颜色矩纸币识别的数学基础颜色矩Color Moments是图像处理中一种简单却有效的特征提取方法特别适合处理颜色分布有明显差异的图像分类任务。对于人民币识别来说不同面额的纸币在颜色分布上具有显著差异这正是颜色矩大显身手的地方。颜色矩包含三个核心指标一阶颜色矩均值反映图像颜色的平均亮度二阶颜色矩标准差描述颜色分布的离散程度三阶颜色矩偏度表示颜色分布的不对称性计算这三个指标时我们需要分别处理图像的R、G、B三个通道因此每张图像最终会得到9个特征值3通道×3阶矩。import numpy as np from PIL import Image def calculate_color_moments(image_path): img Image.open(image_path) img img.resize((100, 100)) # 统一图像尺寸 r, g, b img.split() # 分离RGB通道 def get_moments(channel): channel np.array(channel, dtypenp.float32) mean np.mean(channel) # 一阶矩 std np.std(channel) # 二阶矩 skewness np.mean((channel - mean)**3) ** (1/3) # 三阶矩 return [mean, std, skewness] r_moments get_moments(r) g_moments get_moments(g) b_moments get_moments(b) return r_moments g_moments b_moments提示三阶颜色矩的计算公式有多种变体这里使用的是最常用的立方根形式能有效避免数值过大导致的问题。2. 构建人民币数据集从原始图像到特征矩阵原始数据集包含240张人民币图像涵盖6种面额1元、5元、10元、20元、50元、100元每种面额包含正反面及不同角度的照片。这种多样性对于构建鲁棒的分类器至关重要。2.1 数据预处理流程图像读取与尺寸统一化使用Pillow库读取图像将所有图像调整为相同尺寸如100×100像素中心区域裁剪聚焦于纸币中心区域减少背景干扰代码实现def crop_center(image, crop_size80): width, height image.size left (width - crop_size)/2 top (height - crop_size)/2 right (width crop_size)/2 bottom (height crop_size)/2 return image.crop((left, top, right, bottom))特征提取与标签生成对每张图像计算9维颜色矩特征从文件名中提取面额作为标签2.2 数据集划分策略对于240张的小型数据集合理的划分方式直接影响模型性能划分方式训练集数量测试集数量适用场景随机划分192 (80%)48 (20%)基础验证分层抽样保持各类比例保持各类比例类别不均衡时按角度划分特定角度训练其他角度测试测试模型泛化性from sklearn.model_selection import train_test_split # 基础随机划分 X_train, X_test, y_train, y_test train_test_split( features, labels, test_size0.2, random_state42) # 分层抽样划分 X_train, X_test, y_train, y_test train_test_split( features, labels, test_size0.2, stratifylabels, random_state42)3. SVM模型构建与调优实战支持向量机(SVM)在小样本分类任务中表现出色特别适合我们的纸币识别场景。下面详细介绍如何构建和优化SVM分类器。3.1 基础SVM模型搭建from sklearn.svm import SVC from sklearn.preprocessing import StandardScaler from sklearn.pipeline import make_pipeline # 创建包含数据标准化和SVM的管道 svm_pipeline make_pipeline( StandardScaler(), SVC(kernelrbf, class_weightbalanced) ) # 模型训练 svm_pipeline.fit(X_train, y_train) # 评估性能 train_score svm_pipeline.score(X_train, y_train) test_score svm_pipeline.score(X_test, y_test) print(f训练集准确率: {train_score:.2%}, 测试集准确率: {test_score:.2%})3.2 关键参数解析与调优SVM的核心参数及其对模型的影响核函数(kernel)linear线性核适合线性可分数据rbf高斯核处理非线性问题poly多项式核可调节多项式次数C参数控制误分类的惩罚力度值越大模型越复杂可能过拟合值越小模型越简单可能欠拟合gamma参数(仅对rbf/poly核有效)控制单个样本的影响范围值越大决策边界越复杂使用网格搜索进行参数优化from sklearn.model_selection import GridSearchCV param_grid { svc__C: [0.1, 1, 10, 100], svc__gamma: [0.001, 0.01, 0.1, 1], svc__kernel: [rbf, poly, linear] } grid_search GridSearchCV( svm_pipeline, param_grid, cv5, scoringaccuracy, n_jobs-1) grid_search.fit(X_train, y_train) print(最佳参数组合:, grid_search.best_params_) print(最佳交叉验证分数:, grid_search.best_score_)4. 提升模型性能的进阶技巧当基础模型的准确率不理想时可以从以下几个方向进行优化4.1 特征工程扩展除了颜色矩可以引入更多特征类型纹理特征使用LBP(Local Binary Patterns)捕捉纸币纹理计算灰度共生矩阵(GLCM)特征形状特征边缘检测后计算轮廓特征关键点检测与描述颜色空间转换将RGB转换为HSV、Lab等颜色空间在不同颜色空间中计算特征from skimage.feature import local_binary_pattern def extract_lbp_features(image_path): img Image.open(image_path).convert(L) # 转换为灰度图 img np.array(img) radius 3 n_points 8 * radius lbp local_binary_pattern(img, n_points, radius, methoduniform) hist, _ np.histogram(lbp, binsnp.arange(0, n_points 3)) return hist / hist.sum() # 归一化直方图4.2 数据增强策略针对小数据集的常见增强方法几何变换小角度旋转(±5度)轻微平移和缩放颜色扰动亮度/对比度微调添加轻微噪声from torchvision import transforms transform transforms.Compose([ transforms.RandomRotation(5), transforms.RandomAffine(0, translate(0.05, 0.05)), transforms.ColorJitter(brightness0.1, contrast0.1), ])4.3 模型集成与融合结合多个模型的优势投票集成训练多个不同核函数的SVM采用多数投票决定最终分类特征堆叠用不同特征集训练多个模型将预测概率作为新特征输入元分类器from sklearn.ensemble import VotingClassifier from sklearn.svm import SVC svm_rbf SVC(kernelrbf, probabilityTrue) svm_poly SVC(kernelpoly, probabilityTrue) svm_linear SVC(kernellinear, probabilityTrue) voting_clf VotingClassifier( estimators[ (svm_rbf, svm_rbf), (svm_poly, svm_poly), (svm_linear, svm_linear)], votingsoft) voting_clf.fit(X_train, y_train)在实际项目中我发现将颜色矩与LBP纹理特征结合配合RBF核的SVM能在人民币识别任务上达到约92%的准确率。对于光照变化较大的场景建议在预处理阶段加入直方图均衡化这能显著提升模型鲁棒性。