☰
Python智能垃圾分类系统源码部署与实战:从环境搭建到摄像头实时识别
2026/10/12 15:36:05 网站建设 项目流程

简介:这份资源是面向高校计算机相关专业学生与Python初学者的一套智能垃圾分类系统完整源码,适用于毕业设计、期末大作业或课程实践等场景,能够帮助读者快速搭建一个可运行的垃圾分类识别项目。压缩包共包含20个文件,整体约35.12MB,以7个py源码文件为核心,辅以6个zip数据集、3个ui界面文件,以及cpp、jpg、md、png等说明与素材文件,覆盖界面设计、分类逻辑与数据组织等模块。目前已有297人学习下载,具备一定的参考热度。读者可从中获得完整的项目代码结构、UI界面文件、垃圾分类数据集与使用说明文档,便于理解界面与算法如何协同工作,并在此基础上进行二次开发或功能扩展,对需要提交完整项目成果的读者具有较高的实用价值。

1. 从一份「python的智能垃圾分类系统源码+使用说明.zip」说起:它到底能跑出什么

你拿到一个压缩包,名字叫「python的智能垃圾分类系统源码+使用说明.zip」,双击解压,里面大概率是几个 .py 文件、一个模型权重、一份 README,外加 requirements.txt。它解决的问题很具体:给一张垃圾照片,让程序告诉你这是可回收物、厨余垃圾、有害垃圾还是其他垃圾。对做课程设计、毕业设计、或者想快速搭一个 AI 识别 demo 的人来说,这就是一条从零到能演示的捷径。但源码包和「能跑起来」之间,隔着 Python 安装、依赖版本、模型路径、摄像头调用这几道坎。这篇笔记就按我实际部署这类项目的顺序,把环境、代码结构、参数、避坑点一次讲透,让你拿到包之后不用再到处搜「python安装教程」和「python安装numpy库的方法」。

2. 拆开压缩包先看什么:目录结构与技术栈判断

2.1 一个典型垃圾分类源码包的目录长什么样

不同作者打包习惯不同,但智能垃圾分类这类项目,结构高度趋同。解压后先别急着 pip install,用文件管理器或 tree 命令把目录看一遍,心里有个数。

# Linux / macOS 下查看目录树,Windows 可用 tree /f tree -L 3 -I "__pycache__|*.pyc"

常见的输出大概是这样:

garbage-classification/ ├── main.py # 主入口,通常是摄像头或图片推理 ├── train.py # 训练脚本,部分包会带 ├── predict.py # 单张图片预测 ├── models/ │ ├── model.py # 网络结构定义 │ └── best_model.pth # 训练好的权重 ├── datasets/ │ └── garbage/ # 分类数据集,按类别分文件夹 ├── utils/ │ ├── dataloader.py │ └── visualize.py ├── requirements.txt └── README.md # 使用说明

看到这个结构,基本能判断技术栈:PyTorch 或 TensorFlow 做图像分类,OpenCV 做图像读取和摄像头,Pillow 做预处理,numpy 做数组运算。如果 models 目录下是 .h5 文件,那是 Keras/TensorFlow;是 .pth 或 .pt,就是 PyTorch;是 .onnx,说明作者做了导出,推理可能用 onnxruntime。这一步判断很重要,因为它决定了你后面装哪个框架,装错了就是一堆 ImportError。

2.2 从 requirements.txt 反推 Python 版本和依赖

打开 requirements.txt,这是作者留给你的「配方」。但要注意,很多课程设计类的包,requirements.txt 写得非常随意,只写包名不写版本号,或者版本号是作者本机环境的,直接照装大概率冲突。

torch==1.10.0 torchvision==0.11.1 opencv-python==4.5.4.60 numpy==1.21.2 Pillow==8.3.2 matplotlib==3.4.3

看到 torch 1.10,就要意识到它对应的是 Python 3.6 到 3.9,Python 3.10 以上装这个版本会失败。这是第一个隐藏门槛。我的习惯是:先看 README 里有没有写 Python 版本,没有就看 torch 版本反推。如果 requirements 里完全没版本号,那就用 Python 3.8 这个兼容性最好的版本兜底,绝大多数垃圾分类源码都能跑。

提示:不要用系统自带的 Python 直接装依赖。用 conda 或 venv 建独立环境,否则把系统环境搞乱,后面想恢复很麻烦。

2.3 判断模型输入尺寸和类别数

在动手之前,还有两个参数必须提前确认:模型输入尺寸和分类类别数。这两个信息通常在 model.py 或 predict.py 里。

