这个小项目是基于flask微型目标检测服务。使用的是YOLOv3版本,使用的是在coco数据集上已经训练好的参数。整个目录结构如下(我运行的环境是window10,pycharm):

其中:

  1. cfg是YOLOv3的配置文件,包括权重,网络结构和coco数据集的标签;
  2. static是通过网络访问该服务时被保存的图片;
  3. templates是网页UI的代码;
  4. flask_yolo.py是启动该服务的入口;
  5. testYoloSer.py是测试该服务的接口代码;
  6. yolomain.py是YOLOv3的实现代码;

项目下载地址:https://download.csdn.net/download/qq_31112205/11795537

需要注意的是,由于上传大小的限制只能上传小于220M的文件,而该目录中yolov3_coco.weights就有230多M。如果想运行你需要下载该文件,当然你用积分下载该项目后不想自己找,也可以在下面评论留言,我可以发给你。

其中,主要文件的代码如下:

flask_yolo.py

# -*- coding: utf-8 -*-#
# Author:       weiz
# Date:         2019/9/16 14:12
# Name:         flask_yolo
# Description: 一个可以在浏览器使用YOLO目标检测的函数,和一个可以通过网络访问的YOLO目标检测的接口
#              直接运行就可以在浏览器上面输入带检测图片,并返回检测的结果;同时,可以接受通过局域网
#              访问该接口的服务。from flask import Flask, render_template, request, jsonify, make_response
from werkzeug.utils import secure_filename
import os
import cv2
import time
import json
from PIL import Image
from io import BytesIO
import json
import numpy as npfrom datetime import timedelta
import yolomain# 设置允许的文件格式
ALLOWED_EXTENSIONS = set(['png', 'jpg', 'JPG', 'PNG', 'bmp'])def allowed_file(filename):return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONSapp = Flask(__name__)
# 设置静态文件缓存过期时间
app.send_file_max_age_default = timedelta(seconds=1)# @app.route('/upload', methods=['POST', 'GET'])
@app.route('/upload', methods=['POST', 'GET'])  # 添加路由
def upload():if request.method == 'POST':f = request.files['file']if not (f and allowed_file(f.filename)):return jsonify({"error": 1001, "msg": "请检查上传的图片类型,仅限于png、PNG、jpg、JPG、bmp"})user_input = request.form.get("name")# 当前文件所在路径basepath = os.path.dirname(__file__)# 注意:没有的文件夹一定要先创建,不然会提示没有该路径upload_path = os.path.join(basepath, 'static/images', secure_filename(f.filename))f.save(upload_path)lab, img, loc = yolomain.yolo_detect(pathIn=upload_path)cv2.imwrite(os.path.join(basepath, 'static/images', 'test.jpg'), img)return render_template('upload_ok.html', userinput=user_input, val1=time.time(), data_dict=lab)return render_template('upload.html')@app.route('/yolo_service',methods=['POST'])
def detection():img = request.stream.read()f = BytesIO(img)image = Image.open(f)image = np.array(image, dtype='float32')boxes, lab = yolomain.yolo_ser(image)rsp = make_response(json.dumps(lab))rsp.mimetype = 'application/json'rsp.headers['Connection'] = 'close'return rspif __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

testYoloSer.py

# -*- coding: utf-8 -*-#
# Author:       weiz
# Date:         2019/9/16 17:05
# Name:         test_yolo
# Description: 测试YOLOweb服务是否可以使用的代码(请先运行flask_yolo.py)import requests
import os
import json
if __name__ == '__main__':# 注意填写自己电脑的IP地址url = 'http://192.168.124.19:5000/yolo_service'headers = {'Content-Type': 'image/jpeg'}file = {'media': open('./static/images/test.jpg', 'rb')}requests.post(url, files=file)data = open('./static/images/test.jpg', 'rb').read()r = requests.post(url, data=data, headers=headers, verify=False)print("类别:置信度 (左上角X坐标,左上角Y坐标) (目标的宽, 目标的高)")print(r.text)

yolomain.py

