跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

基于改进 YOLOv8 的美食图像分割系统实战与源码解析

美食图像分割作为计算机视觉的重要方向,结合改进 YOLOv8 模型可实现高精度识别。本项目构建了包含 136 类美食的数据集,涵盖主菜、配菜及调料等。通过 Streamlit 搭建 Web 界面,配合 OpenCV 实现实时摄像头检测,支持中文标注与颜色生成。代码涵盖模型训练、推理、轨迹跟踪及可视化模块,提供从数据预处理到部署的完整流程,适用于餐饮分析、营养监测等场景。

热情发布于 2026/4/11更新于 2026/10/2597 浏览
基于改进 YOLOv8 的美食图像分割系统实战与源码解析

项目背景

随着计算机视觉技术的成熟,美食图像分割在餐饮行业、食品安全监测及营养分析中的应用价值日益凸显。YOLO(You Only Look Once)系列模型凭借高效的实时检测能力成为首选,尤其是 YOLOv8,其在复杂场景下的表现更为优异。

本项目构建了一个基于改进 YOLOv8 的美食图像分割系统。数据集包含 3800 张图像,涵盖 136 种不同类别的美食,包括主菜、配菜、调料等。丰富的类别设置不仅提升了模型的识别能力,也为后续的营养分析、热量计算和个性化推荐提供了数据支持。通过精确分割,系统能帮助用户了解食物成分,辅助科学饮食选择,同时提升美食分享内容的可读性。

效果展示

美食分割效果示例

美食分割效果示例

美食分割效果示例

数据集信息

数据集名为'food',包含 136 个类别,从新鲜水果到精致主菜,覆盖了广泛的美食类型。例如青柠、加拿大龙虾、各类披萨、美式早餐、意式火腿奶酪以及多种沙拉等。此外,烤鸡、煎三文鱼、法式薯条等常见菜品,以及鳄梨、奶酪、橄榄油等配料也包含在内。

为了确保模型的泛化能力,图像来源涵盖了不同的烹饪风格和文化背景,无论是西式汉堡还是东南亚风味均有体现。所有图像均经过精心挑选和标注,保证了训练数据的高质量,为模型在不同光照、角度和背景下的准确识别奠定了基础。

数据集分布示例

核心代码实现

应用启动脚本

这个 Python 脚本主要用于运行 Streamlit Web 应用。它获取当前 Python 解释器路径,构建命令并执行 web.py。这样做的目的是确保无论在哪里运行,都能调用正确的环境。

import sys
import subprocess
from QtFusion.path import abs_path

def run_script(script_path):
    """使用当前 Python 环境运行指定的脚本"""
    python_path = sys.executable
    command = f'"{python_path}" -m streamlit run ""'
    result = subprocess.run(command, shell=)
     result.returncode != :
        ()

 __name__ == :
    script_path = abs_path()
    run_script(script_path)
{script_path}
True
if
0
print
"脚本运行出错。"
if
"__main__"
"web.py"

实时检测与可视化

这是核心的推理逻辑部分。我们使用了 OpenCV 读取摄像头流,结合深度学习模型进行预测。为了让结果更直观,代码中实现了中文文本绘制和动态颜色生成。注意 generate_color_based_on_name 函数利用 MD5 哈希确保同一类别始终显示相同颜色,方便追踪。

import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
from hashlib import md5
from model import Web_Detector
from chinese_name_list import Label_list

def generate_color_based_on_name(name):
    hash_object = md5(name.encode())
    hex_color = hash_object.hexdigest()[:6]
    r, g, b = int(hex_color[0:2], 16), int(hex_color[2:4], 16), int(hex_color[4:6], 16)
    return (b, g, r)  # OpenCV 使用 BGR 格式

def draw_with_chinese(image, text, position, font_size=20, color=(255, 0, 0)):
    image_pil = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
    draw = ImageDraw.Draw(image_pil)
    font = ImageFont.truetype("simsun.ttc", font_size, encoding="unic")
    draw.text(position, text, font=font, fill=color)
    return cv2.cvtColor(np.array(image_pil), cv2.COLOR_RGB2BGR)

