在 AI 目标检测领域,YOLO(You Only Look Once)系列模型以其高效、精准的特点成为主流选择,而 Spring Boot 作为 Java 生态最流行的 Web 开发框架,能轻松将 YOLO 的检测能力封装为可复用的接口。本文将全程还原 Windows 环境下,通过 Docker 部署 YOLOv8 模型,并集成到 Spring Boot 项目的完整流程,包含环境准备、问题排查、代码集成、接口测试,适合有一定 Java 和 Docker 基础的开发者参考。
在本地部署 YOLO 模型时,常常会遇到环境依赖复杂、版本冲突、跨平台兼容性差等问题,而 Docker 能完美解决这些痛点------通过容器化封装 YOLO 运行所需的所有依赖,实现"一次构建,到处运行"。
结合 Spring Boot 的优势,我们可以将 YOLO 的图片检测能力封装为 HTTP 接口,支持前端上传图片、后端返回检测结果,轻松集成到小程序、APP、管理系统等各类业务场景中,实现"检测能力接口化、业务集成轻量化"。
本文核心目标:在 Windows 环境下,完成 Docker 部署 YOLOv8 → 解决部署过程中的常见问题 → 将 YOLO 检测能力集成到 Spring Boot 项目 → 提供可直接调用的图片检测接口。
2.1 基础环境清单
- 操作系统:Windows 10/11(建议开启 WSL2,提升 Docker 性能)
- Docker:Docker Desktop(版本 20.0 以上)
- JDK:17(Spring Boot 3.2.x 要求)
- Maven:3.6+(项目构建)
- Spring Boot:3.2.4
- YOLO 模型:YOLOv8n(轻量版,适合 CPU 运行,无需 GPU 加速)
2.2 前置环境配置
2.2.1 Docker Desktop 配置(关键)
- 安装 Docker Desktop 后,开启 WSL2 后端(性能优于 Hyper-V):
- 打开 Docker Desktop → Settings → General → 勾选 "Use the WSL 2 based engine"
- 重启 Docker Desktop,确保服务正常启动(右下角 Docker 图标显示绿色)
- 配置文件共享(避免挂载目录权限问题):
- 打开 Docker Desktop → Settings → Resources → File Sharing
- 点击 "+" 按钮,添加本地目录
D:yolo_test(用于挂载 Docker 容器,存储图片和检测结果),保存后重启 Docker
2.2.2 项目基础准备
本文基于已有的 Spring Boot 项目(原有功能包含 Ollama 大模型集成、PGvector 向量存储、阿里云语音识别等),核心是在原有项目基础上新增 YOLO 图片检测模块,无需从零搭建 Spring Boot 项目。
这一步是核心基础,我们将通过 Docker 拉取 YOLOv8 官方镜像,运行容器并完成图片检测,解决部署过程中最常见的"文件找不到""挂载失败"等问题。
3.1 拉取 YOLOv8 官方 Docker 镜像
打开 PowerShell(管理员模式),执行以下命令拉取官方镜像(内置 YOLOv8 所有依赖,无需手动配置):
docker pull ultralytics/ultralytics:latest
镜像拉取完成后,执行 docker images 可查看镜像是否存在。
3.2 运行 Docker 容器并挂载本地目录
核心命令 (挂载本地 D:yolo_test 到容器内 /yolo_data,实现本地与容器文件互通):
GPT plus 代充 只需 145docker run -it --rm -v /d/yolo_test:/yolo_data ultralytics/ultralytics:latest
命令说明:
-it:交互式终端,方便在容器内执行命令--rm:容器退出后自动删除,避免残留-v /d/yolo_test:/yolo_data:目录挂载(Windows 路径需用/d/替代D:,Docker 才能识别)
3.3 执行 YOLOv8 图片检测(首次实操)
3.3.1 准备测试图片
在本地 D:yolo_test 目录下,放入一张测试图片,命名为 test.jpg(注意 :文件名和后缀必须完全匹配,避免大小写错误,如 Test.jpg、test.jpeg 都会导致失败)。
3.3.2 执行检测命令
在容器内(命令行显示 root@xxx:/ultralytics#),执行以下命令:
yolo detect predict model=yolov8n.pt source=/yolo_data/test.jpg save=True
命令说明:
model=yolov8n.pt:使用 YOLOv8 轻量版模型(n=纳米版,适合 CPU 运行,体积小、速度快)source=/yolo_data/test.jpg:检测源为容器内挂载目录下的 test.jpgsave=True:保存检测结果(带检测框的图片)
3.4 常见问题排查(重点!)
首次运行大概率会遇到以下问题,本文全程还原排查过程,帮你快速解决。
问题1:FileNotFoundError: /yolo_data/test.jpg does not exist
报错原因:容器内找不到指定图片,核心是两个原因之一:
- 本地
D:yolo_test目录下没有 test.jpg,或文件名/后缀错误 - 目录挂载失败,容器内
/yolo_data目录为空
解决步骤:
- 先在容器内执行
ls /yolo_data,查看挂载目录是否有文件:- 如果输出为空:说明挂载失败,重新执行容器运行命令(确保路径是
/d/yolo_test,而非D:yolo_test) - 如果输出
yolo_data(子目录):说明图片放在了D:yolo_testyolo_data下,需修改命令为source=/yolo_data/yolo_data/test.jpg
- 如果输出为空:说明挂载失败,重新执行容器运行命令(确保路径是
- 确认本地
D:yolo_test下有 test.jpg,重新执行检测命令
问题2:检测结果保存到容器内,本地看不到
报错现象 :检测成功,但本地 D:yolo_test 目录下没有检测结果
原因 :YOLO 默认将结果保存到容器内 /ultralytics/runs/detect/predict,而非挂载目录
解决方法:
- 手动复制结果到挂载目录(容器内执行):
GPT plus 代充 只需 145
cp -r /ultralytics/runs/detect/predict /yolo_data/ - 下次检测直接指定保存路径(推荐),修改命令为:
yolo detect predict model=yolov8n.pt source=/yolo_data/test.jpg save=True project=/yolo_data/runs name=detect这样结果会直接保存到
/yolo_data/runs/detect,对应本地D:yolo_test unsdetect
3.5 检测成功验证
检测成功后,容器内会输出类似以下日志:
GPT plus 代充 只需 145image 1/1 /yolo_data/test.jpg: 640x480 1 cup, 1 tv, 1 mouse, 1 refrigerator, 1 book, 63.4ms Speed: 4.6ms preprocess, 63.4ms inference, 8.6ms postprocess per image at shape (1, 3, 640, 480) Results saved to /yolo_data/runs/detect
此时打开本地 D:yolo_test unsdetect 目录,会看到带检测框的 test.jpg,图片上会标注出识别到的物体(如杯子、电视、鼠标等),说明 Docker 部署 YOLOv8 成功!
Docker 部署 YOLOv8 成功后,我们将其集成到 Spring Boot 项目,提供 HTTP 接口,支持前端上传图片、后端返回检测结果(识别的物体、数量、耗时、结果图片路径)。
4.1 项目改造:pom.xml 依赖新增
在原有 pom.xml 基础上,新增文件操作、命令执行相关依赖(用于处理图片上传、调用 Docker 命令):
2.15.1
3.14.0
commons-io
commons-io
${commons-io.version}
org.apache.commons
commons-lang3
${commons-lang3.version}
ch.ethz.ganymed
ganymed-ssh2
262
注:原有依赖(Spring Boot Web、Ollama、PGvector、阿里云语音等)全部保留,无需修改。
4.2 项目改造:application.yml 配置新增
在原有配置基础上,新增 YOLO 和 Docker 相关配置,同时补充文件上传限制:
GPT plus 代充 只需 145# 新增 YOLO 配置 yolo: # Docker 本地挂载目录(对应本地 D:yolo_test) docker-mount-path: D:yolo_test # 容器内挂载路径 container-mount-path: /yolo_data # YOLO 模型名称(默认 yolov8n.pt) model-name: yolov8n.pt # 检测结果保存目录(容器内) container-result-path: /yolo_data/runs/detect # 本地临时文件存储目录 local-temp-path: D:yolo_test emp # Docker 镜像名称 docker-image: ultralytics/ultralytics:latest # 原有配置保留,补充文件上传配置 spring: servlet: multipart: max-file-size: 10MB # 单文件最大10MB max-request-size: 50MB # 总请求最大50MB
4.3 新增核心代码(可直接复制使用)
新增 4 个核心类,实现图片上传、Docker 命令调用、检测结果解析、接口提供,全部放在 com.ruoyi 包下(与原有项目包结构一致)。
4.3.1 配置类:YoloConfig.java(读取 YOLO 配置)
package com.ruoyi.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; / * YOLO 配置类,读取 application.yml 中的 yolo 相关配置 */ @Data @Component @ConfigurationProperties(prefix = "yolo") public class YoloConfig { / * Docker 本地挂载目录 */ private String dockerMountPath; / * 容器内挂载路径 */ private String containerMountPath; / * YOLO 模型名称 */ private String modelName; / * 容器内检测结果保存路径 */ private String containerResultPath; / * 本地临时文件存储目录 */ private String localTempPath; / * Docker 镜像名称 */ private String dockerImage; }
4.3.2 实体类:YoloDetectResult.java(封装检测结果)
GPT plus 代充 只需 145package com.ruoyi.entity; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.List; / * YOLO 检测结果返回实体,用于接口返回 JSON 格式数据 */ @Data @Builder @NoArgsConstructor @AllArgsConstructor public class YoloDetectResult { / * 检测是否成功 */ private boolean success; / * 错误信息(失败时返回) */ private String errorMsg; / * 检测到的目标列表 */ private List
detectObjects; / * 检测耗时(毫秒) */ private long costTime; / * 检测结果图片路径(本地) */ private String resultImagePath; / * 检测目标实体(单个物体的信息) */ @Data @Builder @NoArgsConstructor @AllArgsConstructor public static class DetectObject { / * 目标类别(如 cup、tv、mouse) */ private String className; / * 目标数量 */ private int count; / * 置信度(0-1),越大越精准 */ private float confidence; } }
4.3.3 工具类:YoloDetectUtil.java(核心检测逻辑)
package com.ruoyi.util; import com.ruoyi.config.YoloConfig; import com.ruoyi.entity.YoloDetectResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; / * YOLO 图片检测工具类,封装 Docker 命令调用、结果解析逻辑 */ @Slf4j @Component @RequiredArgsConstructor public class YoloDetectUtil // 2. 校验图片格式(仅支持 jpg/jpeg/png/bmp) String originalFilename = file.getOriginalFilename(); if (originalFilename == null || !originalFilename.matches(".*\.(jpg|jpeg|png|bmp)$")) { return YoloDetectResult.builder() .success(false) .errorMsg("仅支持 jpg/jpeg/png/bmp 格式的图片") .build(); } // 3. 创建临时目录(用于存储上传的图片) File tempDir = new File(yoloConfig.getLocalTempPath()); if (!tempDir.exists()) ", yoloConfig.getLocalTempPath()); return YoloDetectResult.builder() .success(false) .errorMsg("创建临时目录失败") .build(); } } // 4. 保存上传的图片到本地挂载目录(Docker 可访问) String fileName = UUID.randomUUID() + "_" + originalFilename; String localImagePath = yoloConfig.getDockerMountPath() + File.separator + fileName; File localImageFile = new File(localImagePath); file.transferTo(localImageFile); log.info("上传的图片已保存到:{}", localImagePath); // 5. 构建 Docker 命令(调用 YOLO 检测) String containerImagePath = yoloConfig.getContainerMountPath() + "/" + fileName; String dockerCmd = String.format( "docker run --rm -v %s:%s %s yolo detect predict model=%s source=%s save=True project=%s name=detect", yoloConfig.getDockerMountPath().replace("\", "/"), // Windows 路径转换为 Docker 可识别格式 yoloConfig.getContainerMountPath(), yoloConfig.getDockerImage(), yoloConfig.getModelName(), containerImagePath, yoloConfig.getContainerResultPath() ); log.info("执行 Docker 命令:{}", dockerCmd); // 6. 执行 Docker 命令,获取输出结果 Process process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", dockerCmd}); int exitCode = process.waitFor(); if (exitCode != 0) ,错误信息:{}", exitCode, errorMsg); return YoloDetectResult.builder() .success(false) .errorMsg("执行检测失败:" + errorMsg) .build(); } // 7. 解析命令输出,提取检测到的物体信息 String output = new String(process.getInputStream().readAllBytes()); log.info("YOLO 检测命令输出:{}", output); List
detectObjects = parseDetectResult(output); // 8. 拼接检测结果图片路径(本地可访问) String resultImagePath = yoloConfig.getDockerMountPath() + File.separator + "runs" + File.separator + "detect" + File.separator + "detect" + File.separator + fileName; long costTime = System.currentTimeMillis() - startTime; // 9. 返回成功结果 return YoloDetectResult.builder() .success(true) .detectObjects(detectObjects) .costTime(costTime) .resultImagePath(resultImagePath) .build(); } catch (IOException e) catch (InterruptedException e) catch (Exception e) } / * 解析 YOLO 检测命令输出,提取目标信息(类别、数量) * @param output 命令输出字符串 * @return 检测目标列表 */ private List
parseDetectResult(String output) // 匹配 "1 cup, 1 tv, 1 mouse" 格式的字符串 Matcher matcher = DETECT_PATTERN.matcher(output); Map
countMap = new HashMap<>(); while (matcher.find()) // 转换为 DetectObject 列表(置信度默认 0.9,可根据实际输出优化) for (Map.Entry
entry : countMap.entrySet()) return result; } }
4.3.4 控制器:YoloController.java(提供 HTTP 接口)
GPT plus 代充 只需 145package com.ruoyi.controller; import com.ruoyi.entity.YoloDetectResult; import com.ruoyi.util.YoloDetectUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; / * YOLO 图片检测控制器,提供 HTTP 接口供前端调用 */ @Slf4j @RestController @RequestMapping("/api/yolo") @RequiredArgsConstructor public class YoloController { private final YoloDetectUtil yoloDetectUtil; / * 图片目标检测接口 * @param file 上传的图片文件 * @return 检测结果(JSON 格式) */ @PostMapping("/detect") public ResponseEntity
detectImage(@RequestParam("file") MultipartFile file) { try { YoloDetectResult result = yoloDetectUtil.detectImage(file); return ResponseEntity.ok(result); } catch (Exception e) } }
4.4 启动类验证(确保组件扫描)
确保 Spring Boot 启动类扫描到新增的配置类、控制器等组件,修改启动类(如已有则无需新增):
package com.ruoyi; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; @Slf4j @SpringBootApplication(scanBasePackages = "com.ruoyi") // 扫描 com.ruoyi 下所有组件 @EnableConfigurationProperties public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); log.info("Spring Boot 应用启动成功,端口:8889"); } }
项目启动成功后,我们通过 Postman 测试图片检测接口,验证集成效果。
5.1 测试准备
- 启动 Docker Desktop(确保 Docker 服务正常运行)
- 启动 Spring Boot 应用(端口 8889)
- 准备一张测试图片(jpg/png 格式)
5.2 Postman 测试步骤
- 新建 POST 请求,地址:
http://localhost:8889/api/yolo/detect - 请求类型选择
form-data,key 填写file,value 选择"文件",上传测试图片 - 点击发送请求,查看返回结果
5.3 成功返回示例
GPT plus 代充 只需 145
{ "success": true, "errorMsg": null, "detectObjects": [ { "className": "cup", "count": 1, "confidence": 0.9 }, { "className": "tv", "count": 1, "confidence": 0.9 }, { "className": "mouse", "count": 1, "confidence": 0.9 } ], "costTime": 1200, "resultImagePath": "D:\yolo_test\runs\detect\detect\xxx_test.jpg"
}
GPT plus 代充 只需 145 返回结果说明:
success: true:检测成功detectObjects:识别到的物体列表(类别、数量、置信度)costTime:检测耗时(毫秒)resultImagePath:本地带检测框的图片路径,可直接打开查看结果
6.1 常见问题
6.2 优化建议
1. 优化检测速度
- 开启 Docker GPU 加速(需安装 NVIDIA 显卡驱动和 Docker GPU 插件)
- 使用更轻量的 YOLO 模型(如 YOLOv8n 已是最轻量,可考虑模型量化压缩)
- 图片预处理:上传前对图片进行压缩,减小分辨率
2. 增强接口安全性
- 添加 API Key 权限校验,防止匿名调用
- 添加接口限流,避免 Docker 容器被压垮
- 文件类型严格校验,防止恶意文件上传
3. 拓展功能
- 支持批量图片检测(上传压缩包,异步处理)
- 检测结果持久化:将检测结果存入数据库(如 PostgreSQL),支持历史记录查询
- 前端可视化:新增前端页面,实现图片上传、检测结果可视化
- 视频流检测:支持 RTSP 视频流实时目标检测
本文全程还原了 Windows 环境下,通过 Docker 部署 YOLOv8 模型,并集成到 Spring Boot 项目的完整流程,从环境准备、问题排查到代码集成、接口测试,每一步都提供了详细的实操步骤和解决方案。
核心亮点
- 通过 Docker 容器化部署 YOLOv8,避免环境依赖冲突,实现快速部署
- 完整解决了 Windows 下 Docker 挂载目录、文件找不到等常见问题
- 将 YOLO 检测能力封装为 Spring Boot 接口,可直接集成到各类业务系统
- 代码可直接复用,适配原有 Spring Boot 项目(无需从零搭建)
后续拓展方向
基于本文的基础,可以进一步拓展:
- 视频流实时目标检测
- 批量图片异步处理
- 检测结果可视化 Dashboard
- 模型训练与迭代优化
让 YOLO 目标检测能力更好地服务于实际业务场景。如果在实操过程中遇到问题,可参考本文的问题排查部分,或留言交流。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/244778.html