# -*- coding: utf-8 -*-
# Author:       weiz
# Date:         2019/9/16 17:00
# Name:         test_yolo
# Description:  YOLOv3目标检测的代码,提供检测的接口;也可以单独运行。
# 载入所需库
import cv2
import numpy as np
import os
import timedef yolo_detect(im=None,pathIn=None,label_path='./cfg/coco.names',config_path='./cfg/yolov3_coco.cfg',weights_path='./cfg/yolov3_coco.weights',confidence_thre=0.5,nms_thre=0.3):'''im:原始图片pathIn:原始图片的路径label_path:类别标签文件的路径config_path:模型配置文件的路径weights_path:模型权重文件的路径confidence_thre:0-1,置信度(概率/打分)阈值,即保留概率大于这个值的边界框,默认为0.5nms_thre:非极大值抑制的阈值,默认为0.3'''# 加载类别标签文件LABELS = open(label_path).read().strip().split("\n")nclass = len(LABELS)# 为每个类别的边界框随机匹配相应颜色np.random.seed(42)COLORS = np.random.randint(0, 255, size=(nclass, 3), dtype='uint8')# 载入图片并获取其维度#base_path = os.path.basename(pathIn)if pathIn == None:img = imelse:img = cv2.imread(pathIn)(H, W) = img.shape[:2]net = cv2.dnn.readNetFromDarknet(config_path, weights_path)# 获取YOLO输出层的名字ln = net.getLayerNames()ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]# 将图片构建成一个blob,设置图片尺寸,然后执行一次# YOLO前馈网络计算,最终获取边界框和相应概率blob = cv2.dnn.blobFromImage(img, 1 / 255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)start = time.time()layerOutputs = net.forward(ln)end = time.time()# 初始化边界框,置信度(概率)以及类别boxes = []confidences = []classIDs = []# 迭代每个输出层,总共三个for output in layerOutputs:# 迭代每个检测for detection in output:# 提取类别ID和置信度scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]# 只保留置信度大于某值的边界框if confidence > confidence_thre:# 将边界框的坐标还原至与原图片相匹配,记住YOLO返回的是# 边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")# 计算边界框的左上角位置x = int(centerX - (width / 2))y = int(centerY - (height / 2))# 更新边界框,置信度(概率)以及类别boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)# 使用非极大值抑制方法抑制弱、重叠边界框idxs = cv2.dnn.NMSBoxes(boxes, confidences, confidence_thre, nms_thre)lab = []loc = []# 确保至少一个边界框if len(idxs) > 0:# 迭代每个边界框for i in idxs.flatten():# 提取边界框的坐标(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])# 绘制边界框以及在左上角添加类别标签和置信度color = [int(c) for c in COLORS[classIDs[i]]]cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)text = '{}: {:.3f}'.format(LABELS[classIDs[i]], confidences[i])(text_w, text_h), baseline = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)cv2.rectangle(img, (x, y-text_h-baseline), (x + text_w, y), color, -1)cv2.putText(img, text, (x, y-5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)text_inf = text + ' ' + '(' + str(x) + ',' + str(y) + ')' + ' ' + '宽:' + str(w) + '高:' + str(h)loc.append([x, y, w, h])lab.append(text_inf)return lab, img, locdef yolo_ser(im,label_path='./cfg/coco.names',config_path='./cfg/yolov3_coco.cfg',weights_path='./cfg/yolov3_coco.weights',confidence_thre=0.5,nms_thre=0.3):'''im:原始图片label_path:类别标签文件的路径config_path:模型配置文件的路径weights_path:模型权重文件的路径confidence_thre:0-1,置信度(概率/打分)阈值,即保留概率大于这个值的边界框,默认为0.5nms_thre:非极大值抑制的阈值,默认为0.3'''LABELS = open(label_path).read().strip().split("\n")nclass = len(LABELS)np.random.seed(42)COLORS = np.random.randint(0, 255, size=(nclass, 3), dtype='uint8')img = im(H, W) = img.shape[:2]net = cv2.dnn.readNetFromDarknet(config_path, weights_path)# 获取YOLO输出层的名字ln = net.getLayerNames()ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]# 将图片构建成一个blob,设置图片尺寸,然后执行一次# YOLO前馈网络计算,最终获取边界框和相应概率blob = cv2.dnn.blobFromImage(img, 1 / 255.0, (416, 416), swapRB=True, crop=False)net.setInput(blob)start = time.time()layerOutputs = net.forward(ln)end = time.time()# 初始化边界框,置信度(概率)以及类别boxes = []confidences = []classIDs = []# 迭代每个输出层,总共三个for output in layerOutputs:# 迭代每个检测for detection in output:# 提取类别ID和置信度scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]# 只保留置信度大于某值的边界框if confidence > confidence_thre:# 将边界框的坐标还原至与原图片相匹配,记住YOLO返回的是# 边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")# 计算边界框的左上角位置x = int(centerX - (width / 2))y = int(centerY - (height / 2))# 更新边界框,置信度(概率)以及类别boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)# 使用非极大值抑制方法抑制弱、重叠边界框idxs = cv2.dnn.NMSBoxes(boxes, confidences, confidence_thre, nms_thre)lab_cfd = []lab = []loc = []# 确保至少一个边界框if len(idxs) > 0:# 迭代每个边界框for i in idxs.flatten():# 提取边界框的坐标(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])# 绘制边界框以及在左上角添加类别标签和置信度color = [int(c) for c in COLORS[classIDs[i]]]cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)text = '{}: {:.3f}'.format(LABELS[classIDs[i]], confidences[i])(text_w, text_h), baseline = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, 0.5, 2)cv2.rectangle(img, (x, y - text_h - baseline), (x + text_w, y), color, -1)cv2.putText(img, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)text_inf = text + ' ' + '(' + str(x) + ',' + str(y) + ')' + ' ' + '(' + str(w) + ',' + str(h) + ')'loc.append([x, y, w, h])lab.append(text_inf)return loc, labif __name__ == '__main__':pathIn = './static/images/test1.jpg'im = cv2.imread('./static/images/test2.jpg')lab, img, loc = yolo_detect(pathIn=pathIn)print(lab)# cv2.imshow("ret", img)# cv2.waitKey(0)