def draw_detections(image, info):
    name, bbox = info['class_name'], info['bbox']
    x1, y1, x2, y2 = bbox
    cv2.rectangle(image, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=3)
    image = draw_with_chinese(image, name, (x1, y1 - 10), font_size=20)
    return image

def process_frame(model, image):
    pre_img = model.preprocess(image)
    pred = model.predict(pre_img)
    det = pred[0]
    if det is not None and len(det):
        det_info = model.postprocess(pred)
        for info in det_info:
            image = draw_detections(image, info)
    return image

if __name__ == "__main__":
    model = Web_Detector()
    model.load_model("./weights/yolov8s-seg.pt")
    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret: break
        processed_frame = process_frame(model, frame)
        cv2.imshow('Camera Feed', processed_frame)
        if cv2.waitKey(1) & 0xFF == ord('q'): break
    cap.release()
    cv2.destroyAllWindows()

模型接口定义

这里展示了 FastSAM 的类定义,它是 Ultralytics YOLO 框架中的一个模型接口,用于图像分割任务。初始化时会自动检查模型后缀,确保加载的是预训练权重而非配置文件。

from pathlib import Path
from ultralytics.engine.model import Model
from .predict import FastSAMPredictor
from .val import FastSAMValidator

class FastSAM(Model):
    """FastSAM 模型接口"""
    def __init__(self, model='FastSAM-x.pt'):
        if str(model) == 'FastSAM.pt':
            model = 'FastSAM-x.pt'
        assert Path(model).suffix not in ('.yaml', '.yml'), 'FastSAM models only support pre-trained models.'
        super().__init__(model=model, task='segment')

    @property
    def task_map(self):
        return {'segment': {'predictor': FastSAMPredictor, 'validator': FastSAMValidator}}

姿态估计训练器

虽然主任务是分割,但系统也集成了姿态估计功能。PoseTrainer 继承自 DetectionTrainer,专门处理关键点形状属性。注意其中对 Apple MPS 设备的警告,建议在使用 Pose 模型时使用 CPU 以避免已知 bug。

from ultralytics.models import yolo
from ultralytics.nn.tasks import PoseModel
from ultralytics.utils import DEFAULT_CFG, LOGGER

class PoseTrainer(yolo.detect.DetectionTrainer):
    def __init__(self, cfg=DEFAULT_CFG, overrides=None, _callbacks=None):
        if overrides is None:
            overrides = {}
        overrides['task'] = 'pose'
        super().__init__(cfg, overrides, _callbacks)
        if isinstance(self.args.device, str) and self.args.device.lower() == 'mps':
            LOGGER.warning("WARNING ⚠️ Apple MPS known Pose bug. Recommend 'device=cpu'.")

    def get_model(self, cfg=None, weights=None, verbose=True):
        model = PoseModel(cfg, ch=3, nc=self.data['nc'], data_kpt_shape=self.data['kpt_shape'], verbose=verbose)
        if weights:
            model.load(weights)
        return model

训练脚本

这是实际触发训练的入口。脚本会动态调整 YAML 配置文件中的路径,确保相对于当前目录正确加载数据集。显存不足时记得调小 batch 参数。

import os
import torch
import yaml
from ultralytics import YOLO

def abs_path(path, path_type='current'):
    # 假设此处有实现绝对路径的逻辑
    return os.path.abspath(path)

if __name__ == '__main__':
    workers = 1
    batch = 8
    device = "0" if torch.cuda.is_available() else "cpu"
    
    data_path = abs_path(f'datasets/data/data.yaml')
    with open(data_path, 'r') as file:
        data = yaml.load(file, Loader=yaml.FullLoader)
    
    if 'train' in data and 'val' in data and 'test' in data:
        directory_path = os.path.dirname(data_path.replace(os.sep, '/'))
        data['train'] = directory_path + '/train'
        data['val'] = directory_path + '/val'
        data['test'] = directory_path + '/test'
        with open(data_path, 'w') as file:
            yaml.safe_dump(data, file, sort_keys=False)
    
    model = YOLO(r"./config/yolov8-seg-C2f-Faster.yaml").load("./weights/yolov8s-seg.pt")
    results = model.train(
        data=data_path,
        device=device,
        workers=workers,
        imgsz=640,
        epochs=100,
        batch=batch
    )

