Python yolov5加Flask打包docker镜像

yolov5加Flask打包docker镜像

将已经训练好的模型打包之后供外部使用

环境准备

1.python 环境,建议python3.8
2.已经搭建好的yolov5 环境
3.已经训练好的模型
4.已经搭建好的flask环境
5.已经搭建好的docker环境

将编写调用yolov5 代码放到yolov5 根目录
代码model_test.py示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from flask import Flask, jsonify, request, abort
import json
import base64
import numpy as np

import torch
import os
from PIL import Image
import cv2
from io import BytesIO, StringIO


app = Flask(__name__)

@app.route('/ana', methods=['GET', 'POST'])
def call_analysis():
print("Hello, World!")

data1 = request.data #----获取的是字符串
#print(data1)
data2 = request.get_data() #----获取的是字符串
#print(data2)
j_data = json.loads(data2) #-----load将字符串解析成json
# print(j_data)
# print(j_data['base64'])

# return jsonify(j_data)
return getbase64(j_data['base64'])

def getbase64(imgbase64):
# print(img)
# os.environ["CUDA_VISIBLE_DEVICES"]
# model = torch.hub.load('./', 'custom', path='./yolov5s.pt', source='local')
model = torch.hub.load('./app/', 'custom', './app/runs/train/exp2/weights/last.pt', source='local')
# model.cuda()
# print(model)
# img1 = Image.open(BytesIO(img))


# 传入为RGB格式下的base64,传出为RGB格式的numpy矩阵
byte_data = base64.b64decode(imgbase64)#将base64转换为二进制
encode_image = np.asarray(bytearray(byte_data), dtype="uint8")# 二进制转换为一维数组
img_array = cv2.imdecode(encode_image, cv2.IMREAD_COLOR)# 用cv2解码为三通道矩阵
img_array = cv2.cvtColor(img_array, cv2.COLOR_BGR2RGB)# BGR2RGB

img1 = img_array
imgs = [img1]
#img2 = cv2.imread('./data/images/zidane.jpg')[:,:,::-1]
#imgs = [img2]

results = model(imgs, size=640)
print('识别成功')
results.ims
results.render()
base64_image = ''
for img in results.ims:
buffered = BytesIO()
img_base64 = Image.fromarray(img)
img_base64.save(buffered, format='JPEG')
base64_image = base64.b64encode(buffered.getvalue()).decode('utf-8')
# with open('./result.txt', 'a+') as f:
# f.write(base64_image)
# f.close()
print(results)
results.save()
base64_image = 'data:image/jpeg;base64,%s' % base64_image
return base64_image
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug = False)

./app/ 为yolov5根目录 ,根据实际情况调整
./app/runs/train/exp2/weights/last.pt 为训练好的模型文件 ,根据实际情况调整

切换环境(切换到Flask和yolov5相关依赖的环境,若安装到默认环境,则不需要)

1
activate yolo

在 yolov5 根目录打包python项目所需的依赖:

1
pip freeze > requirements.txt

编写dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#基于的基础镜像
FROM python:3.8.2
#解决 ImportError: libGL.so.1: cannot open shared object file: No such file or directory 问题
#RUN (apt-get update) && (apt-get install -y libgl1-mesa-dev ffmpeg libsm6 libxext6)
#ENV PYTHONUNBUFFERED 1

RUN apt-get update
RUN apt-get install ffmpeg libsm6 libxext6 -y

#代码添加到code文件夹
ADD . /code
# 设置code文件夹是工作目录
WORKDIR /code
# 安装支持
RUN pip install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
# 暴露对外端口
EXPOSE 5000
# 启动命令
CMD ["python", "/code/app/model_test.py"]

新建dockerBulid 文件夹
在文件夹内,放入Dockerfile,requirements.txt 两个文件
在文件夹内,新建app 文件夹,将yolov5 源码放到此目录下

进行打包

在dockerBulid 文件夹下运行打包命令

1
docker build -t cattest:v1 .

打包过程比较长,需要下载python 依赖和安装依赖,大约20-30分钟左右,只要不报错,可以继续执行

cattest:v1 cattest 为打包镜像名字,v1 为版本,都可以换
注意命令最后有个点”.”

打包完成完成之后可以查看到打包完成的镜像

