位置: IT常识 - 正文

爆改YOLOV7的detect.py制作成API接口供其他python程序调用(超低延时)(yolov5怎么改进)

编辑:rootadmin
爆改YOLOV7的detect.py制作成API接口供其他python程序调用(超低延时) 一、前言

推荐整理分享爆改YOLOV7的detect.py制作成API接口供其他python程序调用(超低延时)(yolov5怎么改进),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:yolo修改器,yolo v5改进,yolov5改进bifpn,yolov5魔改,yolo v5改进,yolov5改进bifpn,yolov5怎么改进,yolov5修改backbone,内容如对您有帮助,希望把文章链接给更多的朋友!

YOLO系列框架凭借其超高的运行流畅度和不俗的准确率,一直被广泛地应用到各个领域。

刚刚推出不久的YOLOV7在5 FPS到160 FPS范围内的速度和精度达到了新的高度,并在GPU V100上具有30 FPS或更高的所有已知实时目标检测器中具有最高的精度56.8%AP。YOLOv7-E6目标检测器(56 FPS V100,55.9% AP)比基于Transform的检测器SWINL Cascade-Mask R-CNN(9.2 FPS A100,53.9% AP)的速度和准确度分别高出509%和2%,以及基于卷积的检测器ConvNeXt-XL Cascade-Mask R-CNN (8.6 FPS A100, 55.2% AP) 速度提高551%,准确率提高0.7%。以及YOLOv7的表现优于:YOLOR、YOLOX、Scaled-YOLOv4、YOLOv5、DETR、Deformable DETR , DINO-5scale-R50, ViT-Adapter-B和许多其他目标检测器在速度和准确度上。

此外,研究者只在MS COCO数据集上从头开始训练YOLOv7,而不使用任何其他数据集或预训练的权重。

论文地址:https://arxiv.org/pdf/2207.02696.pdf

github地址:GitHub - WongKinYiu/yolov7: Implementation of paper - YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors

作为目标检测领域的一种框架,YOLOV7能在超低延时的情况下,还能把准确率提升一个层次,效果相当惊人。在识别过程中,将视频流中每一帧图像中的信息进行提取,获得待检测目标的识别种类、具体坐标、置信度等,这些信息可以应用到工业环境下的多个方向,比如:协助机械臂来实现精准夹取,协助无人车进行货物的运输和夹取,监控控制报警器等等,用途广泛。

二、整体制作过程1.起因

YOLOV7的原始代码argparse库进行封装,让大多数的小白凭借终端命令行可以快速地运行代码查看效果,但是只运行代码而不能获取相关的信息来进一步控制一些硬件,这样的代码是难以落地到实际使用中去的。

于是,如何将detect.py即实时检测代码制作成API是个问题。只有制作成可调用的API,使得其他python程序可以快速调用,且在识别的过程中,还能实时超低延时地获取到识别到的信息(包括:识别到的种类、目标的大致二维坐标,置信度),通过这些信息再来编写相关的硬件控制代码来控制下位机(比如:arduino、STM32等),进而实现一定的自动化控制功能。

2.爆改detect.py的大致思路

将原始代码中使用 argparse库 封装的部分删去,尝试使用面向对象编程中的类来封装;原始的detect.py中还包含很多与其核心识别功能无关的部分,包括:对识别结果的保存等,我们的目标是制作出来的 API 还能保持原来的识别流畅度,于是我只保留进行核心识别的部分。

爆改YOLOV7的detect.py制作成API接口供其他python程序调用(超低延时)(yolov5怎么改进)

原本我采用的思路通过 OpenCV 将摄像头的图像保存到某个文件夹下,再将图像导入 YOLOV7 中来实现识别,这样通过图像文件作为中介,运行时还有考虑到读取和保存图像所用的时间,尝试后发现识别相当卡顿,无法应用到实际场景。于是,我删除了原始代码中的调用摄像头的代码,在调用程序中来调用摄像头图像,以 Mat 的格式传输到 API 中,再将得到的识别信息 return 到调用函数中,大大提高了运行速率。

3.代码

保留原始框架下的大部分代码,只修改和新增几个部分,分别是:

新建一个   detect_with_API.py    文件来代替原始的    detect.py   文件

