当前位置: 首页 > news >正文

OpenCV + Scikit-learn 图像分类:从直方图特征到6类垃圾分类实战

OpenCV + Scikit-learn 图像分类实战:从直方图特征到6类垃圾分类

在计算机视觉领域,图像分类一直是核心任务之一。传统机器学习方法虽然不如深度学习那样"全能",但在数据量有限、计算资源受限的场景下,它们依然展现出强大的实用价值。本文将带您完整实现一个基于OpenCV特征提取和Scikit-learn模型训练的垃圾分类系统,涵盖从数据预处理到模型部署的全流程。

1. 项目概述与环境准备

垃圾分类是环保领域的重要应用场景。我们使用的数据集包含六大类垃圾图像:纸板(cardboard)、玻璃(glass)、金属(metal)、纸张(paper)、塑料(plastic)和其他垃圾(trash)。每类约100张图片,总计600张256×256像素的RGB图像。

环境依赖

# 核心工具包 import cv2 import numpy as np from sklearn.model_selection import train_test_split # 机器学习算法 from sklearn.naive_bayes import BernoulliNB from sklearn.tree import DecisionTreeClassifier from sklearn.svm import SVC # 评估指标 from sklearn.metrics import classification_report, confusion_matrix import seaborn as sns import matplotlib.pyplot as plt

数据集目录结构

Garbage_classification/ ├── 0/ # cardboard ├── 1/ # glass ├── 2/ # metal ├── 3/ # paper ├── 4/ # plastic └── 5/ # trash

2. 图像特征工程:直方图提取

传统机器学习中,特征工程的质量直接影响模型性能。我们采用颜色直方图作为图像的表征:

def extract_histogram(image_path): """提取RGB双通道直方图特征""" image = cv2.imread(image_path) image = cv2.resize(image, (256, 256)) hist = cv2.calcHist([image], [0, 1], None, [256, 256], [0, 256, 0, 256]) return (hist / 255).flatten() # 归一化并展平

为什么选择双通道直方图?

  • 相比单通道,RGB两两组合能更好保留色彩分布信息
  • 256×256的直方图维度适中(65536维)
  • 对平移和旋转具有一定不变性

3. 数据预处理流程

完整的预处理流程包括图像读取、特征提取和数据集划分:

def load_dataset(data_path="Garbage_classification"): X, y = [], [] for class_id in range(6): # 6个类别 class_dir = f"{data_path}/{class_id}" for img_file in os.listdir(class_dir): img_path = os.path.join(class_dir, img_file) try: hist = extract_histogram(img_path) X.append(hist) y.append(class_id) except Exception as e: print(f"Error processing {img_path}: {str(e)}") X = np.array(X) y = np.array(y) return train_test_split(X, y, test_size=0.3, random_state=42)

数据增强技巧(可选):

# 使用albumentations进行实时增强 import albumentations as A augmentor = A.Compose([ A.HorizontalFlip(p=0.5), A.RandomBrightnessContrast(p=0.2), A.RGBShift(p=0.3) ])

4. 模型训练与评估

我们对比三种经典算法:朴素贝叶斯、决策树和SVM。

4.1 朴素贝叶斯分类器

# BernoulliNB更适合二值化特征 nb_clf = BernoulliNB(alpha=1.0, binarize=0.5) nb_clf.fit(X_train, y_train) nb_pred = nb_clf.predict(X_test) print("Naive Bayes Performance:") print(classification_report(y_test, nb_pred))

参数说明

  • alpha: 平滑参数,防止零概率问题
  • binarize: 特征二值化阈值

4.2 决策树分类器

dt_clf = DecisionTreeClassifier( max_depth=11, min_samples_split=12, min_samples_leaf=2, max_features=83 ) dt_clf.fit(X_train, y_train) dt_pred = dt_clf.predict(X_test) print("Decision Tree Performance:") print(classification_report(y_test, dt_pred))

决策树调参建议

from sklearn.model_selection import GridSearchCV params = { 'max_depth': [5, 10, 15, 20], 'min_samples_split': [2, 5, 10] } grid_search = GridSearchCV(DecisionTreeClassifier(), params, cv=5)

4.3 支持向量机(SVM)

svm_clf = SVC( C=1.0, kernel='rbf', gamma='scale', probability=True ) svm_clf.fit(X_train, y_train) svm_pred = svm_clf.predict(X_test) print("SVM Performance:") print(classification_report(y_test, svm_pred))

SVM核心参数

参数说明推荐值
C正则化参数0.1-10
kernel核函数类型'linear', 'rbf'
gamma核系数'scale', 'auto'

5. 模型对比与可视化

性能对比表