目标跟踪工具

这部分代码处理轨迹匹配问题。linear_assignment 函数利用成本矩阵进行最优分配,iou_distance 计算交并比作为成本。这些底层算法是保证多目标跟踪稳定性的关键。

import numpy as np
import scipy
from scipy.spatial.distance import cdist
from ultralytics.utils.metrics import bbox_ioa

def linear_assignment(cost_matrix, thresh, use_lap=True):
    if cost_matrix.size == 0:
        return np.empty((0, 2), dtype=int), tuple(range(cost_matrix.shape[0])), tuple(range(cost_matrix.shape[1]))
    if use_lap:
        try:
            import lap
            _, x, y = lap.lapjv(cost_matrix, extend_cost=True, cost_limit=thresh)
            matches = [[ix, mx] for ix, mx in enumerate(x) if mx >= 0]
            unmatched_a = np.where(x < 0)[0]
            unmatched_b = np.where(y < 0)[0]
        except ImportError:
            # Fallback or error handling
            pass
    else:
        x, y = scipy.optimize.linear_sum_assignment(cost_matrix)
        matches = np.asarray([[x[i], y[i]] for i in range(len(x)) if cost_matrix[x[i], y[i]] <= thresh])
    return matches, list(unmatched_a), list(unmatched_b)

def iou_distance(atracks, btracks):
    atlbrs = [track.tlbr for track in atracks] if atracks else []
    btlbrs = [track.tlbr for track in btracks] if btracks else []
    ious = np.zeros((len(atlbrs), len(btlbrs)), dtype=np.float32)
    if len(atlbrs) and len(btlbrs):
        ious = bbox_ioa(np.ascontiguousarray(atlbrs, dtype=np.float32), 
                        np.ascontiguousarray(btlbrs, dtype=np.float32), iou=True)
    return 1 - ious

总结

整个系统从数据处理到模型训练,再到前端展示和实时推理,形成了一套完整的闭环。通过改进 YOLOv8 架构并结合自定义的后处理逻辑,我们在保持高精度的同时优化了响应速度。对于希望深入计算机视觉工程落地的开发者来说,这套代码提供了很好的参考范本。

目录

  1. 项目背景
  2. 效果展示
  3. 数据集信息
  4. 核心代码实现
  5. 应用启动脚本
  6. 实时检测与可视化
  7. 模型接口定义
  8. 姿态估计训练器
  9. 训练脚本
  10. 目标跟踪工具
  11. 总结

更多推荐文章

查看全部
  • AIGC 降重实用软件推荐:免费与高性价比工具汇总
  • Tomcat 服务器安全加固实战指南
  • DeepSeek-R1-Distill-Llama-8B 部署实战:从零搭建推理服务
  • IntelliJ IDEA 搭建 Spring Boot Web 项目实战指南
  • Node.js 通过 WASI 运行 WebAssembly 应用实现性能提速
  • Java 大厂实习面试高频考点:MySQL、Redis、并发与算法实战
  • 前端监控实战:基于 Sentry 的错误与性能管理
  • npm 安装 OpenClaw 遇到 Git 报错的解决方案
  • Spring Cloud 熔断降级详解:Sentinel 实战指南
  • 前端开发者 Agent 工程化开发学习路线
  • 跨平台 Web 字体渲染方案与性能优化实践
  • 本地使用 GitHub 和 Gitee 时连接服务器错误及代理配置冲突解决
  • 位运算实战:两整数之和与只出现一次的数字
  • 在安卓设备使用 llama.cpp 部署 Llava 多模态模型
  • Git 合并时忽略特定文件的 6 种实用技巧
  • Whisper-Tiny.en 轻量级语音识别模型实战与优化
  • OpenClaw 本地 AI 助理搭建与配置实战指南
  • 1877. 数组中最大数对和的最小值
  • 深入理解前端虚拟列表:原理与 React 实现
  • Python 框架 datastream.io:实时异常检测

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online