YOLOv8 测试 5:Linux 中 Docker 部署 YOLOv8,Python 封装 API 接口,base64 图片处理

news/2024/5/22 10:17:16

一、前言

记录时间 [2024-4-14]

系列文章简摘:
Docker 学习笔记(二):在 Linux 中部署 Docker(Centos7 下安装 docker、环境配置,以及镜像简单使用)
API 接口简单使用(二):Python 中使用 Flask(接口封装整理版,含文件上传接口的详细实现)
YOLOv8 测试 3:在 Python 中将 YOLOv8 模型封装成 API 接口使用(上传测试图片并返回识别结果,附测试代码)
YOLOv8 测试 4:在 Linux 中使用 Docker 部署 YOLOv8 模型,并使用简单的命令行脚本测试模型

更多 YOLOv8 测试相关文章请参考上面专栏哦。

本文在 YOLOv8 测试 3 和 4 的基础上开展,在测试 3 中,介绍 Windows 中使用 Python 将 YOLOv8 模型封装成 API 接口来调用;在测试 4 中,介绍 Linux 中使用 Docker 部署 YOLOv8 模型。

综合测试 3 和 4,本文主要实现在 Linux 中 使用 Docker 部署 YOLOv8 模型,并借助 Python 封装 API 接口来调用。在此基础上,再介绍 base64 格式图片的处理方法,最后通过接口上传图片的 base64 格式编码,得到接口返回识别结果


二、思路整理

  • 在本地 PyCharm 中完成项目开发
    • 使用 Flask 框架编写 API 接口
    • base64 格式图片处理
    • YOLOv8 模型的 predict 使用
  • 在 Linux 中部署 Docker,操作系统为 CentOS 7
    • 准备 Linux 云服务器 / 虚拟机
    • 安装并配置 Docker
    • 熟悉 Docker 的镜像容器操作
  • 在 Conda 容器中部署 YOLOv8 项目
    • 通过 FinalShell 把本地项目上传到 Linux 服务器中
    • 部署一个 conda 镜像
    • 配置端口暴露,数据卷挂载
    • 通过数据卷挂载 YOLOv8 项目到容器中
  • 使用 Postman 测试 API 接口
    • 上传图片的 base64 格式编码文件
    • 得到接口返回的图片识别结果

三、YOLOv8 项目开发

在本地 PyCharm 中完成项目开发,更详细的步骤请参考这篇文章

1. 依赖配置

使用 PyCharm 打开我们之前使用过的,从仓库下载的 YOLOv8 项目 ultralytics-main,找到 tests 目录,在该目录下新建 base64_test.py 文件

并在 ultralytics-main/tests/tmp/ 目录下,新建 upload 文件夹,用来存放接口上传的文件;新建 save 文件夹,用来存放项目保存的文件;

在 base64_test.py 文件中导入 YOLOv8 项目运行所需的依赖和配置:

# Ultralytics YOLO 🚀, AGPL-3.0 licenseimport contextlib
from copy import copy
from pathlib import Pathimport cv2
import numpy as np
import pytest
import torch
import yaml
from PIL import Image
from torchvision.transforms import ToTensorfrom ultralytics import RTDETR, YOLO
from ultralytics.cfg import TASK2DATA
from ultralytics.data.build import load_inference_source
from ultralytics.utils import (ASSETS,DEFAULT_CFG,DEFAULT_CFG_PATH,LINUX,MACOS,ONLINE,ROOT,WEIGHTS_DIR,WINDOWS,Retry,checks,is_dir_writeable,
)
from ultralytics.utils.downloads import download
from ultralytics.utils.torch_utils import TORCH_1_9, TORCH_1_13MODEL = WEIGHTS_DIR / "path with spaces" / "yolov8n.pt"  # test spaces in path
CFG = "yolov8n.yaml"
SOURCE = ASSETS / "bus.jpg"
TMP = (ROOT / "../tests/tmp").resolve()  # temp directory for test files
IS_TMP_WRITEABLE = is_dir_writeable(TMP)