# 在 predict.py 或 config 里找类似这样的定义 IMG_SIZE = 224 # 输入图片尺寸 NUM_CLASSES = 4 # 分类数 CLASS_NAMES = ['可回收物', '厨余垃圾', '有害垃圾', '其他垃圾']

如果找不到,就去 model.py 看网络最后一层:

# 全连接层输出维度就是类别数 self.fc = nn.Linear(512, 4) # 这里的 4 就是 NUM_CLASSES

输入尺寸则看 transforms 里的 Resize:

transform = transforms.Compose([ transforms.Resize((224, 224)), # 输入尺寸 transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])

这两个参数决定了你后面换自己的图片或接摄像头时,需不需要改预处理代码。类别数决定了输出标签怎么映射,如果作者用的是英文标签而你想显示中文,就得改 CLASS_NAMES。这些都在读代码阶段确认清楚,比跑起来报错再回头找要省时间。

3. 把环境搭起来:Python 安装到依赖落地的完整命令

3.1 用 conda 建一个干净的 Python 环境

不管你是 Windows 还是 Linux,我都建议用 conda 管理环境,因为它能同时管 Python 版本和包,比纯 pip 省心。假设你已经装好 Miniconda 或 Anaconda。

# 创建名为 garbage 的环境,指定 Python 3.8 conda create -n garbage python=3.8 -y # 激活环境 conda activate garbage # 确认 Python 版本 python --version # 应输出 Python 3.8.x

为什么选 3.8 而不是更新的版本?因为垃圾分类源码里常见的 torch 1.8 到 1.10、opencv 4.5 这些版本,对 3.8 支持最稳。Python 3.11 以上,很多老版本 torch 根本没有对应的 wheel,pip 会尝试源码编译,然后在你机器上卡半小时再报错。这是血泪经验,别问我怎么知道的。

3.2 安装 PyTorch:CPU 版和 GPU 版怎么选

这一步是最大的分叉点。如果你的机器有 NVIDIA 显卡并且装了 CUDA,可以装 GPU 版,推理速度快很多;如果没有,就装 CPU 版,一样能跑,只是慢。

# CPU 版,通用,先保证能跑 pip install torch==1.10.0 torchvision==0.11.1 -f https://download.pytorch.org/whl/cpu/torch_stable.html # GPU 版(需要 CUDA 11.3),有显卡再考虑 # pip install torch==1.10.0+cu113 torchvision==0.11.1+cu113 -f https://download.pytorch.org/whl/torch_stable.html

装完验证一下:

import torch print(torch.__version__) print(torch.cuda.is_available()) # CPU 版会输出 False,正常

如果 torch.cuda.is_available() 是 False 但你确实有显卡,多半是 CUDA 版本和 torch 版本不匹配,或者显卡驱动太旧。这种情况先用 CPU 版把流程跑通,再回头折腾 GPU,不要一上来就卡在环境上。

3.3 装剩余依赖并处理版本冲突

torch 装好后,剩下的依赖用 pip 批量装。但不要直接 pip install -r requirements.txt,因为里面可能包含 torch,会覆盖你刚装好的版本。

# 先手动装核心依赖,指定兼容版本 pip install opencv-python==4.5.4.60 pip install numpy==1.21.2 pip install Pillow==8.3.2 pip install matplotlib==3.4.3 # 如果 requirements 里还有其他包,逐个装 pip install tqdm scikit-learn

装 numpy 时如果报「numpy 版本与 torch 不兼容」,通常是 numpy 太新。torch 1.10 配 numpy 1.21 最稳,numpy 1.24 以上会出问题。这就是为什么我不建议无脑装最新版。遇到冲突时,pip 会打印一段红字告诉你哪个包要求哪个版本,按它说的降级就行。

注意:Windows 下 opencv-python 有时会因为缺少 Visual C++ 运行库而导入失败,报错信息是「DLL load failed」。装一个 Visual C++ Redistributable 就能解决,这是 Windows 特有的坑。

3.4 验证环境:跑通一个最小推理

环境装完,别急着跑 main.py。先写一个最小脚本,验证 torch 和 opencv 都能用,并且能加载模型。

import torch import cv2 import numpy as np from PIL import Image # 1. 验证基础库 print("torch:", torch.__version__) print("opencv:", cv2.__version__) print("numpy:", np.__version__) # 2. 验证能否加载权重(把路径换成你包里的实际路径) try: model = torch.load("models/best_model.pth", map_location="cpu") print("模型加载成功") except Exception as e: print("模型加载失败:", e)

如果这一步报「No module named xxx」,说明还有依赖没装;如果报「FileNotFoundError」,说明权重路径不对,去 models 目录确认文件名。这一步过了,后面才有意义。很多人跳过验证直接跑主程序,结果报错信息一大堆,分不清是环境问题还是代码问题。

4. 跑通推理:图片预测和摄像头实时识别的参数怎么调

4.1 单张图片预测:从命令行到代码逐行说明

大部分源码包会提供一个 predict.py,接受图片路径作为参数。先看它的入口:

# predict.py 简化版 import argparse import torch from PIL import Image from torchvision import transforms parser = argparse.ArgumentParser() parser.add_argument("--image", type=str, required=True, help="图片路径") parser.add_argument("--model", type=str, default="models/best_model.pth") args = parser.parse_args() # 预处理,必须和训练时一致 transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) img = Image.open(args.image).convert("RGB") input_tensor = transform(img).unsqueeze(0) # 增加 batch 维度 model = torch.load(args.model, map_location="cpu") model.eval() with torch.no_grad(): output = model(input_tensor) prob = torch.softmax(output, dim=1) pred = torch.argmax(prob, dim=1).item() print("预测类别:", pred, "置信度:", prob[0][pred].item())

运行命令:

python predict.py --image test.jpg

这里有几个参数必须和训练时对齐,否则预测结果会乱:Resize 的尺寸、Normalize 的 mean 和 std。如果作者训练时用的是 256 输入然后 CenterCrop 到 224,你这里只写 Resize 224,结果会有偏差。判断方法:去 train.py 或 datasets 的 transforms 里找训练时的预处理,照抄过来。这是最容易被忽略、又最影响准确率的地方。

4.2 接摄像头做实时识别:帧率、分辨率与推理耗时

把 predict.py 改成读摄像头,是课程设计演示的常见需求。核心改动是把图片源换成 cv2.VideoCapture。

import cv2 import torch from PIL import Image from torchvision import transforms cap = cv2.VideoCapture(0) # 0 是默认摄像头 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) model = torch.load("models/best_model.pth", map_location="cpu") model.eval() while True: ret, frame = cap.read() if not ret: break # OpenCV 是 BGR,PIL 需要 RGB img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)) input_tensor = transform(img).unsqueeze(0) with torch.no_grad(): output = model(input_tensor) prob = torch.softmax(output, dim=1) pred = torch.argmax(prob, dim=1).item() conf = prob[0][pred].item() cv2.putText(frame, f"class:{pred} {conf:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) cv2.imshow("garbage", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()

这段代码能跑,但 CPU 上帧率可能只有 3 到 5 帧,画面会卡。原因是每帧都做一次完整推理。优化方向有三个:把输入分辨率降到 160 或 128(如果模型允许)、用 torch.jit 或 onnxruntime 加速、或者隔帧推理。参数上,cap.set 的 640x480 是采集分辨率,和模型输入 224 是两回事,不要混淆。如果摄像头打不开,先确认 cap.isOpened() 返回 True,Linux 下还要确认 /dev/video0 权限。

4.3 批量测试和置信度阈值:怎么判断模型靠不靠谱

演示之外,你可能想批量测一批图片,看模型在哪些类别上容易错。写一个循环遍历测试集,统计混淆矩阵。

import os import torch from PIL import Image from torchvision import transforms from collections import defaultdict transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ]) model = torch.load("models/best_model.pth", map_location="cpu") model.eval() test_dir = "datasets/garbage/val" correct = 0 total = 0 confusion = defaultdict(lambda: defaultdict(int)) for cls_name in os.listdir(test_dir): cls_dir = os.path.join(test_dir, cls_name) if not os.path.isdir(cls_dir): continue for fname in os.listdir(cls_dir): img_path = os.path.join(cls_dir, fname) img = Image.open(img_path).convert("RGB") input_tensor = transform(img).unsqueeze(0) with torch.no_grad(): output = model(input_tensor) pred = torch.argmax(output, dim=1).item() confusion[cls_name][pred] += 1 total += 1 print("总样本:", total) for true_cls, preds in confusion.items(): print(true_cls, dict(preds))