web端展示(注意地址的输入):

接口端效果展示:

上面的项目不能部署到Linux系统上。下面的代码是可以让上面的项目快速部署成功。

文件名是runServer.sh

#!/usr/bin/env bash
export LANG=zh_CN.UTF-8PRG_KEY="FWebYolo"
RUN_PATH=$(cd `dirname $0`;pwd)   # Get the absolute path of the workcd $RUN_PATHcase "$1" instart)nohup python3 -u $RUN_PATH/flask_yolo1.py runserver > nohup.log 2>&1 &echo "$PRG_KEY started, please check log.";;stop)pid=$(pgrep -f $PRG_KEY)echo "$pid"kill -9 $pid##killall python3echo "$PRG_KEY stoped!";;restart)$0 stopsleep 1$0 start;;*)echo "Usage: $0 {start|stop|restart}"exit 1
esacexit 0

开启服务的命令:

开启服务:sh runServer.sh start
关闭服务:sh runServer.sh stop
查看进程:ps ef|grep FWebYolo1

基于flask的YOLO目标检测web服务及接口相关推荐

  1. 目标检测实战必会!4种基于YOLO目标检测(Python和C++两种版本实现)

    目标检测实战必会!4种基于YOLO目标检测(Python和C++两种版本实现) AI算法修炼营 1周前 以下文章来源于极市平台 ,作者CV开发者都爱看的 极市平台 专注计算机视觉前沿资讯和技术干货,官 ...

  2. 目标检测实战:4种YOLO目标检测的C++和Python两种版本实现

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨nihate 审稿丨邓富城 编辑丨极市平台 导读 本文作者使用C++编写一套基于OpenCV的Y ...

  3. 【深度学习】目标检测实战:4种YOLO目标检测的C++和Python两种版本实现

    作者丨nihate 审稿丨邓富城 编辑丨极市平台 导读 本文作者使用C++编写一套基于OpenCV的YOLO目标检测,包含了经典的YOLOv3,YOLOv4,Yolo-Fastest和YOLObile ...

  4. 项目设计:基于YOLO目标检测算法的安全帽/口罩/汽车/行人/交通标志...检测

    本文将详细介绍YOLO目标检测算法,该算法支持各种目标检测,包括:安全帽.汽车.造价.交通标志......等.  其他毕业设计题目推荐参考: 毕业设计:电子/通信/计算机/物联网专业毕业设计选题参考( ...

  5. 基于YOLO目标检测及OpenCV实现的游戏代玩人工智能体(Auto Gaming Agent) [4]

    大型生存类游戏自动代玩人工智能[4] -- 自动控制 一.键鼠自动操作 1. 操作游戏角色 2. 瞄准目标 二.自动采集 1. OCR文字识别 2. 多线程运行 一.键鼠自动操作 一般电脑上的游戏操作 ...

  6. 基于深度学习的YOLO目标检测研究-附Matlab代码

    目录 ✳️ 一.引言 ✳️ 二.YOLO的基本思想 ✳️ 三.实验验证 ✳️ 四.参考文献 ✳️ 五.Matlab代码获取 ✳️ 一.引言 目标检测是计算机视觉中的一个研究热点,在很多领域都有应用需求 ...

  7. 致敬YOLO!华科提出YOLOS:基于视觉Transformer的目标检测

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 导读 本文是华科&地平线关于Transformer的迁移学习.泛化性能方面的深度思考.重点揭示 ...

  8. 目标检测YOLO实战应用案例100讲-基于YOLOv4的SAR目标检测方法应用(论文篇)

    目录 基于改进YOLOv4的SAR目标检测方法研究 传统的目标检测方法 基于深度学习的目标检测方法

  9. 病虫害模型算法_基于深度学习的目标检测算法综述

    sigai 基于深度学习的目标检测算法综述 导言 目标检测的任务是找出图像中所有感兴趣的目标(物体),确定它们的位置和大小,是机器视觉领域的核心问题之一.由于各类物体有不同的外观,形状,姿态,加上成像 ...

最新文章

  1. Python 基础教程(第2版) 中文版+英文原版下载
  2. 机器学习:SVM训练,SMO算法描述,启发式选择样本或变量
  3. 一个由于Pricing RFC引起的UI超时问题
  4. php 垃圾回收机制----写时复制和引用计数
  5. Qt-qwidget项目入门实例
  6. linux tomcat php配置文件在哪个文件夹下,tomcat下,怎么安配备置php ?(linux系统)
  7. 苹果“炸场”发布会:搭载刘海屏的MacBook Pro来了,还有AirPods 3...
  8. 数据结构 5排序算法
  9. NXP JN5169 USB Dongle 原理图
  10. 微分方程模型_MIT—微分方程笔记03 一阶线性常微分方程解法
  11. 碎片化时间学习,这几个在线视频学习网站值得拥有!
  12. js字段名下划线命名转驼峰,驼峰转下划线
  13. leetcode学习打卡--572. 另一个树的子树(递归,二叉树遍历)
  14. 葫芦娃各平台以及微信hook分析汇总
  15. 自动控制理论的发展历程
  16. 嵌入式Linux工程师发展前景 嵌入式工程师待遇怎样?
  17. 实现简单的自定义音乐播放器
  18. PAT-1032 挖掘机技术哪家强
  19. AD学习笔记(四)PCB布局分析
  20. 高德 java.lang.UnsatisfiedLinkError: Native method not found: com.autonavi.amap.mapc

热门文章

  1. 各种编码中字母和汉字分别占多少字节
  2. Win10电脑开机PIN码怎么取消?
  3. 使用Ajax动态的显示时间
  4. 训练数据集的时候GPU老是lost
  5. centos7配置静态网络
  6. iOS多语言解决方案全面指南
  7. 数字财税解决方案-制造业数字化探讨(5)
  8. 广东省东莞市电信机房
  9. idea项目启动时刷新_[转]springboot+idea热部署(自动刷新)
  10. 车道线数据集详细介绍以及使用方法汇总——CULane Datasets、Tusimple、LLAMAS、ApolloScape(后续会持续更新)