Yolov5部署成为Python接口 当然是用flask实现啦~ yolo5写成接口

本文档介绍了如何在Ubuntu18.04上搭建Yolov5环境,确保CUDA10.0和CUDNN7.4.1等组件配置正确。接着,利用Flask创建API接口,将Yolov5模型集成,实现目标检测功能。作者分享了从修改requirements.txt到编写flask应用的详细步骤,并提供了项目源码链接。
部署运行你感兴趣的模型镜像

一、在此之前你是不是要先把yolov5跑通?

yolov5的环境特别简单,建议在Ubuntu18.04下面部署,一次成型,省去很多麻烦。

  • Ubuntu18.04
  • RTX2080
  • CUDA10.0
  • CUDNN7.4.1
  • Torch1.3.1GPU
  • torchvision0.4.2
  • Python 3.6.5

项目地址:https://gitee.com/situyufeng/yolov5.git

github太慢了 我把他迁到了gitee上面

装好Torch以后呢,记得修改pip为清华源,然后修改requirements.txt里面关于cocoapi的部分。

第13行:

git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI

换成:

git+https://gitee.com/situyufeng/cocoapi.git#subdirectory=PythonAPI

然后

pip install -r requirements.txt

至此所有跑通yolov5的准备工作已经结束了

权重的话不要担心,文末我上传了整个项目,希望可以换点积分。

对了,运行下面这个命令的话是可以跑通的~

python detect.py --source ./inference/images/ --weights yolov5s.pt --conf 0.4

yolov5最方便的地方就是用Python写的,不需要编译,不需要编译,不需要编译!

二、开始搭建flask接口!

第一件事就是安装flask

pip install flask

接下来接口的主要函数文件都是基于detect.py,本来想做成yolov3那种项目和配置,奈何能力有限,读取权重的时候无法生成model。说到这里,yolov4我也尝试过做成flask接口,这里OpenCV拖了后腿,最新OpenCV不支持yolo4里面的mish函数,所以没有办法读取整个模型,可能是因为太新了不兼容。

打开detect.py复制一份,改成yolo5.py

因为我改动的部分实在是太多了,这里只能简要说一下了,具体的修改见我上传的代码。

part1 detect.py就是核心推断函数,只不过传参使用命令行的方式传进去的,
但是所有的参数并不是每一个都需要修改,常用的也就是图片路径
(这里需要夸赞U神单张批量和视频都写到一个函数里面了,当初改yolov3的时候简直麻烦到天上去了),
剩下的参数写成默认参数就可以了:
def detect( save_img=False,
            o_weights = "weights/yolov5s.pt",
            o_source = "inference/images",
            o_output = "inference/output",
            o_img_size = 640,
            o_conf_thres = 0.4,
            o_iou_thres = 0.5,
            o_fourcc = "mp4v",
            o_device = '',
            o_view_img = False,
            o_save_txt = False,
            o_classes = None,
            o_agnostic_nms = False,
            o_augment = False):
    p = ''
    c1 = (0,0)
    c2 = (0,0)
    label_no_value = ''
    detection_result_list = []
    out, source, weights, view_img, save_txt, imgsz = \
        o_output, o_source, o_weights, o_view_img, o_save_txt, o_img_size
    webcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')

第二个部分:

part2 原始代码在获得推断结果以后会进行调用绘图函数画框,保存文本结果
,保存图像结果等一系列操作,那我们的思路就是在他调用绘图函数之前截获他的目标检测坐标和标签信息:
            if det is not None and len(det):
                # 重新缩放框从img_size到im0的尺寸
                det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
                # 打印结果
                # for c in det[:, -1].unique():
                #     n = (det[:, -1] == c).sum()  # 推断每一类
                    # s += '%g %ss, ' % (n, names[int(c)])  # 加到输出串里面个数 标签
                    # s  = 'sssssaaaaassssaaaa %s' % ("asdffdsfsdfsfsf")
                # 写出结果
                for *xyxy, conf, cls in det:
                    label = '%s: %.2f' % (names[int(cls)], conf)
                    label_no_value = '%s' % (names[int(cls)])
                    confidences_value = '%.2f' % (conf)
                    c1,c2=plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
                    print(c1,c2,label_no_value)