import torchfrom numpy import randomfrom models.experimental import attempt_loadfrom utils.datasets import MyLoadImagesfrom utils.general import check_img_size, non_max_suppression, apply_classifier, \ scale_coords, set_loggingfrom utils.plots import plot_one_boxfrom utils.torch_utils import select_device, load_classifierclass simulation_opt: def __init__(self, weights='models/yolov7.pt', img_size = 640, conf_thres = 0.25, iou_thres = 0.45,device='', view_img= False, classes = None, agnostic_nms = False, augment = False, update = False, exist_ok = False): self.weights = weights self.source = None self.img_size = img_size self.conf_thres = conf_thres self.iou_thres = iou_thres self.device = device self.view_img = view_img self.classes = classes self.agnostic_nms = agnostic_nms self.augment =augment self.update = update self.exist_ok = exist_okclass detectapi: def __init__(self, weights, img_size=640): self.opt = simulation_opt(weights=weights, img_size=img_size) weights, imgsz = self.opt.weights, self.opt.img_size # Initialize set_logging() self.device = select_device(self.opt.device) self.half = self.device.type != 'cpu' # half precision only supported on CUDA # Load model self.model = attempt_load(weights, map_location=self.device) # load FP32 model self.stride = int(self.model.stride.max()) # model stride self.imgsz = check_img_size(imgsz, s=self.stride) # check img_size if self.half: self.model.half() # to FP16 # Second-stage classifier self.classify = False if self.classify: self.modelc = load_classifier(name='resnet101', n=2) # initialize self.modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=self.device)['model']).to(self.device).eval() # read names and colors self.names = self.model.module.names if hasattr(self.model, 'module') else self.model.names self.colors = [[random.randint(0, 255) for _ in range(3)] for _ in self.names] def detect(self, source): # 使用时,调用这个函数 if type(source) != list: raise TypeError('source must be a list which contain pictures read by cv2') dataset = MyLoadImages(source, img_size=self.imgsz, stride=self.stride)#imgsz # 原来是通过路径加载数据集的,现在source里面就是加载好的图片,所以数据集对象的实现要 # 重写。修改代码后附。在utils.dataset.py上修改。 # Run inference if self.device.type != 'cpu': self.model(torch.zeros(1, 3, self.imgsz, self.imgsz).to(self.device).type_as(next(self.model.parameters()))) # run once #t0 = time.time() result = [] ''' for path, img, im0s, vid_cap in dataset:''' for img, im0s in dataset: img = torch.from_numpy(img).to(self.device) img = img.half() if self.half else img.float() # uint8 to fp16/32 img /= 255.0 # 0 - 255 to 0.0 - 1.0 if img.ndimension() == 3: img = img.unsqueeze(0) # Inference #t1 = time_synchronized() pred = self.model(img, augment=self.opt.augment)[0] # Apply NMS pred = non_max_suppression(pred, self.opt.conf_thres, self.opt.iou_thres, classes=self.opt.classes, agnostic=self.opt.agnostic_nms) #t2 = time_synchronized() # Apply Classifier if self.classify: pred = apply_classifier(pred, self.modelc, img, im0s) # Print time (inference + NMS) #print(f'{s}Done. ({t2 - t1:.3f}s)') # Process detections det = pred[0] # 原来的情况是要保持图片,因此多了很多关于保持路径上的处理。另外,pred # 其实是个列表。元素个数为batch_size。由于对于我这个api,每次只处理一个图片, # 所以pred中只有一个元素,直接取出来就行,不用for循环。 im0 = im0s.copy() # 这是原图片,与被传进来的图片是同地址的,需要copy一个副本,否则,原来的图片会受到影响 # s += '%gx%g ' % img.shape[2:] # print string # gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh result_txt = [] # 对于一张图片,可能有多个可被检测的目标。所以结果标签也可能有多个。 # 每被检测出一个物体,result_txt的长度就加一。result_txt中的每个元素是个列表,记录着 # 被检测物的类别引索,在图片上的位置,以及置信度 if len(det): # Rescale boxes from img_size to im0 size det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round() # Write results for *xyxy, conf, cls in reversed(det): # xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh line = (int(cls.item()), [int(_.item()) for _ in xyxy], conf.item()) # label format result_txt.append(line) label = f'{self.names[int(cls)]} {conf:.2f}' plot_one_box(xyxy, im0, label=label, color=self.colors[int(cls)], line_thickness=3) result.append((im0, result_txt)) # 对于每张图片,返回画完框的图片,以及该图片的标签列表。 return result, self.names