2. 编写 API 接口

如果对 Flask 构建 API 接口有疑问的,参考这篇文章

在这个接口中,实现以下要求:

  • 接收接口请求的图片的 base64 格式编码文件
  • 将 base64 格式编码文件还原成图片并保存
  • YOLOv8 模型对该图片进行目标识别
  • 返回目标图片的识别结果

编写文件上传接口

在 base64_test.py 文件中,导入 Flask 框架使用所需依赖:

from flask import Flask, request, send_file

编写一个简单的 API 接口,后面我们在return_image()函数中编写内容。

app = Flask(__name__)@app.post('/baseFile')
def return_image():return "Succeed"if __name__ == '__main__':app.run(host='0.0.0.0', port=5001)

编写好后运行(右键 run ‘base64_test.py’),使用 Postman 测试下这个接口可不可用。

POST 请求不能直接在浏览器测试,浏览器默认 GET 请求。

在这里插入图片描述


处理上传的文件

return_image()函数中编写内容:获取接口上传的文件,并保存到 upload 目录。

# 1. 获取上传的文件# 文件作为参数传递,其 id为 file
# 如果没有接收到这个请求,返回 No file part
if 'file' not in request.files:return "No file part"# 获取文件
file = request.files['file']# 获取文件名
if file.filename == '':return "No selected file"filename = file.filename# 2. 保存到指定位置 upload 文件夹
file.save(TMP / 'upload' / filename)

处理 base64 格式编码文件

base64 格式编码是指:把二进制数据转换成 64 个可以打印的字符。

如何获取图片的 base64 格式编码呢?使用在线图片转换工具,上传图片获得 base64 格式编码,将编码保存为 txt 文件。

在 base64_test.py 文件中,导入依赖:

import base64
from PIL import Image
from io import BytesIO

接着在return_image()函数中编写内容:读取编码文件内容,将 base64 格式编码文件还原成图片并保存。

# 3. 获取编码文件并解码
base_file = TMP / 'upload' / filename# 打开编码文件,读取文件中的内容
with open(base_file, 'r') as file:content = file.read()# 将 base64_str 以 “,” 分割为两部分,context 部分是需要解码的部分
base64_str = str(content)
head, context = base64_str.split(",")# 解码时只要内容部分
img_data = base64.b64decode(context)# 4. 通过解码内容得到图片,保存图片
image = Image.open(BytesIO(img_data))
image.save(TMP / 'save' / 'test_image.jpg')# 看图片
# image.show()

3. YOLOv8 识别图片

接下来,下载并使用 YOLOv8 模型,对获得的图片进行目标识别。

接着在return_image()函数中编写内容:对图片进行目标识别,并返回识别结果。

# 5. 使用 YOLOv8 模型对该图片进行目标识别
model = YOLO(MODEL)# 得到的图片路径
source = TMP / 'save' / 'test_image.jpg'# 保存 目标识别的结果
results = model.predict(source, save=True, imgsz=320, conf=0.5)# 6. 获取 识别结果 的保存路径
save_path = Path(results[0].save_dir)
image_path = save_path / 'test_image.jpg'# 7. 以图片形式 返回结果
return send_file(image_path)

编写好后运行(右键 run ‘base64_test.py’),使用 Postman 测试下,选 form-data 类型,上传 base64 格式编码文件,测试下识别结果是否返回成功。

在这里插入图片描述


四、在 Linux 中的准备工作

1. Linux 中部署 Docker

宿主机 Linux,操作系统为 CentOS 7,Linux 虚拟机安装,参考这篇文章

在 Linux 中部署 Docker,参考这篇文章

2. 上传本地项目

本地项目 ultralytics-main 已经完成编写,关闭 PyCharm,找到 ultralytics-main 文件夹

通过 FinalShell,把 ultralytics-main 一整个上传到 Linux 服务器 /home/YOLO 目录中(目录随便)

在这里插入图片描述


3. 运行 conda 容器