跑完看混淆矩阵,如果某一类大量被预测成另一类,比如「有害垃圾」总被认成「其他垃圾」,说明这两类特征太像或者训练样本不均衡。置信度低于 0.6 的样本,实际演示时可以考虑显示「不确定」,比硬给一个错答案更稳妥。这个阈值没有标准值,看你的场景能接受多少误判。

5. 避坑与排查:源码包跑不起来时先查这几条

5.1 现象:ImportError: No module named 'torch'

原因:当前 Python 环境没装 torch,或者你激活的环境不对。conda 环境切换后,pip 和 python 必须来自同一个环境。

解决:先which python(Linux)或where python(Windows)确认解释器路径在 conda 环境内,再pip list | grep torch确认装了。如果装了还报错,多半是 IDE 里选的解释器不是命令行那个,去 IDE 设置里改成 conda 环境的 python。

5.2 现象:模型加载报「Missing key(s) in state_dict」

原因:权重文件和 model.py 里的网络结构对不上。常见于作者改了网络但没重新训练,或者你下载的权重和源码版本不匹配。

解决:先看报错里缺哪些 key,如果是module.前缀,说明权重是用 DataParallel 保存的,加载时要去掉前缀:

state_dict = torch.load("best_model.pth", map_location="cpu") new_state_dict = {k.replace("module.", ""): v for k, v in state_dict.items()} model.load_state_dict(new_state_dict)