修改  根目录下  utils/datasets.py  文件,在 logger = logging.getLogger(__name__)  后一行加入以下代码,其他的代码保留原始的,不用删除也不用修改。

class MyLoadImages: # for inference def __init__(self, path, img_size=640, stride=32): for img in path: if type(img)!=np.ndarray or len(img.shape)!=3: raise TypeError('there is a object which is not a picture read by cv2 in source') ''' p = str(Path(path).absolute()) # os-agnostic absolute path if '*' in p: files = sorted(glob.glob(p, recursive=True)) # glob elif os.path.isdir(p): files = sorted(glob.glob(os.path.join(p, '*.*'))) # dir elif os.path.isfile(p): files = [p] # files else: raise Exception(f'ERROR: {p} does not exist') images = [x for x in files if x.split('.')[-1].lower() in img_formats] videos = [x for x in files if x.split('.')[-1].lower() in vid_formats] ni, nv = len(images), len(videos) ''' self.img_size = img_size self.stride = stride self.files = path self.nf = len(path) #self.video_flag = [False] * ni + [True] * nv self.mode = 'image' #if any(videos): #self.new_video(videos[0]) # new video #else: #self.cap = None #assert self.nf > 0, f'No images or videos found in {p}. ' \ #f'Supported formats are:\nimages: {img_formats}\nvideos: {vid_formats}' def __iter__(self): self.count = 0 return self def __next__(self): if self.count == self.nf: raise StopIteration path = self.files[self.count] ''' if self.video_flag[self.count]: # Read video self.mode = 'video' ret_val, img0 = self.cap.read() if not ret_val: self.count += 1 self.cap.release() if self.count == self.nf: # last video raise StopIteration else: path = self.files[self.count] self.new_video(path) ret_val, img0 = self.cap.read() self.frame += 1 print(f'video {self.count + 1}/{self.nf} ({self.frame}/{self.nframes}) {path}: ', end='') ''' # Read image self.count += 1 #img0 = cv2.imread(path) # BGR #assert img0 is not None, 'Image Not Found ' + path #print(f'image {self.count}/{self.nf} {path}: ', end='') # Padded resize img = letterbox(path, self.img_size, stride=self.stride)[0] # Convert img = img[:, :, ::-1].transpose(2, 0, 1) # BGR to RGB, to 3x416x416 img = np.ascontiguousarray(img) return img, path

新建一个   demo_run_API.py   文件,对   detect_with_API.py   中的  API  进行调用

import cv2import detect_with_APIimport torchcap=cv2.VideoCapture('http://admin:admin@192.168.1.109:8081')# 0a = detect_with_API.detectapi(weights='models/yolov7.pt')if __name__ == '__main__': with torch.no_grad(): while True: rec,img = cap.read() result,names = a.detect([img]) img=result[0][0] #每一帧图片的处理结果图片 # 每一帧图像的识别结果(可包含多个物体) for cls,(x1,y1,x2,y2),conf in result[0][1]: print(names[cls],x1,y1,x2,y2,conf)#识别物体种类、左上角x坐标、左上角y轴坐标、右下角x轴坐标、右下角y轴坐标,置信度 ''' cv2.rectangle(img,(x1,y1),(x2,y2),(0,255,0)) cv2.putText(img,names[cls],(x1,y1-20),cv2.FONT_HERSHEY_DUPLEX,1.5,(255,0,0))''' print()#将每一帧的结果输出分开 cv2.imshow("vedio",img) if cv2.waitKey(1)==ord('q'): break三、效果演示

我这里使用的是网络摄像头,你也可以用 USB 的接口摄像头或者电脑自带的摄像头。

配置好环境,摄像头后,运行  demo_run_API.py ,得:

 我的整体项目框架如下,有需要的自取:

YOLOV7_with_API.7z-深度学习文档类资源-CSDN下载