在之前的文章中,参考这篇文章,我们已经在 Docker 中部署了 Conda 环境,可以直接把这个部署好的 conda 虚拟环境拿来用。

如果之前的容器丢失了,那我们快速地部署一下吧。

# 1. 创建 conda 容器并运行
docker run -it --name yolopy03 conda/miniconda3 /bin/bash# 2. 配置 yolov8 运行环境
conda create -n yolov8 python=3.9
# Proceed ([y]/n)? y# 3. 检查虚拟环境配置
conda env list# 4. 进入 base 环境
source activate# 5. 激活 Conda 环境,创建 yolov8 运行
conda activate yolov8# 6. 配置清华源镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple# 7. 安装 pytorch
pip install torch==1.13.1+cpu torchvision==0.14.1+cpu torchaudio==0.13.1 \
--extra-index-url https://download.pytorch.org/whl/cpu# 8. 检查 python 环境
python --version# 9. 退出容器 exit,退出虚拟环境用 conda deactivate,退不出就 kill,没事的
exit

五、部署 YOLOv8 项目

接下来,在 Docker 中部署 YOLOv8 项目,配置数据卷挂载,更详细的步骤请参考这篇文章

1. 导出 yolov8 虚拟环境

把上面那个配置好的 yolopy03 容器 conda 环境拿过来,导出 envs 下面的 yolov8 虚拟环境。

虚拟环境位于容器的 /usr/local/envs ,把它导出到宿主机的 /home/YOLO目录下:

# 导出 yolov8 虚拟环境
docker cp yolopy03:/usr/local/envs /home/YOLO

2. 运行新的容器

在运行前,配置下端口暴露,以及数据卷挂载。

端口暴露是为 API 接口访问做准备,数据卷挂载是为了将宿主机上的 ultralytics-main 项目和 yolov8 虚拟环境同步到新容器中。

这样可以省去新容器重复配置的步骤,一些创建的、安装好的东西不用重复安装了。

但是参数 / 变量的配置是不会生效的,比如清华源镜像。

  • -it:交互式运行;
  • --name:容器命名;
  • -p 3352:5001:把容器的 5001 端口映射到宿主机的 3352 端口;
  • -v 宿主机路径:容器内路径:把容器内路径挂载到宿主机路径,可以挂载很多个路径。
docker run -it --name yolopy06 -p 3352:5001 \-v /home/YOLO/ultralytics-main:/usr/local/ultralytics-main \-v /home/YOLO/envs:/usr/local/envs conda/miniconda3

进入容器后,检查下虚拟环境配置,然后激活 yolov8 运行环境。

# 检查虚拟环境配置
conda env list# 进入 base 环境
source activate# 激活 yolov8 运行环境
conda activate yolov8

配置清华源镜像,否则下载东西非常慢

# 检查 python 环境
python --version# 配置清华源镜像
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

3. 安装 YOLOv8 项目依赖

进入 ultralytics-main 目录,为什么容器内会有 ultralytics-main 文件呢?答对了,因为数据卷挂载。

cd /usr/local/ultralytics-main

在该目录下,安装 / 更新 YOLOv8 项目运行所需的依赖:

# 安装 YOLOv8 项目依赖
pip install -e .# 更新 opencv-python
pip uninstall opencv-python -y
pip install opencv-python-headless -i https://pypi.tuna.tsinghua.edu.cn/simplepip install pytest
pip install flask

六、项目测试运行

1. 运行项目

先确定容器工作目录:/usr/local/ultralytics-main

python 方式运行 base64_test.py(熟悉吗?我们刚刚写的)

python tests/base64_test.py

2. 接口测试

测试方式,使用 Postman 测试。

http://ip:3352/baseFile

如图所示,项目启动成功后,输入宿主机 ip / 宿主机端口,POST 请求,添加 base64 格式编码文件,Send 测试!

返回了识别结果,测试成功!

在这里插入图片描述


再来看一下服务端的情况吧:

  • 处理了 base64 编码文件,保存了图片;
  • 下载了 yolov8n.pt 模型,对图片进行目标识别;
  • 将结果保存,并通过接口返回给客户端。