1
docker images

打包问题处理

出现问题 The read operation timed out

Dockerfile 中将

1
RUN pip install -r requirements.txt

修改为

1
RUN pip install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com

ERROR: Could not find a version that satisfies the requirement importlib-metadata==6.4.1 (from -r requirements.txt (line 55)) (from versions: 0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.10, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20, 0.21, 0.22, 0.23, 1.0.0, 1.1.0, 1.1.1, 1.1.2, 1.1.3, 1.2.0, 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.5.2, 1.6.0, 1.6.1, 1.7.0, 2.0.0, 2.1.0, 2.1.1, 2.1.2, 2.1.3, 3.0.0, 3.1.0, 3.1.1, 3.2.0, 3.3.0, 3.4.0, 3.5.0, 3.6.0, 3.7.0, 3.7.1, 3.7.2, 3.7.3, 3.8.0, 3.8.1, 3.8.2, 3.9.0, 3.9.1, 3.10.0, 3.10.1, 4.0.0, 4.0.1, 4.1.0, 4.2.0, 4.3.0, 4.3.1, 4.4.0, 4.5.0, 4.6.0, 4.6.1, 4.6.2, 4.6.3, 4.6.4, 4.7.0, 4.7.1, 4.8.0, 4.8.1, 4.8.2, 4.8.3, 4.9.0, 4.10.0, 4.10.1, 4.11.0, 4.11.1, 4.11.2, 4.11.3, 4.11.4, 4.12.0, 4.13.0, 5.0.0, 5.1.0, 5.2.0, 6.0.0, 6.0.1, 6.1.0)

将requirement中 importlib-metadata==6.4.1 修改为 importlib-metadata==6.1.0

这个根据实际情况修改,一版为python 的依赖版本不对

运行

启动

1
docker run -p 5000:5000 --name cattest -d cattest:v1

启动之后,可以访问ip:5000 接口查看效果

也可以通过postman 进行测试

查看是否正确的运行,有无报错
通过如下命令来获取容器的日志地址

1
docker inspect --format '{{.LogPath}}' d1f48d1606b9

通过cat 去查看

启动问题处理

启动之后访问不了

两个问题
1.注意需要Dockerfile 暴露端口

  1. run()设置为“0.0.0.0”以使服务器在外部可用
    Flask类的run()方法在本地开发服务器上运行应用程序。
    app.run(host, port, debug, options)
    全部参数都是可选的web

host:要监听的主机名。 默认为127.0.0.1(localhost)。设置为“0.0.0.0”以使服务器在外部可用
port :默认值为5000
debug:默认为false。 若是设置为true,则提供调试信息,能够自动重载代码并显示调试信息
options:要转发到底层的Werkzeug服务器。

File “/code/app/model_test.py”, line 9, in

启动报错

1
2
3
4
File "/code/app/model_test.py", line 9, in <module>
import cv2
File "/usr/local/lib/python3.8/site-packages/cv2/__init__.py", line 181, in <module>
bootstrap()

解决python版本与opencv版本不搭
修改requirements.txt

1
opencv_python==3.4.5

ImportError: libGL.so.1: cannot open shared object file: No such file or directory

启动报错 ImportError: libGL.so.1: cannot open shared object file: No such file or directory
解决,Dcokerfile 中增加

1
2
3
FROM python:3.8
RUN (apt-get update) && (apt-get install -y libgl1-mesa-dev ffmpeg libsm6 libxext6)
ENV PYTHONUNBUFFERED 1

“No such file or directory hubconf.py”‘

启动后报错
相对路径报错:”No such file or directory hubconf.py”‘原因及解决方法

取相对路径不是在主文件里,可能就会有相对路径问题
修改 ‘./yolov5-master/‘ ‘./yolov5-master/runs/train/exp2/weights/last.pt’ 从执行python 的目录开始计算
model = torch.hub.load(‘./yolov5-master/‘, ‘custom’, ‘./yolov5-master/runs/train/exp2/weights/last.pt’, source=’local’)

这个根据实际情况修改

一辈子很短,努力的做好两件事就好;
第一件事是热爱生活,好好的去爱身边的人;
第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;

继开 wechat
欢迎加我的微信,共同交流技术