忽略我乱七八糟的调试代码~

第三个部分:

part3 我们只是为了拿他的坐标、标签和置信度,并不需要(至少暂时不需要)保存结果,真的完成绘图步骤,所以找到这些地方然后注释掉以提升速度:
            # 打印时间 (推断时间 + NMS)
            # print('%sDone. (%.3fs)' % (s, t2 - t1))

            # # 视频流的结果
            # if view_img:
            #     #返回实时检测结果
            #     cv2.imshow(p, im0)
            #     if cv2.waitKey(1) == ord('q'):  # q to quit
            #         raise StopIteration

            # # 保存结果 (推断后的图像)
            # if save_img:
            #     if dataset.mode == 'images':
            #         cv2.imwrite(save_path, im0)
            #     else:
            #         if vid_path != save_path:  # 新的视频
            #             vid_path = save_path
            #             if isinstance(vid_writer, cv2.VideoWriter):
            #                 vid_writer.release()  # 释放上一个视频编写器句柄

            #             fps = vid_cap.get(cv2.CAP_PROP_FPS)
            #             w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
            #             h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
            #             vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*opt.fourcc), fps, (w, h))
            #         vid_writer.write(im0)
    # print(detection_result_list)
其中绘图函数写在了utils.py里面:
def plot_one_box(x, img, color=None, label=None, line_thickness=None):
    # Plots one bounding box on image img
    # tl = line_thickness or round(0.002 * (img.shape[0] + img.shape[1]) / 2) + 1  # line/font thickness
    # color = color or [random.randint(0, 255) for _ in range(3)]
    c1, c2 = (int(x[0]), int(x[1])), (int(x[2]), int(x[3]))
    # cv2.rectangle(img, c1, c2, color, thickness=tl, lineType=cv2.LINE_AA)
    # print(c1,c2)
    # if label:
    #     tf = max(tl - 1, 1)  # font thickness
    #     t_size = cv2.getTextSize(label, 0, fontScale=tl / 3, thickness=tf)[0]
    #     c2 = c1[0] + t_size[0], c1[1] - t_size[1] - 3
    #     cv2.rectangle(img, c1, c2, color, -1, cv2.LINE_AA)  # filled
    #     cv2.putText(img, label, (c1[0], c1[1] - 2), 0, tl / 3, [225, 255, 255], thickness=tf, lineType=cv2.LINE_AA)
    return c1,c2

第四个部分就是把这些我们需要的信息封装成为json文件,通过flask来传送他们:

part4 这里你可以改为你需要的信息:
 text = label
                    text_inf = text + ' ' + '(' + str(c1[0]) + ',' + str(c1[1]) + ')' + ' ' + '宽:' + str(c2[0]-c1[0]) + '高:' + str(c2[1]-c1[1])
                    info.append({"label":names[int(cls)],"confidences":confidences_value})
                    loc.append([c1[0], c1[1], c2[0]-c1[0], c2[1]-c1[1]])
                    lab.append(text_inf)
                # for *xyxy, conf, cls in det:
                #     if save_txt:  # 写到文件
                #         xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # 归一化 xywh
                #         with open(txt_path + '.txt', 'a') as f:
                #             f.write(('%g ' * 5 + '\n') % (cls, *xywh))  # 格式化标签
                #     if save_img or view_img:  # 把框画到图像上
                #         label = '%s %.2f' % (names[int(cls)], conf)
                #         plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
            data['data']=info
            res = jsonify(data)
            print(res)

第五部分:编写flask的代码部分:

part5 把flask的代码写好,调用yolo5的检测函数
set_upload_path = 'static/images'
set_result_path = 'static/images'
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp'])
# glo._init()
def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
app = Flask(__name__)
app.send_file_max_age_default = timedelta(seconds=1)
#URL地址
@app.route('/api/face_detection5', methods=['POST', 'GET'])
def upload():