若你用自己的数据集来定制化地训练自己的识别模型,可以参考:

YOLOV5训练自己的无人车避坑(障)系统_Leonard2021的博客-CSDN博客_yolo训练

YOLOV7的训练的函数是没有修改的,训练完成后,在我制作API中调用你自己训练的模型即可。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~如果本文对你有帮助,欢迎一键三连!
本文链接地址:https://www.jiuchutong.com/zhishi/293038.html 转载请保留说明!

上一篇:微信小程序web-view与H5 通信方式探索(微信小程序web-view 添加悬浮按钮)

下一篇:锡特卡的港口,阿拉斯加 (© Blaine Harrington III/Alamy)(锡特f8)

  • 钉钉学生号忘了怎么办(钉钉学生号忘记了)

    钉钉学生号忘了怎么办(钉钉学生号忘记了)

  • 腾讯课堂怎么关闭麦克风权限(腾讯课堂怎么关闭麦克风和摄像头)

    腾讯课堂怎么关闭麦克风权限(腾讯课堂怎么关闭麦克风和摄像头)

  • qq群课堂是否有上课记录(qq群课堂有什么用)

    qq群课堂是否有上课记录(qq群课堂有什么用)

  • 小米音量图标不消失(小米音量显示图标显示在右边,怎么关掉)

    小米音量图标不消失(小米音量显示图标显示在右边,怎么关掉)

  • 苹果11商店下载不了软件(苹果11商店下载app需要验证查看账单)

    苹果11商店下载不了软件(苹果11商店下载app需要验证查看账单)

  • sai2和sai1有什么区别(sai1和sai2区别)

    sai2和sai1有什么区别(sai1和sai2区别)

  • 哈罗单车忘记锁了怎么办(哈罗单车忘记锁了怎么关)

    哈罗单车忘记锁了怎么办(哈罗单车忘记锁了怎么关)

  • 换机微信记录如何导入(手机微信记录换手机怎么导)

    换机微信记录如何导入(手机微信记录换手机怎么导)

  • 抖音权重3是什么意思(抖音权重3是高还是低)

    抖音权重3是什么意思(抖音权重3是高还是低)

  • 华为Nova5怎样设置呼叫转移(华为nova5怎样设置锁屏图片)

    华为Nova5怎样设置呼叫转移(华为nova5怎样设置锁屏图片)

  • 为什么电脑连网显示无internet(为什么电脑连网老是断开?)

    为什么电脑连网显示无internet(为什么电脑连网老是断开?)

  • 微信连麦闹钟会响么(微信连麦闹钟会吵到对方吗)

    微信连麦闹钟会响么(微信连麦闹钟会吵到对方吗)

  • 荣耀30有液冷散热吗(荣耀30是液态散热吗)

    荣耀30有液冷散热吗(荣耀30是液态散热吗)

  • 抖音关注别人对方会知道吗(抖音关注别人对方不回关)

    抖音关注别人对方会知道吗(抖音关注别人对方不回关)

  • 苹果11锁屏声音有时大有时小(苹果11锁屏声音忽大忽小)

    苹果11锁屏声音有时大有时小(苹果11锁屏声音忽大忽小)

  • 小米投影仪青春版不能手动调屏幕大小吗(小米投影仪青春版2怎么用手机遥控)

    小米投影仪青春版不能手动调屏幕大小吗(小米投影仪青春版2怎么用手机遥控)

  • i5 650配什么主板(i5650配什么主板)

    i5 650配什么主板(i5650配什么主板)

  • Apple Watch S5支持防水吗(Apple Watch s5支持无线充电吗)

    Apple Watch S5支持防水吗(Apple Watch s5支持无线充电吗)

  • b站可以拒收陌生人的消息吗(b站可以拒收私信吗)

    b站可以拒收陌生人的消息吗(b站可以拒收私信吗)

  • 苹果手机怎么设置拍照有时间水印(苹果手机怎么设置手写)

    苹果手机怎么设置拍照有时间水印(苹果手机怎么设置手写)

  • 收藏的图片在哪里找(收藏的图片在哪里找出来)

    收藏的图片在哪里找(收藏的图片在哪里找出来)

  • 小米arcore怎么用(小米手机ar如何使用)

    小米arcore怎么用(小米手机ar如何使用)

  • opporenoz用的是什么处理器(opporenoz用的是什么中框)

    opporenoz用的是什么处理器(opporenoz用的是什么中框)

  • 苹果x有几款型号(苹果x系列有几款型号)

    苹果x有几款型号(苹果x系列有几款型号)

  • 快手作品违规怎么办(快手作品违规怎么申请解封)

    快手作品违规怎么办(快手作品违规怎么申请解封)

  • 企业微信一周小结是什么意思(企业微信一周小结评语哪来的)

    企业微信一周小结是什么意思(企业微信一周小结评语哪来的)

  • 电脑美式键盘调出来教程(电脑美式键盘怎么设置)

    电脑美式键盘调出来教程(电脑美式键盘怎么设置)

  • 路由器重启后电脑无法联网怎么办(路由器重启后电视放不出来咋办)

    路由器重启后电脑无法联网怎么办(路由器重启后电视放不出来咋办)

  • 怎样理解一般纳税人
  • 个人所得税一般多久能退下来
  • 小规模纳税人可以收专票吗
  • 什么是原始凭证?审核原始凭证主要审查哪些内容?
  • 买新车时旧车置换新车划算吗
  • 过路费报销属于什么费用科目
  • 个人所得税怎么扣
  • 进项多少就开多少的票吗
  • 合伙企业季度所得税预缴不用纳税调整是吗
  • 机械设备关税税率多少
  • 客运地方税务局监制发票还能用吗?
  • 注销税务注意事项
  • 善意接受虚开发票只能自认倒霉么
  • 没有发票如何报账
  • 应收留抵税额退税款科目怎么添加进项
  • 企业购入投资性房地产时借记什么科目
  • 付垫资款给其他公司应该怎么做账?
  • 设备免费提供给客户使用
  • 会计账簿的定义及其作用
  • 地税开发票为啥要交百分之二的企业所得税?
  • 看看大家退休的单子
  • 公司注销留抵税金能退税吗
  • 出差人什么意思
  • 转账银行汇票遗失后可以申请办理
  • 增值税进项税额抵扣期限最新
  • 促销礼物
  • ms-dos 6.0
  • ajax不刷新页面
  • 爱荷华州的首府
  • 企业发放职工薪酬的账务处理例子
  • 进程中svchost
  • 作废的凭证不能恢复吗
  • 员工辞退补偿金扣个税吗
  • 温哥华瀑布
  • javaweb知识点汇总
  • diff比较文件不同输出
  • 进口付汇操作
  • 广告系统源码
  • 用于职工福利的进项税账务处理
  • 企业收取的罚款需要交企业所得税吗
  • 物品登记制度
  • 分页存储的优缺点
  • 加计扣除的增值税怎么做账
  • 家电销售的税率
  • 民宿的房屋租赁费怎么算
  • 股权收购协议书实际案例
  • 进项税额转出期限是多久
  • 保险费用缴纳
  • 去年少交的增值税可以和今年的合并吗
  • 短期借款怎么做账务处理
  • 企业最应避免的外部环境和内部条件组合是
  • 社保调低,上半年多缴的怎么办
  • 应记入营业外支出的科目核算是
  • 预提工资如何算增值税
  • 外资企业对应的企业是什么
  • 小额零星支出是什么意思
  • 分公司需要独立核算和报税吗
  • sql server dbcc
  • sqlserver升级到2016
  • 打印机向windows发送消息
  • win7用u盘怎么重装系统
  • 电脑输入systeminfo
  • linux系统ln命令
  • subss
  • 怎么知道游戏是什么引擎
  • 联想电脑win7系统开机修改开机密码
  • cocos2dx drawcall优化
  • opengl用法
  • 用一个简单的方法作文
  • [置顶]JM259194
  • jquery选择器实例
  • js读取cookies
  • jquery中绑定和解绑的事件有哪些
  • node.js的express
  • jQuery插件下载
  • python源码分析工具
  • js能写贪吃蛇游戏是什么水平
  • wordpress基于什么语言
  • 广东省国家税务局电子发票系统,网络设置
  • 白酒消费税加征
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设