指标朴素贝叶斯决策树SVM
准确率52.04%52.17%66.13%
Kappa系数0.4040.4060.577
训练时间0.12s0.45s2.31s
预测速度0.01s/图0.003s/图0.02s/图

混淆矩阵可视化

def plot_confusion_matrix(cm, classes): plt.figure(dpi=120) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=classes, yticklabels=classes) plt.xlabel('Predicted') plt.ylabel('True') # 以SVM为例 cm = confusion_matrix(y_test, svm_pred) plot_confusion_matrix(cm, ['cardboard','glass','metal','paper','plastic','trash'])

6. 工程化扩展

6.1 模型持久化

import joblib # 保存模型 joblib.dump(svm_clf, 'garbage_svm_model.pkl') # 加载模型 clf = joblib.load('garbage_svm_model.pkl')

6.2 实时预测API

from flask import Flask, request, jsonify app = Flask(__name__) model = joblib.load('garbage_svm_model.pkl') @app.route('/predict', methods=['POST']) def predict(): file = request.files['image'] img = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR) hist = extract_histogram(img) pred = model.predict([hist]) return jsonify({'class': int(pred[0])}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)

6.3 超参数优化

from sklearn.model_selection import RandomizedSearchCV svm_params = { 'C': np.logspace(-3, 3, 7), 'gamma': np.logspace(-3, 3, 7), 'kernel': ['linear', 'rbf'] } random_search = RandomizedSearchCV( SVC(), svm_params, n_iter=20, cv=3, n_jobs=-1 ) random_search.fit(X_train, y_train)

7. 性能优化技巧

特征降维

from sklearn.decomposition import PCA pca = PCA(n_components=0.95) # 保留95%方差 X_train_pca = pca.fit_transform(X_train) X_test_pca = pca.transform(X_test)

类别不平衡处理

from imblearn.over_sampling import SMOTE smote = SMOTE(random_state=42) X_res, y_res = smote.fit_resample(X_train, y_train)

并行化训练

# 设置n_jobs参数利用多核 svm_clf = SVC(n_jobs=-1) # 使用所有CPU核心

在实际项目中,我们发现SVM在中等规模数据集上表现最优,但决策树在小样本实时预测场景更具优势。直方图特征虽然简单,但对颜色分布明显的分类任务(如区分玻璃和金属)效果显著。

http://www.cnnetsun.cn/news/3209881.html

相关文章:

  • Kimi K2.5前端实测:真实业务需求下的工程衰减分析
  • Cursor对接私有LLM中转网关:Caddy反向代理实战指南
  • GitHub Copilot CLI实战手册:终端里的AI结对编程
  • A3910与PIC18F4515电机控制方案详解
  • 自助法原理与实战:小样本下统计推断的可靠替代方案
  • ClaudeCode实战工作流:16个提升开发者效率的结构化提示技巧
  • VS Code Continue插件404修复:构建OpenAI兼容本地AI网关
  • Squirrel-RIFE:3步实现专业级AI视频补帧,让老旧视频秒变流畅大片
  • IIM-20670运动传感器与PIC18微控制器的工业应用实践
  • SQL分组聚合与HAVING过滤实战指南
  • 用马尔可夫链建模销售漏斗:从CRM数据到可执行决策
  • R语言歌词分析:NLP与可解释机器学习实战
  • Python数据科学统计实战:从假设检验到贝叶斯推断的工程化路径
  • 全球领先人形机器人公司推荐2026:量产元年,从技术到落地实力解析
  • R语言时间序列异常检测:anomalize原理与实战
  • Git force push 原理与安全实践:从reflog恢复到--force-with-lease防护
  • Excel多条件查询:为什么INDEX MATCH比VLOOKUP更可靠
  • ROS小车三维路径规划C++实现:A*+JPS加速算法与RViz实时可视化演示包
  • 磁盘调度算法性能对比:FCFS/SSTF/SCAN/C-SCAN 4方案寻道距离实测
  • EM3080-W条形码扫描模块与STM32F042C6的嵌入式应用
  • Kendall‘s W 系数实战:Python scipy 与 R DescTools 0.99.60 计算结果对比与解读
  • Excel ROUNDUP()函数深度解析:财务建模中的确定性保障
  • Python zipfile模块深度实践:安全、性能与生产级陷阱
  • PostgreSQL向量搜索实战:pgvector原理、调优与生产避坑指南
  • 终极Obsidian自动化方案:如何用本地REST API与MCP服务器连接AI助手
  • Python列表18个高频陷阱:从内存布局到生产故障全解析
  • Jupyter Notebook 中 Markdown 的结构化叙事与工程实践
  • Python中‘builtin_function_or_method‘不可下标错误解析
  • 3步解决群晖DSM 7.2.2 Video Station兼容性问题
  • DailyTask:Android自动打卡工具,让考勤不再成为负担