其中调用的yolo5的检测函数被我改成了这样:
with torch.no_grad():
    lab, loc, res = yolo5.detect(o_source = upload_path)

第六部分:做成linux服务d

part6 保存个日志文件,方便调试~
PRG_KEY="yolo5"
RUN_PATH=$(cd `dirname $0`;pwd)   # Get the absolute path of the work
 
 
cd $RUN_PATH
 
case "$1" in
    start)
        nohup python3 -u $RUN_PATH/flask_yolo5.py runserver > nohup.log 2>&1 &
 
        echo "$PRG_KEY started, please check log."
 
        ;;
 
    stop)

第七部分:写个网页,用来上传图片:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传图片</title>
</head>
<body>
    <h1>上传</h1>
    <h2> yolo v5 </h2>
    <form action="" enctype='multipart/form-data' method='POST'>
	Identifier:
	<br>
	<input type="text" name="identifier" />
	<br>
        <input type="file" name="file" style="margin-top:20px;"/>
        <br>
        <input type="submit" value="上传并识别" class="button-new" style="margin-top:15px;"/>
    </form>
</body>
</html>

三、启动啊!等什么呢?

sh runServer.sh start

基本上yolo5写成api接口就是这些步骤了,https://download.youkuaiyun.com/download/Andrwin/12573384

文件已经上传了

您可能感兴趣的与本文相关的镜像

Python3.9

Python3.9

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### 如何在 Flask部署 YOLOv8 模型 为了在 Flask 应用程序中部署 YOLOv8 模型,需要完以下几个方面的配置:加载模型、处理输入数据、预测并返回结果。以下是具体的实现方法以及代码示例。 #### 加载 YOLOv8 模型 YOLOv8 提供了简单易用的接口来加载预训练模型或自定义训练的模型。可以通过 `ultralytics` 库中的 `YOLO` 类实例化模型对象[^3]。 ```python from ultralytics import YOLO # 加载 YOLOv8 模型 (可以替换为自己的权重文件路径) model = YOLO('yolov8n.pt') # 使用官方提供的小型预训练模型作为示例 ``` #### 创建 Flask 应用程序 Flask 是一个轻量级的 Python Web 框架,适合快速构建 RESTful API 或简单的 Web 应用程序。下面是一个基本的 Flask 设置: ```python from flask import Flask, request, jsonify import cv2 import numpy as np app = Flask(__name__) @app.route('/predict', methods=['POST']) def predict(): try: # 获取上传的图像文件 file = request.files['image'] image_bytes = file.read() # 将字节流转换为 OpenCV 图像格式 nparr = np.frombuffer(image_bytes, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # 调用 YOLOv8 模型进行推理 results = model(img)[0] # 解析检测结果 detections = [] for result in results.boxes.data.tolist(): # 遍历每个边界框的结果 x1, y1, x2, y2, score, class_id = result detections.append({ 'class': int(class_id), 'confidence': float(score), 'bbox': [float(x1), float(y1), float(x2), float(y2)] }) return jsonify({'detections': detections}) except Exception as e: return jsonify({'error': str(e)}), 400 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ``` #### 处理 POST 请求 上述代码片段展示了如何接收客户端发送的图片文件,并将其传递给 YOLOv8 模型进行推理。最终将以 JSON 格式返回检测到的目标及其置信度分数和位置坐标。 #### 客户端测试 可以使用 Postman 或 curl 工具向 `/predict` 接口发送带有图片的 POST 请求来进行测试。例如: ```bash curl -X POST http://localhost:5000/predict \ -F "image=@path_to_image.jpg" ``` 这会将指定路径下的图片发送至服务器,并获取目标检测结果。 --- ### 注意事项 - **性能优化**:如果计划在高并发场景下运行此服务,建议考虑使用更高效的框架(如 FastAPI),或者利用 Gunicorn 等工具扩展 Flask 的能力[^3]。 - **依赖安装**:确保已正确安装所需的库,包括 `flask`, `opencv-python`, 和 `ultralytics`. ```bash pip install flask opencv-python-headless ultralytics ``` ---
评论 29
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值