news 2026/10/8 10:44:13

Django语音识别垃圾分类系统:从录音上传到分类入库的完整实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Django语音识别垃圾分类系统:从录音上传到分类入库的完整实战

简介:一份基于语音识别的智能垃圾分类系统源码包,采用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 系统数据流与模块边界:从声音到分类结果

拆开源码后,我发现整个处理链是六个步骤,每一步的输入输出都很清楚:

  1. 浏览器录下用户语音,形成 wav 文件。
  2. 通过 Ajax 请求把音频 POST 到 Django 的识别接口。
  3. Django 视图收到文件,转给语音识别模块。
  4. 语音识别模块返回文本,比如“可乐瓶”。
  5. 分类模块根据文本匹配垃圾类别。
  6. Django 把分类结果和识别文本存入数据库,同时返回 JSON 给前端。

这套设计里最关键的是第 4、5 步之间的解耦。语音识别只负责“听”,垃圾分类只负责“想”,两个模块都不依赖具体实现。也就是说,你以后把 SpeechRecognition 换成讯飞或百度 API,分类模块一行都不用改。

3. 从压缩包到能跑:环境配置、源码结构与核心接口复现

3.1 环境准备:Python 版本、虚拟环境与依赖安装

拿到压缩包后,第一步不是急着看代码,而是先把环境搭好。这套项目基于 Django,我拆的时候用的 Python 3.9,Django 版本在 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:8000

requirements.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 请求'}, status=405) audio_file = request.FILES.get('audio') if not audio_file: return JsonResponse({'error': '缺少音频文件'}, status=400) # 保存音频到 media 目录,文件名加时间戳防止覆盖 from django.utils.timezone import now path = f'media/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, name='recognize'), ]

路由只留了一个入口,其他页面走 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, duration=0.5) audio_data = recognizer.record(source) try: # language 参数控制识别语言,zh-CN 表示简体中文 text = recognizer.recognize_google(audio_data, language='zh-CN') return text except sr.UnknownValueError: return '未识别出有效语音' except sr.RequestError as e: return f'语音服务请求失败: {e}'

adjust_for_ambient_noise这个参数很影响效果。duration=0.5表示取音频前 0.5 秒做环境噪音基线,如果演示现场很吵,建议把时长提到 1 秒,但别超过 1.5 秒,否则会吃掉真正的语音开头。language='zh-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_name=pcm_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_root=settings.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 资源,都强制自己先跑一遍迁移和录音最小测试,再开始改业务逻辑。希望这份拆解能让你避开我走过的弯路,真正把一套语音识别垃圾分类系统跑起来,然后改成你自己的作品。

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

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

轻型AI中台:让ERP/WMS/POS自动对话的实战方案

1. 为什么“轻型AI中台”不是又一个PPT概念,而是财务/运营人员每天都在等的解药“部署轻型AI中台,消除重复录入、消减对账困难”——这句话乍看像某次内部汇报里的一页幻灯片标题,但如果你在制造业做成本会计、在电商公司管订单履约、在连锁门…

作者头像 李华
网站建设 2026/10/8 10:42:40

从零搭建你的第一个Agent:大模型工具调用与Function Calling实战指南

过去这半年,AI圈子里最热的一个词大概就是Agent了。模型本身的能力越来越强,但大家慢慢发现,光有模型还不够——真正值钱的是让模型去调用工具、完成实际任务的能力。我一开始也以为Agent很玄乎,直到自己动手把一个带工具调用的Ag…

作者头像 李华
网站建设 2026/10/8 10:41:42

从鸿蒙人脸识别机到端侧推理:拆解全国产化人脸识别前端方案

1. 先拆解“鸿蒙人脸识别机”:你要找的到底是一台设备,还是一整套方案?最近总有朋友拿着“鸿蒙人脸识别机”这个关键词来问我,说实话第一反应我也愣了一下。人脸识别机做了这么多年,门禁机、考勤机、闸机伴侣都见过&am…

作者头像 李华
网站建设 2026/10/8 10:41:19

Win11+IIS10部署ASP同城门户实战指南

简介:这是一套基于ASP技术开发的同城生活信息门户系统源码,面向Web开发初学者与ASP技术实践者,解决城市生活服务类网站快速搭建需求,适用于本地生活服务平台、社区信息站等场景。资源包共2000个文件,涵盖343个核心ASP业…

作者头像 李华
网站建设 2026/10/8 10:40:59

基于MATLAB的Karma相场模型凝固枝晶生长模拟

最近终于把一个拖了小半年的代码调通了:用 MATLAB 从零手写凝固过程的相场模拟,核心模型用的是 Karma 相场框架,同时耦合了温度场、溶质场和相场三个场的演化。整个过程走完之后回头看,这个题目的价值不在于代码量有多少&#xff…

作者头像 李华
网站建设 2026/10/8 10:40:38

游戏引擎基础架构核心:帧循环、模块依赖与Job System实践解析

去年底,我带团队把自研引擎从 2D 原型引擎重构成能支撑 3D 场景的版本。重构结束后,我让一个刚入职的应届同学跟着模块图走读代码,一周后他的反馈让我印象很深:“模块图我看懂了,渲染是渲染,物理是物理&…

作者头像 李华