如果缺的是分类层,说明类别数不一致,需要改 model.py 里全连接层输出维度再加载。

5.3 现象:预测结果全是同一类,置信度还很高

原因:预处理不一致,最常见的是 Normalize 的 mean/std 和训练时不同,或者图片通道顺序搞反(BGR 当 RGB 用)。

解决:去 train.py 里找训练时的 transform,逐行对照。OpenCV 读进来是 BGR,PIL 是 RGB,混用会导致颜色通道错位,模型看到的图和训练时分布完全不同。统一用 PIL 读图,或者 cv2 读完后 cvtColor 转 RGB。

5.4 现象:摄像头画面卡顿,帧率个位数

原因:CPU 推理每帧耗时 200ms 以上,加上摄像头采集和显示的开销。

解决:降低模型输入尺寸(如果模型支持动态输入)、改用 onnxruntime 推理、或者隔帧推理。演示场景下,隔帧推理最省事:用一个计数器,每 3 帧才做一次推理,中间帧复用上次结果。视觉上几乎看不出差别,帧率能翻倍。

5.5 现象:中文标签显示成方块

原因:OpenCV 的 putText 不支持中文,需要 PIL 绘制或者用 freetype。

解决:把 frame 转成 PIL Image,用 ImageDraw 写中文,再转回 OpenCV 格式。或者简单点,演示时用英文标签,界面文字另做。这个坑不影响识别逻辑,但演示时很显眼,提前处理掉。

6. 进阶:把这份源码改成能持续用的工具

跑通 demo 只是第一步。如果你想让这个垃圾分类系统真正有用,而不是交完作业就删,有几个方向值得投入。第一是换模型,源码里如果是自己搭的小 CNN,可以换成 MobileNetV3 或 EfficientNet-B0,用 torchvision 预训练权重微调,准确率通常能涨 5 到 10 个百分点,而且推理更快。第二是加数据增强,垃圾分类的难点在于同一类物品形态差异大,随机裁剪、颜色抖动、旋转这些增强能明显提升泛化。第三是导出 ONNX,用 onnxruntime 推理,CPU 上通常比原生 PyTorch 快 1.5 到 2 倍,部署到没有 torch 的机器上也方便。

# 导出 ONNX 示例 import torch model = torch.load("models/best_model.pth", map_location="cpu") model.eval() dummy = torch.randn(1, 3, 224, 224) torch.onnx.export(model, dummy, "garbage.onnx", input_names=["input"], output_names=["output"], dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}})

导出后用 onnxruntime 加载验证:

import onnxruntime as ort import numpy as np sess = ort.InferenceSession("garbage.onnx") input_name = sess.get_inputs()[0].name dummy = np.random.randn(1, 3, 224, 224).astype(np.float32) out = sess.run(None, {input_name: dummy}) print(out[0].shape) # 应为 (1, 4)

验证方法上,我习惯用一批固定测试图,对比 PyTorch 和 ONNX 的输出,如果每个样本的 argmax 一致,说明导出没问题。如果差异大,检查导出时的 opset 版本和输入尺寸。

最后说个我自己的习惯:拿到任何源码包,先不改代码,原样跑通一遍,把基线结果记下来,再动手改。这样一旦改出问题,能快速判断是新引入的还是原本就有。垃圾分类这类项目,模型和数据的质量决定上限,代码只是把上限兑现出来。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询