Django语音识别垃圾分类系统:从录音上传到分类入库的完整实战
发布时间:2026/10/8 10:44:15 作者:尧图编辑部 阅读量:1,286

简介一份基于语音识别的智能垃圾分类系统源码包采用Python Django与MySQL技术栈面向计算机相关专业学生与开发者适用于毕业设计、课程设计或项目实训参考。系统划分为前台与后台两大模块前台支持系统信息展示、语音上传分类、用户登录与资料修改后台支持垃圾分类规则管理、用户维护与系统信息配置覆盖了常见的Web管理功能。包内共305个文件含31个Python源文件、14个HTML页面及对应CSS/JS样式脚本另有75张GIF演示截图与WAV/MP3语音样例SQL脚本可直接初始化数据库压缩包整体9.4MB结构清晰便于快速部署和二次开发。已有388人学习附说明文档与演示视频能帮助读者更直观地理解语音识别在垃圾分类中的应用流程。1. Django 语音识别智能垃圾分类系统一套把录音、识别、分类串起来的实战项目又到毕业设计季很多朋友问我要那种“既能写进简历、又能现场演示”的 Django 项目。我手头这套基于语音识别的智能垃圾分类系统正好是答案。它不只是一串 CRUD 代码而是把 浏览器录音 → 后端接收 → 语音识别 → 垃圾分类 整个闭环跑通源码、说明文档、演示视频三件套齐全。适合正在选毕设题目、但不想只写图书管理系统的学生也适合想快速了解语音识别怎么接入 Web 的开发者。这套系统最大的价值在于它让你看到语音识别不是只能写在本地脚本里而是能真实融合进一个 Django Web 应用而且垃圾分类这个业务规则足够具体方便你二次扩展。2. 语音识别与垃圾分类的技术选型为什么这么搭才合理2.1 语音识别在 Web 项目里的落地路径录音、上传与识别做这个项目之前我先把语音识别的落地路径理了一遍。在浏览器端用 Web Audio API 可以录制用户语音生成 wav 或 webm 格式的音频文件但识别动作放在前端并不合适一是模型体积太大二是各浏览器兼容性参差三是识别结果要跟后端业务联动。所以这套系统的设计是前端负责录音和上传后端 Django 接收音频文件后再调用语音识别引擎转文字。这个分工把录音和识别解耦后续换引擎不需要动前端代码。常见做法是用navigator.mediaDevices.getUserMedia获取麦克风流配合 MediaRecorder 封装录音组件。项目里用的是 RecordRTC 封装它会把音频转成 blob再通过 FormData 发给 Django 后端。前端录音和上传的核心逻辑大致如下// 录音与上传基于 RecordRTC 封装 async function startRecording() { const stream await navigator.mediaDevices.getUserMedia({ audio: true }); recorder RecordRTC(stream, { type: audio, mimeType: audio/wav, // 录成 wav后端直接用 SpeechRecognition 读取 recorderType: StereoAudioRecorder, numberOfAudioChannels: 1, desiredSampRate: 16000, // 16kHz 采样率语音识别引擎最常用的配置 }); recorder.startRecording(); } function stopRecording() { recorder.stopRecording(async () { const blob recorder.getBlob(); const formData new FormData(); formData.append(audio, blob, voice.wav); // 字段名和后端对应 const response await fetch(/api/garbage/recognize/, { method: POST, body: formData, }); const result await response.json(); renderResult(result); }); }mimeType和desiredSampRate是这里最值得注意的参数。audio/wav保证生成的音频能被 SpeechRecognition 直接识别不需要额外转码采样率 16kHz 是大多数语音识别引擎的默认输入同时也能控制上传体积。如果录成 webm要么后端装 ffmpeg 转码要么选支持 webm 的引擎这会在第 5 章避坑里详细说。2.2 Django 对比 Flask为什么选 Django 做这个系统技术选型时不少朋友会纠结 Django 和 Flask。Flask 确实更轻一个文件就能启动但做这种带用户、带管理后台、带数据库的完整系统Flask 需要自己拼 ORM、表单、认证拼完可能比 Django 还复杂。Django 自带的东西在这里几乎全用上了用户认证系统实现注册登录Admin 后台直接管理垃圾分类日志和垃圾词库ORM 负责存储识别记录。从毕设答辩的角度看Django 项目的“可讲点”也更多——中间件、CSRF 防护、Session 管理、Admin 定制都是能展开说的内容。下面这张表是我拆这套项目时整理的对比逻辑对比项DjangoFlask用户认证内置完整认证改配置就能用需要 Flask-Login 或手写Admin 后台自带注册模型即可管理数据无需第三方扩展ORM 能力内置支持迁移SQLAlchemy配置略繁琐项目结构固定 app 分层适合中等以上项目自由但需要自己约定学习曲线前 1 周偏陡后面很顺上手快但完整功能要拼装对于一套要展示“用户登录、语音上传、识别结果入库、历史记录查询”的系统Django 的开箱即用优势非常明显。这套项目里把语音识别相关功能放在一个独立 app 里比如名为garbage的 app数据流清晰后期改分类规则也方便。2.3 系统数据流与模块边界从声音到分类结果拆开源码后我发现整个处理链是六个步骤每一步的输入输出都很清楚浏览器录下用户语音形成 wav 文件。通过 Ajax 请求把音频 POST 到 Django 的识别接口。Django 视图收到文件转给语音识别模块。语音识别模块返回文本比如“可乐瓶”。分类模块根据文本匹配垃圾类别。Django 把分类结果和识别文本存入数据库同时返回 JSON 给前端。这套设计里最关键的是第 4、5 步之间的解耦。语音识别只负责“听”垃圾分类只负责“想”两个模块都不依赖具体实现。也就是说你以后把 SpeechRecognition 换成讯飞或百度 API分类模块一行都不用改。3. 从压缩包到能跑环境配置、源码结构与核心接口复现3.1 环境准备Python 版本、虚拟环境与依赖安装拿到压缩包后第一步不是急着看代码而是先把环境搭好。这套项目基于 Django我拆的时候用的 Python 3.9Django 版本在 requirements.txt 里锁定。建议直接建独立虚拟环境避免和系统 Python 打架。下面是一套可复用的安装流程# 创建虚拟环境Windows 和 Linux 都适用 python -m venv venv # 激活虚拟环境Windows venv\Scripts\activate # 激活虚拟环境Linux / macOS source venv/bin/activate # 安装依赖 pip install -r requirements.txt # 执行数据库迁移 python manage.py migrate # 创建超级管理员 python manage.py createsuperuser # 启动开发服务器 python manage.py runserver 0.0.0.0:8000requirements.txt里通常至少包含Django、SpeechRecognition、recordrc或pydub之类。migrate这步很关键它会把 Django 内置的表和项目自定义的表都建好如果漏了访问用户登录页面会直接报 no such table。创建超级管理员是为了进 Admin 后台管理垃圾词库演示时特别有用。3.2 源码目录结构逐层拆解解压后建议先看目录结构别急着点开所有文件。我习惯用 tree 命令先建立整体认知tree /f # Windows tree -L 3 # Linux / macOS项目的典型目录长这样注释里写了每个部分的职责django_garbage/ ├── manage.py # Django 管理入口 ├── config/ # 项目配置目录 │ ├── settings.py # 全局配置媒体路径、app 注册 │ ├── urls.py # 根路由 │ └── wsgi.py # 部署入口 ├── garbage/ # 垃圾分类应用 │ ├── views.py # 视图登录、上传、识别、分类 │ ├── urls.py # 应用内路由 │ ├── models.py # 分类记录表、垃圾词库表 │ ├── recognition.py # 语音识别封装模块 │ └── classify.py # 垃圾分类规则模块 ├── templates/ # Django HTML 模板 │ ├── base.html │ ├── index.html # 主页面包含录音按钮 │ └── login.html ├── static/ # JS/CSS/图片 │ ├── js/recorder.js # 前端录音逻辑 │ └── css/style.css ├── media/ # 用户上传的音频文件按日期存放 └── requirements.txt注意recognition.py和classify.py被独立拆出来了这是整个源码里最值得读的两个文件。它们不依赖 Django 的请求对象所以可以单独写单元测试。如果以后想换语音识别引擎只改recognition.py如果想改分类逻辑只改classify.py。3.3 核心接口复现语音上传与识别返回系统的主接口是/api/garbage/recognize/它负责接收音频、识别文本、返回分类结果。我在源码里看到的核心视图逻辑如下# garbage/views.py import json from django.views.decorators.csrf import csrf_exempt from django.http import JsonResponse from .recognition import recognize_audio from .classify import classify_text csrf_exempt # 仅为演示方便生产环境建议保留 CSRF 校验 def recognize(request): if request.method ! POST: return JsonResponse({error: 只支持 POST 请求}, status405) audio_file request.FILES.get(audio) if not audio_file: return JsonResponse({error: 缺少音频文件}, status400) # 保存音频到 media 目录文件名加时间戳防止覆盖 from django.utils.timezone import now path fmedia/voice/{now().strftime(%Y%m%d%H%M%S)}_{audio_file.name} with open(path, wb) as f: for chunk in audio_file.chunks(): f.write(chunk) # 调用语音识别模块返回文本 text recognize_audio(path) # 调用分类模块返回类别 category classify_text(text) return JsonResponse({ text: text, category: category, audio_path: path, })这段视图的逻辑很直白从请求里取音频文件落盘然后依次调用识别和分类。csrf_exempt只是开发调试用因为前端 fetch 默认不带 CSRF token生产环境要保留校验否则安全审核过不了。写文件时用时间戳拼名字避免多人同时上传互相覆盖。recognize_audio和classify_text是两个纯函数返回都是字符串这样后续在命令行里也能直接测。对应的 URL 路由在garbage/urls.py里注册# garbage/urls.py from django.urls import path from . import views urlpatterns [ path(api/garbage/recognize/, views.recognize, namerecognize), ]路由只留了一个入口其他页面走 Django 模板渲染。这样处理的好处是前端页面和接口分离调试时可以用 Postman 直接打接口不必非开浏览器。4. 识别与分类的调参细节让系统从“能跑”到“好用”4.1 语音识别引擎的参数配置与精度平衡这套项目用的语音识别库是 SpeechRecognition它本身不是引擎而是一层封装底层可以接 Google Web Speech、Sphinx、讯飞、百度等。默认配置通常走recognize_google因为不需要申请 API key但它是联网识别且在线环境下识别中文效果不错。如果毕设演示时断网就需要换成离线方案比如 Vosk 或 PaddleSpeech。源码里recognition.py的封装大概是这样的# garbage/recognition.py import speech_recognition as sr def recognize_audio(audio_path): recognizer sr.Recognizer() with sr.AudioFile(audio_path) as source: # 调整环境噪声阈值数值越小越敏感默认 300 左右 recognizer.adjust_for_ambient_noise(source, duration0.5) audio_data recognizer.record(source) try: # language 参数控制识别语言zh-CN 表示简体中文 text recognizer.recognize_google(audio_data, languagezh-CN) return text except sr.UnknownValueError: return 未识别出有效语音 except sr.RequestError as e: return f语音服务请求失败: {e}adjust_for_ambient_noise这个参数很影响效果。duration0.5表示取音频前 0.5 秒做环境噪音基线如果演示现场很吵建议把时长提到 1 秒但别超过 1.5 秒否则会吃掉真正的语音开头。languagezh-CN是中文识别必须的漏掉这条默认会按英文识别中文全变乱码符。另外SpeechRecognition 对 wav 文件的编码要求是 PCM 16bit如果录音端输出的是 float 格式这里会报AudioFile读取错误所以录音参数里强制StereoAudioRecorder并设置 16kHz 采样率就是为了贴合这个库的预期。4.2 垃圾分类规则的设计与数据组织垃圾分类在这套项目里做的是“文本到类别”的映射不是图像分类。常见做法是用一个分类规则字典或者建一张数据库表。源码里classify.py用的是字典加关键词匹配# garbage/classify.py category_map { 可回收垃圾: [可乐瓶, 易拉罐, 废纸, 纸箱, 塑料瓶], 有害垃圾: [电池, 废灯管, 过期药品, 油漆桶], 厨余垃圾: [剩饭, 菜叶, 果皮, 茶叶渣], 其他垃圾: [陶瓷, 烟蒂, 卫生纸, 一次性餐具], } def classify_text(text): text text.strip() for category, words in category_map.items(): for word in words: if word in text: return category return 未识别请重新描述这里要注意匹配顺序先把高频易混淆的放前面。比如“塑料瓶”属于可回收但“塑料瓶盖”体积小有些城市归为其他垃圾这条规则在不同城市还不一样。所以做毕设时分类规则最好设计成可配置的要么放数据库表要么放配置文件别硬编码在代码里。我还见过有人直接用大语言模型接口去分类但那样演示时依赖网络和 API 费用反而不如规则可控。数据库表GarbageRecord一般至少记录这些字段用户、识别文本、分类结果、音频文件路径、创建时间。这样 Admin 后台能看到每次调用记录答辩时直接拉列表讲很有说服力。4.3 前后端联调Ajax 发送音频与 JSON 返回前端录音停止后通过 fetch 发送 FormData后端返回 JSON。源码里联调的重点在错误处理因为音频上传比普通表单更容易出问题。我拆的时候看到前端处理如下// static/js/recorder.js 中的上传部分 async function uploadAudio(blob) { const formData new FormData(); formData.append(audio, blob, record.wav); try { const response await fetch(/api/garbage/recognize/, { method: POST, body: formData, }); const data await response.json(); if (data.error) { alert(保存失败 data.error); return; } document.getElementById(result-text).innerText 识别结果 data.text; document.getElementById(result-category).innerText 垃圾类别 data.category; } catch (error) { console.error(请求异常, error); } }这里的fetch必须带method: POST和body: formData不能手动设置Content-Type因为 FormData 会自动带上multipart/form-data和随机 boundary。如果手动设置成application/json后端取不到文件会返回 400。JSON 返回里的text和category字段名要和后端视图保持一致前后端一旦改了字段这里也要同步。5. 实战避坑Django 语音识别系统最常见的 5 个翻车点5.1 录音文件识别结果为空现象上传后返回text是空字符串或者“未识别出有效语音”。原因绝大多数时候是录音编码问题。浏览器默认录出来可能是 webm 格式但 SpeechRecognition 的AudioFile只认 wav 或 AIFF还有一种情况是录音时没有做噪音校准麦克风音量太小识别引擎没听到有效语音。解决录音参数里强制设置mimeType: audio/wav采样率固定 16000声道设 1。如果依然为空把保存到 media 的音频下载下来用播放器听一下确认有没有声音再用 ffprobe 检查编码命令是ffprobe -show_streams file.wav看到codec_namepcm_s16le才有救。5.2 媒体文件路径配置混乱导致 404现象浏览器里输入http://127.0.0.1:8000/media/voice/xxx.wav返回 404或者页面图片、录音文件都无法访问。原因Django 开发环境默认不服务media/目录需要在settings.py里配置MEDIA_URL和MEDIA_ROOT并在项目的根urls.py里加static()路由。解决检查config/settings.py中是否设置MEDIA_ROOT BASE_DIR / media然后在config/urls.py末尾追加from django.conf import settings和from django.conf.urls.static import static最后urlpatterns static(settings.MEDIA_URL, document_rootsettings.MEDIA_ROOT)。这一条配置漏了文件存是存了但访问不到。5.3 语音识别库依赖版本冲突现象pip install -r requirements.txt后运行到import speech_recognition报ModuleNotFoundError或者运行时报ValueError: Audio file could not be read as PCM WAV/AIFF。原因SpeechRecognition 依赖pyaudio做录音但pyaudio在 Windows 上经常装不上导致整个导入失败还有pydub依赖 ffmpeg 路径环境变量没配也会触发读取错误。解决Windows 下不要直接pip install pyaudio优先装官方编译好的 wheel或者改用pip install pipwin pipwin install pyaudio。如果项目只需要读 wav 不录音可以注释掉录音相关依赖。装完跑一个最小测试随便拿一段 wav 文件用sr.AudioFile打开能打开说明环境基本正常。5.4 数据库迁移报错与并发锁现象执行python manage.py migrate时有时会卡住或者报database is locked。原因项目默认用的 SQLite。SQLite 对写并发有限制如果后台同时有多个请求写记录特别是演示时多人同时点录音上传就容易出现锁冲突。还有一个常见低级错误自己改了models.py后忘了makemigrations直接 migrate 导致找不到迁移文件。解决先执行python manage.py makemigrations再执行migrate。如果遇到database is locked先检查是不是有开发服务器没关占用着数据库然后把settings.py里CONN_MAX_AGE调小或者干脆换 PostgreSQL。毕设演示用 SQLite 没问题但提前把ENGINE换成 PostgreSQL 的配置写在说明里能显得更专业。5.5 部署到服务器后音频文件无法访问现象本地runserver一切正常部署到云服务器或局域网主机后录音功能可以上传但识别结果总是失败或者 media 文件访问 404。原因部署环境用的是 Nginx 或 Apache静态文件和媒体文件都交给 Web 服务器处理Django 不再直接提供文件服务。媒体文件路径没配好或者 Nginx 转发/media/时落到了错误目录。解决部署时不建议再用runserver改用 Gunicorn 或 uWSGI 跑 Django然后把/static/和/media/两个路径在 Nginx 里做别名映射。比如location /media/ { alias /var/www/django_garbage/media/; }此外要确认 Djangosettings.py里的DEBUG False时要显式配ALLOWED_HOSTS否则所有 POST 请求都会返回 400这种问题一度让我排查了两小时。6. 把项目改造成自己的毕设换引擎、扩类别、做验证6.1 替换语音识别引擎从离线识别到云端 API如果你不想依赖 Google 的在线接口可以换成 Vosk。它支持离线中文模型文件约 40MB放在项目根目录就能用。在recognition.py里替换核心调用import json from vosk import Model, KaldiRecognizer def recognize_audio(audio_path): model Model(vosk-model-small-cn-0.22) recognizer KaldiRecognizer(model, 16000) with open(audio_path, rb) as f: data f.read() if recognizer.AcceptWaveform(data): result json.loads(recognizer.Result()) return result.get(text, ) return 替换时要注意采样率必须和模型匹配这里固定 16000。云端 API 同理通常要求传 base64 编码的音频和对应的参数只要在recognition.py里做好格式转换前端和其他模块不需要动。6.2 扩展垃圾分类类别与识别规则源码自带的四类规则只覆盖了几十个关键词做毕设想加内容可以把classify.py里的字典改成数据库表用 Admin 后台直接增删词条。这样演示时可以现场往数据库里加一个“废旧衣物”然后再录一段语音效果非常直观。数据库表设计字段可以是keyword、category、is_active匹配时遍历表中启用的词条。6.3 系统效果验证的完整测试清单改造完别急着打包代码我一般会用这样一个自测清单先准备 5 段标准音频内容分别对应四类垃圾和一条无效语音依次调接口再测试空文件上传、非 wav 格式上传、超长音频上传最后跑一遍注册、登录、识别、查看历史记录的全流程。只有这五条都通过我才会认为系统可以交付。这套项目我前后拆过两遍第一次是直接在 Windows 上跑卡在 pyaudio 安装和媒体文件 404第二次按 README 的步骤走二十分钟就起来了。从那以后我每次拿到别人的 Django 资源都强制自己先跑一遍迁移和录音最小测试再开始改业务逻辑。希望这份拆解能让你避开我走过的弯路真正把一套语音识别垃圾分类系统跑起来然后改成你自己的作品。本文还有配套的精品资源点击获取