在这里插入图片描述


七、总结

本文主要实现在 Linux 中 使用 Docker 部署 YOLOv8 模型,并借助 Python 封装 API 接口来调用。还介绍了 base64 格式图片的处理方法,最后通过接口上传图片的 base64 格式编码,得到接口返回识别结果。复习了数据卷的命令挂载方法。


一些参考资料

Docker 官方文档:https://docs.docker.com/engine/install/centos/
Docker 远程仓库:https://hub.docker.com/
FinalShell 下载:http://www.hostbuf.com/t/988.html
YOLOv8 官方文档:https://docs.ultralytics.com/zh/
YOLOv8 模型仓库地址:https://github.com/ultralytics/ultralytics
PyCharm官网:https://www.jetbrains.com/pycharm/download/?section=windows
Postman 官网:https://www.postman.com/
阿里云官网:https://www.aliyun.com/


http://www.mrgr.cn/p/76333453

相关文章

EasyPoi表格导入添加校验

EasyPoi表格导入添加校验 项目添加maven依赖实体类自定义校验controller测试结果 代码地址 项目添加maven依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www…

IfcDoorPanelOperationEnum

IfcDoorPanelOperationEnum 类型定义该列举定义了各个门板的基本操作方式,如图所示。EnumeratorIllustrationSwinging DoubleActing Sliding Folding Revolving Rollingup FixedPanel UserDefinedNotDefinedFigure — Door operations 门板的打开方向由IfcDoor的局部位置决定。…

Python案例:输出公元后到目前为止全部回文日期

一、回文日期 一个日期,如果顺读和倒读都一样,那么就称之为回文日期,比如今天:20211202,就是一个神奇的回文日期。 二、提出任务输出公元后的全部回文日期 要求每行输出五个回文日期 统计总共有多少个回文日期三、完成任务 (一)涉及知识点 1、time模块time模块有两个常用…

面相对象

找东西来解决的过程就叫做面相对象 java就是学习获取已有对象来使用从而解决问题,如果要解决的事情是没有对象能解决的,就要自己设计对象并使用可以设计类来获取对象 工具类不需要创建对象,只要调用类名即可

【文献分享】PCCP:机器学习 + 分子动力学 + 第一性原理 + 热学性质 + 微观结构

分享一篇关于机器学习 分子动力学 第一性原理 热学性质&#xff08;密度、粘度、扩散系数&#xff09; 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Machine learning, 2. Deep potential, 3. Molecular dynamics 4. Molten salt, 5. Thermo…

vscode remote-x11 ssh 连接时Another All configured authentication methods failed like #10 报错修复

错误 remote-x11-ssh插件使用ssh2扩展 出现以下错误 https://github.com/joelspadin/vscode-remote-x11/issues/75 Error: All configured authentication methods failed 原因 https://github.com/mscdex/ssh2/issues/989 解决 换成ed25519 并修改配置

【uniapp】vscode安装插件、ts校验、允许json文件注释

1、vscode安装的插件&#xff1a; uni-create-viewuni-hlperuniapp小程序扩展 2、ts校验 安装插件&#xff1a; pnpm i -D types/wechat-miniprogram uni-helper/uni-app-types配置tsconfig.json {"extends": "vue/tsconfig/tsconfig.json","compi…

机器人码垛机的技术特点与应用

随着科技的飞速发展&#xff0c;机器人技术正逐渐渗透到各个行业领域&#xff0c;其中&#xff0c;机器人码垛机在物流行业的应用尤为引人瞩目。它不仅提高了物流效率&#xff0c;降低了成本&#xff0c;更在改变传统物流模式的同时&#xff0c;为行业发展带来了重大的变革。 一…

Java并发(二十五)----异步模式之生产者/消费者

1. 定义 要点与Java并发(二十二)----同步模式之保护性暂停中的保护性暂停中的 GuardObject 不同,不需要产生结果和消费结果的线程一一对应这样的好处是消费队列可以用来平衡生产和消费的线程资源生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据消息…

