从零构建水果品质检测Web应用:YOLOv8与Streamlit实战指南

1. 环境准备与工具链搭建

在开始构建水果品质检测Web应用之前,我们需要准备开发环境和必要的工具链。这个环节看似基础,却直接影响后续开发的效率和项目的可维护性。

1.1 Python环境配置

推荐使用conda创建独立的Python环境,避免依赖冲突:

conda create -n fruit_detection python=3.8
conda activate fruit_detection

安装核心依赖库:

pip install torch torchvision ultralytics streamlit opencv-python

提示:如果使用GPU加速,建议安装对应CUDA版本的PyTorch,可显著提升模型推理速度

1.2 开发工具选择

对于这个项目,我们推荐以下工具组合:

  • PyCharm Professional:提供完善的Python开发支持
  • VS Code:轻量级但功能强大,适合前端调试
  • Jupyter Notebook:用于快速原型验证
工具用途优势
PyCharm主开发环境深度Python支持,强大调试功能
VS Code前端调试轻量快速,丰富插件生态
Jupyter算法验证交互式开发,即时可视化

2. YOLOv8模型实战

2.1 模型选择与加载

YOLOv8提供了多种预训练模型,根据硬件条件选择合适的版本:

from ultralytics import YOLO

# 根据设备性能选择模型大小
model = YOLO('yolov8n.pt')  # 超轻量版
# model = YOLO('yolov8s.pt')  # 小模型
# model = YOLO('yolov8m.pt')  # 中模型
# model = YOLO('yolov8l.pt')  # 大模型
# model = YOLO('yolov8x.pt')  # 超大模型

2.2 自定义数据集训练

准备水果品质检测数据集需要以下步骤:

  1. 收集包含各种水果(苹果、香蕉、橙子等)好坏样本的图像
  2. 使用LabelImg等工具标注图像,生成YOLO格式的标注文件
  3. 按照以下结构组织数据集:
datasets/
└── fruits/
    ├── train/
    │   ├── images/
    │   └── labels/
    ├── val/
    │   ├── images/
    │   └── labels/
    └── data.yaml  # 数据集配置文件

data.yaml示例内容:

path: ../datasets/fruits
train: train/images
val: val/images

names:
  0: apple_good
  1: apple_bad
  2: banana_good
  3: banana_bad

训练命令:

results = model.train(
    data='datasets/fruits/data.yaml',
    epochs=100,
    imgsz=640,
    batch=16,
    name='fruit_quality_v8'
)

3. Streamlit界面开发

3.1 基础界面搭建

创建一个基本的Streamlit应用框架:

import streamlit as st
import cv2
from PIL import Image
import numpy as np

st.set_page_config(page_title="水果品质检测", layout="wide")

def main():
    st.title("🍎 水果品质检测系统")
    st.sidebar.title("设置")
    
    # 模型选择
    model_type = st.sidebar.selectbox(
        "选择模型",
        ["YOLOv8n", "YOLOv8s", "YOLOv8m"]
    )
    
    # 置信度阈值
    conf_threshold = st.sidebar.slider(
        "置信度阈值", 0.0, 1.0, 0.25, 0.01
    )
    
    # 输入源选择
    input_source = st.sidebar.radio(
        "选择输入源",
        ["上传图片", "摄像头"]
    )
    
    # 根据选择显示不同输入界面
    if input_source == "上传图片":
        uploaded_file = st.file_uploader(
            "上传水果图片", 
            type=["jpg", "jpeg", "png"]
        )
        if uploaded_file is not None:
            image = Image.open(uploaded_file)
            st.image(image, caption="上传的图片", use_column_width=True)
    else:
        st.warning("摄像头功能需要浏览器权限")

if __name__ == "__main__":
    main()

3.2 集成YOLOv8模型

将训练好的YOLOv8模型集成到Streamlit应用中:

