手机检测系统开发者手册:app.py核心逻辑、start.sh启动流程详解

手机检测系统开发者手册:app.py核心逻辑、start.sh启动流程详解 手机检测系统开发者手册app.py核心逻辑、start.sh启动流程详解1. 项目概述今天我们来深入解析一个基于DAMO-YOLO和TinyNAS技术的实时手机检测系统。这个系统的核心特点是小、快、省——模型体积小、推理速度快、资源消耗省特别适合手机端低算力、低功耗的应用场景。你可能会有疑问为什么要在手机上做目标检测其实这背后有很多实际需求。比如在考场监控中检测违规使用手机在驾驶场景中监测司机是否分心使用手机或者在会议场所确保参会者专注。传统方案往往需要将视频流发送到云端处理既延迟高又隐私风险大。而我们的方案直接在边缘设备上完成检测既保护隐私又实时响应。2. 系统架构设计2.1 整体架构让我们先来看看系统的整体架构设计手机检测系统架构 ├── 前端界面层 (Gradio WebUI) │ ├── 图片上传模块 │ ├── 实时显示模块 │ └── 结果展示模块 ├── 核心推理层 (DAMO-YOLO) │ ├── 图像预处理 │ ├── 模型推理 │ └── 后处理 ├── 服务管理层 (Supervisor) │ ├── 进程监控 │ ├── 自动重启 │ └── 日志管理 └── 资源调度层 (TinyNAS) ├── 模型优化 ├── 算力分配 └── 功耗控制这样的分层设计让系统既保持了高性能又具备了良好的可维护性和扩展性。2.2 技术选型考量选择DAMO-YOLO和TinyNAS组合不是偶然的。DAMO-YOLO是阿里巴巴达摩院推出的轻量级目标检测模型在保持高精度的同时大幅减少了计算量。而TinyNAS则通过神经架构搜索技术为特定硬件平台优化模型结构实现更好的性能功耗比。这种组合让我们的系统在手机芯片上也能流畅运行平均检测速度达到3.83毫秒每张图片准确率保持在88.8%的较高水平。3. app.py核心逻辑解析3.1 主程序结构app.py是整个系统的心脏我们来逐部分分析其核心逻辑# 导入必要的库 import gradio as gr import cv2 import torch import numpy as np from modelscope import snapshot_download, Model首先导入所需的库Gradio用于构建Web界面OpenCV处理图像PyTorch进行深度学习推理ModelScope提供模型管理。3.2 模型加载与初始化def load_model(): 加载DAMO-YOLO手机检测模型 try: # 下载或使用本地模型 model_dir snapshot_download(damo/yolov5s-phone-detection) # 初始化模型 model Model.from_pretrained(model_dir) print(模型加载成功) return model except Exception as e: print(f模型加载失败: {str(e)}) return None模型加载过程考虑了网络环境和本地缓存。snapshot_download会先检查本地是否有模型缓存避免重复下载。这种设计保证了系统在不同网络环境下都能正常启动。3.3 图像预处理逻辑def preprocess_image(image): 图像预处理函数 # 转换颜色空间 if len(image.shape) 3: image cv2.cvtColor(image, cv2.COLOR_RGB2BGR) # 保持原始图像用于显示 original_image image.copy() # 调整尺寸为模型输入要求 input_size (640, 640) resized_image cv2.resize(image, input_size) # 归一化处理 normalized_image resized_image.astype(np.float32) / 255.0 # 转换维度顺序为CHW input_tensor normalized_image.transpose(2, 0, 1) # 添加batch维度 input_tensor np.expand_dims(input_tensor, axis0) return original_image, torch.from_numpy(input_tensor)预处理过程充分考虑了模型要求和后续显示需求。保留原始图像用于结果展示同时生成符合模型输入的张量。3.4 核心检测函数def detect_phones(image, model): 执行手机检测的核心函数 if model is None: return image, 模型未加载成功请检查日志 try: # 预处理图像 original_image, input_tensor preprocess_image(image) # 模型推理 with torch.no_grad(): predictions model(input_tensor) # 后处理解析预测结果 processed_image, detection_info postprocess_predictions( original_image, predictions ) return processed_image, detection_info except Exception as e: print(f检测过程中出错: {str(e)}) return image, f检测失败: {str(e)}这个函数是整个推理流程的协调者处理了从输入到输出的完整流程并包含了完善的错误处理机制。3.5 后处理与结果可视化def postprocess_predictions(original_image, predictions): 后处理函数解析模型输出并绘制检测结果 # 解析预测框、置信度和类别 boxes predictions[0][boxes].cpu().numpy() scores predictions[0][scores].cpu().numpy() labels predictions[0][labels].cpu().numpy() # 复制原始图像用于绘制 output_image original_image.copy() detection_count 0 confidence_sum 0.0 # 绘制检测结果 for box, score, label in zip(boxes, scores, labels): if score 0.5: # 置信度阈值 # 转换坐标到原始图像尺寸 x1, y1, x2, y2 map(int, box) # 绘制边界框 cv2.rectangle(output_image, (x1, y1), (x2, y2), (0, 0, 255), 2) # 添加标签文本 label_text fphone: {score:.1%} cv2.putText(output_image, label_text, (x1, y1-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2) detection_count 1 confidence_sum score # 生成检测信息 if detection_count 0: avg_confidence confidence_sum / detection_count info f检测到 {detection_count} 个手机\n平均置信度: {avg_confidence:.1%} else: info 未检测到手机 return output_image, info后处理过程不仅解析模型输出还完成了结果可视化和信息统计为用户提供直观的检测结果。3.6 Gradio界面构建def create_interface(model): 创建Gradio Web界面 # 定义界面组件 with gr.Blocks(title手机检测系统) as demo: gr.Markdown(# 实时手机检测系统) gr.Markdown(基于DAMO-YOLO的高性能手机检测模型) with gr.Row(): with gr.Column(): # 输入组件 image_input gr.Image(label上传图片, typenumpy) upload_button gr.UploadButton(选择图片, file_types[image]) examples gr.Examples( examples[example1.jpg, example2.jpg, example3.jpg], inputsimage_input, label示例图片 ) detect_button gr.Button( 检测手机, variantprimary) with gr.Column(): # 输出组件 image_output gr.Image(label检测结果) info_output gr.Textbox(label检测信息, interactiveFalse) # 事件处理 upload_button.upload( fnlambda file: file, inputsupload_button, outputsimage_input ) detect_button.click( fnlambda img: detect_phones(img, model), inputsimage_input, outputs[image_output, info_output] ) # 自动检测 image_input.change( fnlambda img: detect_phones(img, model), inputsimage_input, outputs[image_output, info_output] ) return demoGradio界面的设计考虑了用户体验支持多种图片输入方式并提供实时自动检测功能。4. start.sh启动脚本详解4.1 启动脚本整体结构start.sh负责系统的启动和初始化让我们看看它的完整实现#!/bin/bash # 手机检测系统启动脚本 # 作者: 系统开发团队 # 版本: 1.0.0 set -e # 遇到错误立即退出 # 脚本配置 SCRIPT_DIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) PROJECT_ROOT$(dirname $SCRIPT_DIR) LOG_DIR$PROJECT_ROOT/logs PYTHON_PATH/usr/bin/python3 MAIN_SCRIPT$PROJECT_ROOT/app.py脚本开头设置了错误处理机制和基本路径配置确保脚本的健壮性和可移植性。4.2 环境检查与准备# 检查并创建日志目录 create_log_directory() { echo 检查日志目录... if [ ! -d $LOG_DIR ]; then echo 创建日志目录: $LOG_DIR mkdir -p $LOG_DIR chmod 755 $LOG_DIR else echo 日志目录已存在: $LOG_DIR fi } # 检查Python环境 check_python() { echo 检查Python环境... if [ ! -f $PYTHON_PATH ]; then echo 错误: Python未安装在 $PYTHON_PATH echo 请安装Python 3.8或更高版本 exit 1 fi # 检查Python版本 PYTHON_VERSION$($PYTHON_PATH -c import sys; print(f{sys.version_info.major}.{sys.version_info.minor})) echo Python版本: $PYTHON_VERSION # 验证版本要求 if [ $(echo $PYTHON_VERSION 3.8 | bc -l) -eq 1 ]; then echo 错误: 需要Python 3.8或更高版本当前版本: $PYTHON_VERSION exit 1 fi }环境检查确保了系统依赖的完整性避免了运行时出现环境问题。4.3 依赖安装与验证# 安装Python依赖 install_dependencies() { echo 安装Python依赖... REQUIREMENTS_FILE$PROJECT_ROOT/requirements.txt if [ ! -f $REQUIREMENTS_FILE ]; then echo 错误: 未找到requirements.txt文件 exit 1 fi # 检查pip是否可用 if ! command -v pip3 /dev/null; then echo 错误: pip3未安装 exit 1 fi # 安装依赖 echo 正在安装依赖包... pip3 install -r $REQUIREMENTS_FILE if [ $? -eq 0 ]; then echo 依赖安装成功 else echo 错误: 依赖安装失败 exit 1 fi }依赖管理是系统稳定运行的基础这个函数确保了所有必要的Python包都被正确安装。4.4 端口检查与处理# 检查端口占用 check_port() { local PORT7860 echo 检查端口 $PORT 占用情况... if command -v netstat /dev/null; then if netstat -tuln | grep :$PORT /dev/null; then echo 警告: 端口 $PORT 已被占用 echo 正在尝试终止占用进程... pkill -f gradio || true sleep 2 fi elif command -v lsof /dev/null; then if lsof -i :$PORT /dev/null; then echo 警告: 端口 $PORT 已被占用 pkill -f gradio || true sleep 2 fi fi }端口冲突是Web服务常见的问题这个函数智能地处理了端口占用情况。4.5 主启动流程# 主启动函数 start_application() { echo 启动手机检测系统... echo 项目根目录: $PROJECT_ROOT echo 日志目录: $LOG_DIR # 进入项目目录 cd $PROJECT_ROOT # 设置环境变量 export PYTHONPATH$PROJECT_ROOT:$PYTHONPATH export GRADIO_SERVER_NAME0.0.0.0 export GRADIO_SERVER_PORT7860 # 获取当前时间 START_TIME$(date %Y-%m-%d %H:%M:%S) echo 启动时间: $START_TIME # 启动应用 echo 正在启动Gradio服务... nohup $PYTHON_PATH $MAIN_SCRIPT $LOG_DIR/access.log 2 $LOG_DIR/error.log # 记录PID APP_PID$! echo $APP_PID $PROJECT_ROOT/app.pid echo 应用启动成功PID: $APP_PID # 等待服务启动 echo 等待服务启动... sleep 5 # 检查服务状态 if curl -f http://localhost:7860 /dev/null 21; then echo 服务启动成功! echo 访问地址: http://localhost:7860 echo 或者: http://$(hostname -I | awk {print $1}):7860 else echo 警告: 服务启动但无法访问请检查日志 echo 错误日志: $LOG_DIR/error.log fi }主启动流程包含了完整的服务启动、状态检查和访问信息输出为用户提供清晰的启动反馈。4.6 完整启动脚本#!/bin/bash # 手机检测系统启动脚本 set -e SCRIPT_DIR$(cd $(dirname ${BASH_SOURCE[0]}) pwd) PROJECT_ROOT$(dirname $SCRIPT_DIR) LOG_DIR$PROJECT_ROOT/logs PYTHON_PATH/usr/bin/python3 MAIN_SCRIPT$PROJECT_ROOT/app.py # 颜色定义 RED\033[0;31m GREEN\033[0;32m YELLOW\033[1;33m NC\033[0m # No Color log() { echo -e ${GREEN}[INFO]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 } warn() { echo -e ${YELLOW}[WARN]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 } error() { echo -e ${RED}[ERROR]${NC} $(date %Y-%m-%d %H:%M:%S) - $1 } # 检查并创建日志目录 create_log_directory() { log 检查日志目录... if [ ! -d $LOG_DIR ]; then log 创建日志目录: $LOG_DIR mkdir -p $LOG_DIR chmod 755 $LOG_DIR else log 日志目录已存在: $LOG_DIR fi } # 检查Python环境 check_python() { log 检查Python环境... if [ ! -f $PYTHON_PATH ]; then error Python未安装在 $PYTHON_PATH exit 1 fi PYTHON_VERSION$($PYTHON_PATH -c import sys; print(f{sys.version_info.major}.{sys.version_info.minor})) log Python版本: $PYTHON_VERSION if [ $(echo $PYTHON_VERSION 3.8 | bc -l) -eq 1 ]; then error 需要Python 3.8或更高版本 exit 1 fi } # 安装依赖 install_dependencies() { log 安装Python依赖... REQUIREMENTS_FILE$PROJECT_ROOT/requirements.txt if [ ! -f $REQUIREMENTS_FILE ]; then error 未找到requirements.txt exit 1 fi if ! command -v pip3 /dev/null; then error pip3未安装 exit 1 fi log 正在安装依赖包... pip3 install -r $REQUIREMENTS_FILE if [ $? -eq 0 ]; then log 依赖安装成功 else error 依赖安装失败 exit 1 fi } # 检查端口占用 check_port() { local PORT7860 log 检查端口 $PORT 占用情况... if command -v lsof /dev/null; then if lsof -i :$PORT /dev/null; then warn 端口 $PORT 已被占用 log 正在尝试释放端口... pkill -f gradio || true sleep 2 fi fi } # 主启动函数 start_application() { log 启动手机检测系统... cd $PROJECT_ROOT export PYTHONPATH$PROJECT_ROOT:$PYTHONPATH export GRADIO_SERVER_NAME0.0.0.0 export GRADIO_SERVER_PORT7860 # 启动应用 log 正在启动Gradio服务... nohup $PYTHON_PATH $MAIN_SCRIPT $LOG_DIR/access.log 2 $LOG_DIR/error.log APP_PID$! echo $APP_PID $PROJECT_ROOT/app.pid log 应用启动成功PID: $APP_PID # 等待并检查服务 sleep 5 if curl -f http://localhost:7860 /dev/null 21; then log 服务启动成功! log 访问地址: http://localhost:7860 else warn 服务启动但无法访问请检查日志 fi } # 主执行流程 main() { echo echo 手机检测系统启动脚本 v1.0.0 echo create_log_directory check_python install_dependencies check_port start_application echo log 启动流程完成 echo } # 执行主函数 main $这个完整的启动脚本提供了颜色化的日志输出、完善的错误处理和状态检查确保系统能够可靠地启动和运行。5. 系统部署与监控5.1 Supervisor配置为了确保系统长期稳定运行我们使用Supervisor进行进程管理; /etc/supervisor/conf.d/phone-detection.conf [program:phone-detection] command/root/phone-detection/start.sh directory/root/phone-detection autostarttrue autorestarttrue startretries3 stopwaitsecs30 userroot stdout_logfile/root/phone-detection/logs/supervisor.out.log stderr_logfile/root/phone-detection/logs/supervisor.err.log environmentPYTHONPATH/root/phone-detectionSupervisor配置确保了系统在异常退出时能够自动重启并提供了完整的日志记录。5.2 系统监控脚本我们还提供了一个监控脚本用于检查系统状态#!/bin/bash # monitor.sh - 系统监控脚本 check_status() { # 检查进程是否运行 if pgrep -f app.py /dev/null; then echo ✅ 应用进程运行正常 else echo ❌ 应用进程未运行 fi # 检查端口监听 if netstat -tln | grep :7860 /dev/null; then echo ✅ 端口7860监听正常 else echo ❌ 端口7860未监听 fi # 检查最近错误 ERROR_COUNT$(tail -100 /root/phone-detection/logs/error.log | grep -i error | wc -l) echo 最近错误数: $ERROR_COUNT }6. 性能优化技巧6.1 模型推理优化def optimize_model_performance(model): 模型性能优化函数 # 启用GPU加速如果可用 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) # 设置为评估模式 model.eval() # 启用半精度推理 if device.type cuda: model.half() # 转换为半精度 # 启用TensorRT加速可选 if device.type cuda: try: from torch2trt import torch2trt # 创建示例输入 example_input torch.randn(1, 3, 640, 640).to(device) # 转换模型 model torch2trt(model, [example_input]) except ImportError: print(TensorRT未安装使用标准推理) return model, device这些优化措施可以显著提升模型推理速度特别是在支持GPU的环境中。6.2 内存管理优化def manage_memory_usage(): 内存使用优化 # 清理GPU缓存 if torch.cuda.is_available(): torch.cuda.empty_cache() torch.cuda.reset_peak_memory_stats() # 设置合理的批处理大小 # 根据可用内存动态调整 import psutil memory_info psutil.virtual_memory() available_memory memory_info.available / (1024 ** 3) # GB if available_memory 8: batch_size 8 elif available_memory 4: batch_size 4 else: batch_size 2 return batch_size7. 总结通过本文的详细解析你应该对手机检测系统的核心逻辑有了深入的理解。我们从app.py的模型加载、图像处理、推理流程到start.sh的环境检查、依赖管理、服务启动全面剖析了系统的各个组件。这个系统的设计体现了几个重要原则模块化设计各功能模块职责清晰便于维护和扩展错误处理完善的异常处理机制保证系统稳定性性能优化针对移动端场景的深度优化用户体验简洁的Web界面和自动化部署脚本实际部署时记得根据你的硬件环境调整相关参数特别是内存管理和模型优化相关的设置。如果遇到问题首先检查日志文件大多数问题都能在日志中找到答案。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。