Chrome免安装绿色版制作教程

chrome离线安装包 https://downzen.com/en/windows/google-chrome/versions/?page=1 方法一: 1) 下载最新版Google Chrome离线安装包文件1. Stable版(稳定版、正式版)下载:http://www.google.com/chrome/eula.html?standalone=1注:Stable 似乎只有最新稳定版可以从官方下…

UML学习

UML(Unified Modeling Language)&#xff1a;统一建模语言&#xff0c;提供了一套符号和规则来帮助分析师和设计师表达系统的架构、行为和交互 类图&#xff1a;描绘类、接口之间的关系(继承、实现、关联、依赖等)以及类的内部结构(属性和方法)&#xff0c;直观展现系统的静态…

独一无二:探索单例模式在现代编程中的奥秘与实践

设计模式在软件开发中扮演着至关重要的角色&#xff0c;它们是解决特定问题的经典方法。在众多设计模式中&#xff0c;单例模式因其独特的应用场景和简洁的实现而广受欢迎。本文将从多个角度详细介绍单例模式&#xff0c;帮助你理解它的定义、实现、应用以及潜在的限制。 1. 什…

打造心灵栖息地:YY日记App——原型设计分享

YY日记App是一个专为年轻人打造的心灵日记应用,旨在提供一个私密、个性化的日记记录平台。在本篇博客中,我将分享我对YY日记App的原型设计思路和实现过程。一、用户研究在设计YY日记App的原型之前,我进行了深入的用户研究,明确了目标用户群体为年轻人,他们希望有一个简洁易…

cpu scheduling

基本概念多道程序设计的目的将CPU的利用率最大化 多个进程同时存在于内存(并发),当一个进程暂不使用cpu时,系统调用另一个进程占用cpu。 cpu调度程序whenever the cpu becomes idle(空闲) the operating system must select one of the processes in the ready queue to be…

毕业设计4.17

后台返回数据在安卓端列表化显示,数据处理出错

从入门到精通C++之类和对象(续)

目录 初始化列表构造函数&#xff1f;拷贝构造&#xff1f;浅谈explicit关键字友元 内部类static成员总结 初始化列表 引入初始化列表&#xff1a;简化代码&#xff0c;提高效率 在编程中&#xff0c;初始化列表是一种用于在创建对象时初始化成员变量的快捷方式。通过初始化列…

第十五届蓝桥杯大赛软件赛省赛 C/C++ 大学 B 组(基础题)

试题 C: 好数 时间限制 : 1.0s 内存限制: 256.0MB 本题总分&#xff1a;10 分 【问题描述】 一个整数如果按从低位到高位的顺序&#xff0c;奇数位&#xff08;个位、百位、万位 &#xff09;上 的数字是奇数&#xff0c;偶数位&#xff08;十位、千位、十万位 &…

NGINX Ingress Controller 设置未配置过的域名增加默认路由

背景 k8s 集群对应的公网 slb ip 经常被人绑定域名,监控侧经常会收集到 502 相关状态码的异常告警,着手处理这种bad case策略 1. 所有没有在ingress 配置过的域名要进行处理,即不是公司的、非法绑定到slb 上的域名要加上一条策略 2. NGINX Ingress Controller 设置未配置过…

基于达梦数据库开发-Java篇

文章目录 前言一、示例展示1.环境准备2.采用基础的jdbc调用3.采用扩展的mybatis调用 二、注意事项1.使用路径注解2.数据库对象的准确引用 三、可能异常1.无效的表或视图名2.无效的表或视图名3.网络通信异常 总结 前言 达梦提供了JDBC方式的驱动以便进行Java开发。默认情况下相…

web安全学习笔记(9)

记一下第十三课的内容。 准备工作&#xff1a;在根目录下创建template目录&#xff0c;将login.html放入其中&#xff0c;在该目录下新建一个reg.html。在根目录下创建一个function.php 一、函数声明与传参 PHP中的函数定义和其他语言基本上是相同的。我们编辑function.php …