def detect_objects(image, model_path="best.pt"):
    # 加载模型
    model = YOLO(model_path)
    
    # 执行检测
    results = model(image)
    
    # 绘制检测结果
    for result in results:
        boxes = result.boxes
        for box in boxes:
            x1, y1, x2, y2 = box.xyxy[0]
            conf = box.conf[0]
            cls = box.cls[0]
            
            # 在图像上绘制边界框和标签
            cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
            label = f"{model.names[int(cls)]} {conf:.2f}"
            cv2.putText(image, label, (int(x1), int(y1)-10), 
                       cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
    
    return image

4. 高级功能实现

4.1 实时摄像头检测

实现摄像头实时检测功能:

def camera_detection():
    stframe = st.empty()
    cap = cv2.VideoCapture(0)
    
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            st.error("无法获取摄像头画面")
            break
        
        # 转换颜色空间
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        
        # 执行检测
        detected_frame = detect_objects(frame)
        
        # 显示结果
        stframe.image(detected_frame, channels="RGB")
        
        # 添加停止按钮
        if st.button("停止检测"):
            break
    
    cap.release()

4.2 结果导出功能

添加检测结果导出功能:

def save_results(image, results):
    # 创建结果目录
    os.makedirs("results", exist_ok=True)
    
    # 保存图像
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    image_path = f"results/detection_{timestamp}.jpg"
    cv2.imwrite(image_path, cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
    
    # 保存检测数据
    data = []
    for result in results:
        boxes = result.boxes.cpu().numpy()
        for box in boxes:
            data.append({
                "class": model.names[int(box.cls[0])],
                "confidence": float(box.conf[0]),
                "x1": float(box.xyxy[0][0]),
                "y1": float(box.xyxy[0][1]),
                "x2": float(box.xyxy[0][2]),
                "y2": float(box.xyxy[0][3])
            })
    
    df = pd.DataFrame(data)
    csv_path = f"results/detection_{timestamp}.csv"
    df.to_csv(csv_path, index=False)
    
    return image_path, csv_path

5. 性能优化与部署

5.1 模型量化加速

使用PyTorch的量化功能减小模型大小并提升推理速度:

def quantize_model(model_path):
    # 加载原始模型
    model = YOLO(model_path)
    
    # 转换为量化模型
    quantized_model = torch.quantization.quantize_dynamic(
        model.model,
        {torch.nn.Linear},
        dtype=torch.qint8
    )
    
    # 保存量化模型
    quantized_path = model_path.replace(".pt", "_quantized.pt")
    torch.save(quantized_model.state_dict(), quantized_path)
    
    return quantized_path

5.2 使用ONNX Runtime加速

将模型转换为ONNX格式并使用ONNX Runtime加速:

def export_to_onnx(model_path):
    model = YOLO(model_path)
    model.export(format="onnx")
    return model_path.replace(".pt", ".onnx")

def create_onnx_session(onnx_path):
    import onnxruntime as ort
    providers = ['CUDAExecutionProvider', 'CPUExecutionProvider']
    session = ort.InferenceSession(onnx_path, providers=providers)
    return session

5.3 部署选项

根据需求选择合适的部署方式:

  1. 本地运行:直接运行Streamlit应用

    streamlit run app.py
    
  2. Docker容器化:

    FROM python:3.8-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    CMD ["streamlit", "run", "app.py"]
    
  3. 云服务部署:

    • AWS EC2
    • Google Cloud Run
    • Azure App Service

6. 实际应用案例

6.1 超市水果质检

在超市后端系统中集成该应用,可以:

  • 自动检测进货水果品质
  • 实时监控货架水果新鲜度
  • 生成每日品质报告

6.2 水果分拣流水线

结合工业相机和机械臂:

  1. 传送带运送水果通过检测区域
  2. 系统实时识别并分类
  3. 机械臂根据分类结果分拣

6.3 家庭使用场景

开发移动端应用,消费者可以:

  • 扫描水果获取新鲜度评估
  • 记录购买水果的品质变化
  • 获取最佳食用时间建议

7. 常见问题解决

在开发过程中可能会遇到以下问题:

问题1:模型检测精度不足
解决方案:

  • 增加训练数据量,特别是困难样本
  • 调整数据增强策略
  • 尝试更大的模型版本

问题2:Streamlit界面响应慢
解决方案:

  • 使用缓存装饰器@st.cache
  • 优化图像处理流程
  • 考虑使用异步更新

问题3:跨平台兼容性问题
解决方案:

  • 统一使用相对路径
  • 明确指定编码格式
  • 在Docker中测试各平台兼容性

问题4:移动端适配不佳
解决方案:

  • 使用响应式布局
  • 调整UI元素大小
  • 考虑开发专用移动应用

8. 进阶开发方向

对于希望进一步扩展功能的开发者,可以考虑:

  1. 多模型集成:结合YOLOv8与其他视觉模型(如分类、分割)
  2. 云端训练平台:构建自动化模型训练流水线
  3. 边缘设备部署:优化模型在树莓派等边缘设备上的性能
  4. 用户反馈系统:收集用户标注改进模型
  5. 多语言支持:增加国际化界面
# 示例:多模型集成
class MultiModelDetector:
    def __init__(self):
        self.detector = YOLO('yolov8n.pt')
        self.classifier = load_classifier()
        
    def detect(self, image):
        # 目标检测
        det_results = self.detector(image)
        
        # 精细分类
        for obj in det_results:
            crop = image[obj.y1:obj.y2, obj.x1:obj.x2]
            cls_result = self.classifier(crop)
            obj.class_name = cls_result['class']
        
        return det_results

构建完整的水果品质检测系统需要综合考虑算法精度、系统性能和用户体验。通过YOLOv8提供的强大检测能力和Streamlit的简洁界面开发方式,即使是个人开发者也能快速构建出实用的应用原型。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