保姆级教程:用Flask+SocketIO从零搭建一个YOLO番茄检测Web应用(附完整源码)

张开发
2026/4/8 11:48:54 15 分钟阅读

分享文章

保姆级教程:用Flask+SocketIO从零搭建一个YOLO番茄检测Web应用(附完整源码)
从零构建YOLO番茄检测Web应用FlaskSocketIO全栈实战在智能农业和食品加工领域番茄成熟度检测是一个具有重要商业价值的技术应用。传统的人工检测方法效率低下且容易出错而基于深度学习的解决方案能够实现快速、准确的自动化检测。本文将带你从零开始使用Flask和SocketIO构建一个完整的YOLO番茄检测Web应用涵盖从模型加载到前后端交互的全流程实现。1. 环境准备与项目初始化1.1 创建Python虚拟环境首先我们需要建立一个隔离的Python开发环境。使用conda或venv创建并激活虚拟环境conda create -n tomato-detection python3.8 conda activate tomato-detection1.2 安装核心依赖项目需要的主要Python包包括pip install flask flask-socketio opencv-python numpy torch torchvision对于YOLO模型支持我们推荐使用Ultralytics官方库pip install ultralytics1.3 项目目录结构合理的项目结构对后续开发至关重要tomato-detection/ ├── app.py # Flask主应用 ├── static/ │ ├── js/ # 前端JavaScript │ ├── css/ # 样式表 │ └── models/ # 预训练模型权重 ├── templates/ # HTML模板 ├── uploads/ # 用户上传文件 └── requirements.txt # 依赖清单2. YOLO模型集成与推理优化2.1 模型选择与加载YOLO系列模型有多种变体针对番茄检测任务我们选择YOLOv8作为基础模型from ultralytics import YOLO def load_model(model_pathyolov8n.pt): model YOLO(model_path) model.fuse() # 优化推理速度 return model2.2 推理流程封装创建一个统一的推理函数处理不同输入类型def predict(image, model, conf_threshold0.25, iou_threshold0.45): results model.predict( sourceimage, confconf_threshold, iouiou_threshold, devicecpu # 可根据实际情况使用GPU ) return results[0].plot() # 返回带标注框的图像2.3 性能优化技巧为提高实时性可以采用以下优化策略使用半精度推理FP16实现批处理预测启用TensorRT加速调整输入图像分辨率3. Flask后端开发3.1 基础应用搭建创建一个基本的Flask应用结构from flask import Flask, render_template, request from flask_socketio import SocketIO app Flask(__name__) app.config[SECRET_KEY] your-secret-key socketio SocketIO(app, async_modeeventlet) app.route(/) def index(): return render_template(index.html)3.2 文件上传处理实现图片上传和检测的API端点from werkzeug.utils import secure_filename import os app.route(/upload, methods[POST]) def upload_file(): if file not in request.files: return {error: No file uploaded}, 400 file request.files[file] if file.filename : return {error: No selected file}, 400 filename secure_filename(file.filename) save_path os.path.join(uploads, filename) file.save(save_path) # 执行检测 result_image predict(save_path, model) result_path os.path.join(static, results, filename) cv2.imwrite(result_path, result_image) return {result_url: f/static/results/{filename}}3.3 实时视频流处理对于摄像头实时检测我们需要建立SocketIO连接socketio.on(connect) def handle_connect(): print(Client connected) socketio.on(disconnect) def handle_disconnect(): print(Client disconnected) socketio.on(video_feed) def handle_video_feed(data): # 处理视频帧数据 frame process_frame(data[frame]) socketio.emit(detection_result, {frame: frame})4. 前端交互界面开发4.1 基础HTML结构创建一个响应式布局的检测页面!DOCTYPE html html head title番茄成熟度检测系统/title link relstylesheet href/static/css/style.css /head body div classcontainer h1番茄检测系统/h1 div classdetection-area div classoriginal-view h3原始图像/h3 img idoriginal-img src /div div classresult-view h3检测结果/h3 img idresult-img src /div /div div classcontrols input typefile idfile-input acceptimage/* button idstart-camera开启摄像头/button /div /div script src/static/js/app.js/script /body /html4.2 实时视频处理JavaScript实现摄像头访问和帧处理逻辑document.getElementById(start-camera).addEventListener(click, async () { const stream await navigator.mediaDevices.getUserMedia({ video: true }); const video document.createElement(video); video.srcObject stream; video.play(); const canvas document.createElement(canvas); const ctx canvas.getContext(2d); function processFrame() { canvas.width video.videoWidth; canvas.height video.videoHeight; ctx.drawImage(video, 0, 0); const imageData canvas.toDataURL(image/jpeg); socket.emit(video_feed, { frame: imageData }); requestAnimationFrame(processFrame); } processFrame(); });4.3 SocketIO事件处理建立前后端实时通信const socket io(); socket.on(detection_result, (data) { document.getElementById(result-img).src data.frame; }); socket.on(connect, () { console.log(Connected to server); });5. 系统部署与优化5.1 生产环境部署使用Gunicorn或uWSGI部署Flask应用gunicorn -k eventlet -w 4 app:app对于更高性能需求可以考虑使用Nginx作为反向代理启用Gzip压缩配置静态文件缓存5.2 性能监控实现简单的系统健康监控端点app.route(/status) def status(): return { status: healthy, model: model.model_name, memory_usage: psutil.Process().memory_info().rss / 1024 / 1024 }5.3 安全加固生产环境需要考虑的安全措施实现请求速率限制添加CSRF保护文件上传验证敏感配置管理6. 功能扩展思路6.1 多模型支持扩展系统以支持不同YOLO版本models { yolov8n: YOLO(yolov8n.pt), yolov8s: YOLO(yolov8s.pt), custom: YOLO(custom.pt) } app.route(/set_model, methods[POST]) def set_model(): model_name request.json.get(model) if model_name in models: current_model models[model_name] return {status: success} return {error: Invalid model}, 4006.2 批处理与历史记录添加批处理和历史记录功能from datetime import datetime app.route(/batch, methods[POST]) def batch_process(): files request.files.getlist(files) results [] for file in files: filename secure_filename(file.filename) save_path os.path.join(uploads, filename) file.save(save_path) result_image predict(save_path, model) result_path fstatic/results/{datetime.now().timestamp()}_{filename} cv2.imwrite(result_path, result_image) results.append(result_path) return {results: results}6.3 移动端适配通过响应式设计和PWA技术优化移动体验media (max-width: 768px) { .detection-area { flex-direction: column; } .original-view, .result-view { width: 100%; } }7. 常见问题解决7.1 模型加载失败可能原因及解决方案模型文件损坏重新下载模型权重CUDA版本不匹配检查PyTorch与CUDA版本兼容性内存不足尝试使用更小的模型变体7.2 实时视频延迟高优化策略降低视频流分辨率增加帧跳过间隔客户端进行简单预处理使用WebWorker处理帧数据7.3 检测精度不足提升方法使用更大模型变体如YOLOv8x在特定数据集上微调模型调整置信度和IoU阈值添加后处理逻辑如NMS8. 完整项目结构示例以下是项目完整代码结构的参考实现# app.py from flask import Flask, render_template, request, jsonify from flask_socketio import SocketIO from ultralytics import YOLO import cv2 import os from datetime import datetime app Flask(__name__) app.config[SECRET_KEY] your-secret-key app.config[UPLOAD_FOLDER] uploads app.config[RESULT_FOLDER] static/results socketio SocketIO(app, async_modeeventlet) # 确保目录存在 os.makedirs(app.config[UPLOAD_FOLDER], exist_okTrue) os.makedirs(app.config[RESULT_FOLDER], exist_okTrue) # 加载模型 model YOLO(yolov8n.pt) app.route(/) def index(): return render_template(index.html) app.route(/upload, methods[POST]) def upload_file(): if file not in request.files: return jsonify({error: No file uploaded}), 400 file request.files[file] if file.filename : return jsonify({error: No selected file}), 400 filename secure_filename(file.filename) save_path os.path.join(app.config[UPLOAD_FOLDER], filename) file.save(save_path) # 执行检测 results model.predict(save_path) result_image results[0].plot() result_filename f{datetime.now().timestamp()}_{filename} result_path os.path.join(app.config[RESULT_FOLDER], result_filename) cv2.imwrite(result_path, result_image) return jsonify({ original: f/uploads/{filename}, result: f/static/results/{result_filename} }) if __name__ __main__: socketio.run(app, debugTrue)!-- templates/index.html -- !DOCTYPE html html head title番茄检测系统/title style body { font-family: Arial, sans-serif; max-width: 1200px; margin: 0 auto; padding: 20px; } .detection-area { display: flex; gap: 20px; margin: 20px 0; } .original-view, .result-view { flex: 1; border: 1px solid #ddd; padding: 10px; } img { max-width: 100%; height: auto; } .controls { margin: 20px 0; } /style /head body h1番茄成熟度检测系统/h1 div classdetection-area div classoriginal-view h3原始图像/h3 img idoriginal-img src /div div classresult-view h3检测结果/h3 img idresult-img src /div /div div classcontrols input typefile idfile-input acceptimage/* button idstart-camera开启摄像头/button /div script srchttps://cdn.socket.io/4.5.4/socket.io.min.js/script script const socket io(); const fileInput document.getElementById(file-input); const originalImg document.getElementById(original-img); const resultImg document.getElementById(result-img); fileInput.addEventListener(change, (e) { const file e.target.files[0]; if (!file) return; const formData new FormData(); formData.append(file, file); fetch(/upload, { method: POST, body: formData }) .then(response response.json()) .then(data { if (data.error) { alert(data.error); return; } originalImg.src data.original; resultImg.src data.result; }); }); /script /body /html这个完整的番茄检测Web应用实现涵盖了从模型加载到前后端交互的全流程开发者可以根据实际需求进一步扩展功能或优化性能。项目采用模块化设计便于维护和功能添加为农业智能化应用开发提供了可靠的技术参考。

更多文章