news 2026/7/7 22:43:01

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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在中等规模数据集上表现最优,但决策树在小样本实时预测场景更具优势。直方图特征虽然简单,但对颜色分布明显的分类任务(如区分玻璃和金属)效果显著。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 22:42:37

Kimi K2.5前端实测:真实业务需求下的工程衰减分析

1. 项目背景与实测动机:为什么这次我坚持用真实前端需求来“考”Kimi K2.5最近朋友圈和各大技术社区又被刷屏了——“Kimi K2.5发布”“国产Gemini来了”“UI智能体终于落地”,标题一个比一个响亮。作为每天和前端工程、AI辅助开发打交道的从业者&#x…

作者头像 李华
网站建设 2026/7/7 22:42:11

Cursor对接私有LLM中转网关:Caddy反向代理实战指南

1. 项目概述:Cursor 接入第三方中转站不是“能不能”,而是“怎么接得稳、用得久”你打开 Cursor,敲下CtrlK,输入“帮我写一个解析 CSV 并生成统计图表的 Python 脚本”,结果卡在“思考中…”超过 40 秒,光标…

作者头像 李华
网站建设 2026/7/7 22:37:00

GitHub Copilot CLI实战手册:终端里的AI结对编程

1. 这不是另一个“AI编程助手”宣传稿,而是一线开发者用烂三台Mac后写的真实CLI操作手册 GitHub Copilot CLI——注意,是 CLI ,不是那个集成在VS Code右下角、点几下就弹出建议的图形界面插件。它是一个独立运行在终端里的命令行工具&#…

作者头像 李华
网站建设 2026/7/7 22:34:56

A3910与PIC18F4515电机控制方案详解

1. 认识A3910与PIC18F4515这对黄金搭档在嵌入式控制领域,电机驱动芯片与微控制器的组合就像赛车引擎与驾驶员的配合。A3910作为一款全桥电机驱动芯片,能够提供高达3A的持续输出电流,而PIC18F4515则是Microchip旗下经典的8位微控制器&#xff…

作者头像 李华
网站建设 2026/7/7 22:34:42

自助法原理与实战:小样本下统计推断的可靠替代方案

1. 项目概述:为什么统计学里人人都在说“自助法”,却很少有人真懂它在干什么“Bootstrapping”这个词,中文常被译作“自助法”或“拔靴法”,听起来像某种健身动作,或者程序员在服务器上敲的某条神秘命令。但其实它背后…

作者头像 李华
网站建设 2026/7/7 22:29:30

ClaudeCode实战工作流:16个提升开发者效率的结构化提示技巧

1. 这不是“AI使用指南”,而是ClaudeCode实战者的真实工作流切片你有没有过这种体验:打开ClaudeCode,输入一句“帮我写个Python脚本读取Excel并统计销售额”,它秒回一段代码——但运行报错;你再追问“为什么第12行报Ke…

作者头像 李华