基于yolov5的火焰识别

1、准备工作

yolov5项目下载

​ 下载yolov5项目代码,其链接为:yolov5项目地址

​ 并且在PC机上配置环境,即正常按照requirements安装依赖包,而后根据自身需要下载相应的权重文件(yolov5s、yolov5m、yolov5l、yolov5x)

数据集的准备

​ 1、根据实际情况可以自身在网上爬取火焰图片

​ 2、通过网上的资料下载相关数据集,大部分数据集是无标注的数据集,此处可参考工控-小白的博客博客地址,其中就有部分火焰识别数据集的下载链接

​ 如下载的数据集无标注,那么使用lableImg进行标注,且将标注文件的保存格式设置为PascalVOC的类型,即xml格式的label文件,而后通过脚本将标签格式转换为.txt文件,并在文件上添加类别信息和对数据进行归一化。脚本脚本代码如下:

import os
import xml.etree.ElementTree as ET
from decimal import Decimaldirpath = '/home/jiu/data_change/label_0'  # 原来存放xml文件的目录
newdir = '/home/jiu/data_change/labels'  # 修改label后形成的txt目录if not os.path.exists(newdir):os.makedirs(newdir)for fp in os.listdir(dirpath):root = ET.parse(os.path.join(dirpath, fp)).getroot()xmin, ymin, xmax, ymax = 0, 0, 0, 0sz = root.find('size')width = float(sz[0].text)height = float(sz[1].text)filename = root.find('filename').textprint(fp)with open(os.path.join(newdir, fp.split('.')[0] + '.txt'), 'a+') as f:for child in root.findall('object'):  # 找到图片中的所有框sub = child.find('bndbox')  # 找到框的标注值并进行读取sub_label = child.find('name')xmin = float(sub[0].text)ymin = float(sub[1].text)xmax = float(sub[2].text)ymax = float(sub[3].text)try:  # 转换成yolov的标签格式,需要归一化到(0-1)的范围内x_center = Decimal(str(round(float((xmin + xmax) / (2 * width)),6))).quantize(Decimal('0.000000'))y_center = Decimal(str(round(float((ymin + ymax) / (2 * height)),6))).quantize(Decimal('0.000000'))w = Decimal(str(round(float((xmax - xmin) / width),6))).quantize(Decimal('0.000000'))h = Decimal(str(round(float((ymax - ymin) / height),6))).quantize(Decimal('0.000000'))print(str(x_center) + ' ' + str(y_center)+ ' '+str(w)+ ' '+str(h))#读取需要的标签if sub_label.text == 'fire':f.write(' '.join([str(0), str(x_center), str(y_center), str(w), str(h) + '\n']))except ZeroDivisionError:print(filename, '的 width有问题')

​ 此处提供本人所使用的火焰数据集,该数据集一共1421张带火焰的图片,并将其分为训练集和测试集,其中训练集1200张,测试集221张;同样的将label也分为训练集和测试集,其图片和其label相对应。

数据集下载地址:Let’s go

txt标签:

xml标签:

将下载后的zip文件解压到项目目录中

项目实现

配置文件修改

新建一个.yaml文件,在其中添加(根据实际情况修改文件路径):

train: /home/jiu/project/fire_detect/dataset/images/train  # train images 1200 images
val: /home/jiu/project/fire_detect/dataset/images/val  # val images 221 images
test:  # test images (optional)# Classes
nc: 1  # number of classes
names: [ 'fire' ]  # class names

修改train.py以及detect.py

在train.py的parse_opt()函数中,修改’–weights’、’–data’、’–imgsz’等配置,其如下所示:

def parse_opt(known=False):parser = argparse.ArgumentParser()parser.add_argument('--weights', type=str, default='yolov5s.pt', help='initial weights path')parser.add_argument('--cfg', type=str, default='', help='model.yaml path')parser.add_argument('--data', type=str, default='data/coco128.yaml', help='dataset.yaml path')parser.add_argument('--hyp', type=str, default='data/hyps/hyp.scratch.yaml', help='hyperparameters path')parser.add_argument('--epochs', type=int, default=300)parser.add_argument('--batch-size', type=int, default=8, help='total batch size for all GPUs')parser.add_argument('--img-size', nargs='+', type=int, default=[320, 320], help='[train, val] image sizes')parser.add_argument('--rect', action='store_true', help='rectangular training')parser.add_argument('--resume', nargs='?', const=True, default=False, help='resume most recent training')parser.add_argument('--nosave', action='store_true', help='only save final checkpoint')parser.add_argument('--noval', action='store_true', help='only validate final epoch')parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')parser.add_argument('--evolve', type=int, nargs='?', const=300, help='evolve hyperparameters for x generations')parser.add_argument('--bucket', type=str, default='', help='gsutil bucket')parser.add_argument('--cache-images', action='store_true', help='cache images for faster training')parser.add_argument('--image-weights', action='store_true', help='use weighted image selection for training')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--multi-scale', action='store_true', help='vary img-size +/- 50%%')parser.add_argument('--single-cls', action='store_true', help='train multi-class data as single-class')parser.add_argument('--adam', action='store_true', help='use torch.optim.Adam() optimizer')parser.add_argument('--sync-bn', action='store_true', help='use SyncBatchNorm, only available in DDP mode')parser.add_argument('--workers', type=int, default=8, help='maximum number of dataloader workers')parser.add_argument('--project', default='runs/train', help='save to project/name')parser.add_argument('--entity', default=None, help='W&B entity')parser.add_argument('--name', default='exp', help='save to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--quad', action='store_true', help='quad dataloader')parser.add_argument('--linear-lr', action='store_true', help='linear LR')parser.add_argument('--label-smoothing', type=float, default=0.0, help='Label smoothing epsilon')parser.add_argument('--upload_dataset', action='store_true', help='Upload dataset as W&B artifact table')parser.add_argument('--bbox_interval', type=int, default=-1, help='Set bounding-box image logging interval for W&B')parser.add_argument('--save_period', type=int, default=-1, help='Log model after every "save_period" epoch')parser.add_argument('--artifact_alias', type=str, default="latest", help='version of dataset artifact to be used')parser.add_argument('--local_rank', type=int, default=-1, help='DDP parameter, do not modify')opt = parser.parse_known_args()[0] if known else parser.parse_args()return opt

即’–weights’:添加yolov5的预训练权重文件,此处使用的是yolov5s.pt。如使用其他预训练权重文件,则在val.py中也应当相应修改

‘–data’:数据集的配置文件,即上面定义的.yaml文件

‘–imgsz’:输入图片的大小

在detect.py的parse_opt()函数中,同样修改’–weights’、’–source’、’–imgsz’等配置,其如下所示:

def parse_opt():parser = argparse.ArgumentParser()parser.add_argument('--weights', nargs='+', type=str,default='/home/jiu/project/fire_detect/runs/train/exp/weights/best.pt',help='model.pt path(s)')parser.add_argument('--source', type=str, default='/home/jiu/project/fire_detect/test_images/2.mp4',help='file/dir/URL/glob, 0 for webcam')parser.add_argument('--imgsz', '--img', '--img-size', type=int, default=320, help='inference size (pixels)')parser.add_argument('--conf-thres', type=float, default=0.25, help='confidence threshold')parser.add_argument('--iou-thres', type=float, default=0.45, help='NMS IoU threshold')parser.add_argument('--max-det', type=int, default=1000, help='maximum detections per image')parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')parser.add_argument('--view-img', action='store_true', help='show results')parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')parser.add_argument('--save-crop', action='store_true', help='save cropped prediction boxes')parser.add_argument('--nosave', action='store_true', help='do not save images/videos')parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')parser.add_argument('--augment', action='store_true', help='augmented inference')parser.add_argument('--visualize', action='store_true', help='visualize features')parser.add_argument('--update', action='store_true', help='update all models')parser.add_argument('--project', default='runs/detect', help='save results to project/name')parser.add_argument('--name', default='exp', help='save results to project/name')parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')parser.add_argument('--line-thickness', default=3, type=int, help='bounding box thickness (pixels)')parser.add_argument('--hide-labels', default=False, action='store_true', help='hide labels')parser.add_argument('--hide-conf', default=False, action='store_true', help='hide confidences')parser.add_argument('--half', action='store_true', help='use FP16 half-precision inference')opt = parser.parse_args()return opt

即’–weights’:添加训练好的权重文件

‘–source’:测试图片的路径或测试视频的路径

‘–imgsz’:输入图片的大小

训练过程

1、如在pycharm中运行,可直接运行train.py文件

2、如使用终端运行,则运行指令为:

python train.py --img 320 --batch 16 --epoch 300 --data data/coco128.yaml --cfg models/yolov5s.yaml --weights weights/yolov5s.pt --device '0'

实际测试

图片测试

# -*- coding: UTF-8 -*-
import time
import cv2
import torch
import copy
from models.experimental import attempt_load
from utils.datasets import letterbox
from utils.general import check_img_size, non_max_suppression, scale_coords, xyxy2xywhdef load_model(weights, device):model = attempt_load(weights, map_location=device)  # load FP32 modelreturn modeldef show_results(img, xywh, conf, class_num):h, w, c = img.shapelabels = ['fire']tl = 1 or round(0.002 * (h + w) / 2) + 1  # line/font thicknessx1 = int(xywh[0] * w - 0.5 * xywh[2] * w)y1 = int(xywh[1] * h - 0.5 * xywh[3] * h)x2 = int(xywh[0] * w + 0.5 * xywh[2] * w)y2 = int(xywh[1] * h + 0.5 * xywh[3] * h)cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), thickness=tl, lineType=cv2.LINE_AA)tf = max(tl - 1, 1)  # font thicknesslabel = str(labels[int(class_num)]) + ': ' + str(conf)[:5]cv2.putText(img, label, (x1, y1 - 2), 0, tl / 3, [0, 0, 255], thickness=tf, lineType=cv2.LINE_AA)return imgdef detect_one(model, image_path, device):# Load modelimg_size = 320conf_thres = 0.3iou_thres = 0.2orgimg = cv2.imread(image_path)  # BGR# orgimg = image_pathimg0 = copy.deepcopy(orgimg)assert orgimg is not None, 'Image Not Found ' + image_pathh0, w0 = orgimg.shape[:2]  # orig hwr = img_size / max(h0, w0)  # resize image to img_sizeif r != 1:  # always resize down, only resize up if training with augmentationinterp = cv2.INTER_AREA if r < 1  else cv2.INTER_LINEARimg0 = cv2.resize(img0, (int(w0 * r), int(h0 * r)), interpolation=interp)imgsz = check_img_size(img_size, s=model.stride.max())  # check img_sizeimg = letterbox(img0, new_shape=imgsz)[0]# Convertimg = img[:, :, ::-1].transpose(2, 0, 1).copy()  # BGR to RGB, to 3x416x416# Run inferencet0 = time.time()img = torch.from_numpy(img).to(device)img = img.float()  # uint8 to fp16/32img /= 255.0  # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inferencepred = model(img)[0]# Apply NMSpred = non_max_suppression(pred, conf_thres, iou_thres)print('pred: ', pred)print('img.shape: ', img.shape)print('orgimg.shape: ', orgimg.shape)# Process detectionsfor i, det in enumerate(pred):  # detections per imagegn = torch.tensor(orgimg.shape)[[1, 0, 1, 0]].to(device)  # normalization gain whwhif len(det):# Rescale boxes from img_size to im0 sizedet[:, :4] = scale_coords(img.shape[2:], det[:, :4], orgimg.shape).round()# Print resultsfor c in det[:, -1].unique():n = (det[:, -1] == c).sum()  # detections per classfor j in range(det.size()[0]):xywh = (xyxy2xywh(torch.tensor(det[j, :4]).view(1, 4)) / gn).view(-1).tolist()conf = det[j, 4].cpu().numpy()class_num = det[j, 4].cpu().numpy()orgimg = show_results(orgimg, xywh, conf, class_num)# Stream resultsprint(f'Done. ({time.time() - t0:.3f}s)')cv2.imshow('orgimg', orgimg)cv2.imwrite('filename.jpg',orgimg)if cv2.waitKey(0) == ord('q'):  # q to quitraise StopIterationif __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")weights = '/home/jiu/project/fire_detect/runs/train/exp/weights/best.pt'model = load_model(weights, device)# using imagesimage_path = '/home/jiu/project/fire_detect/test_images/1.jpg'detect_one(model, image_path, device)print('over')

运行结果:

视频测试

可直接使用detect.py进行测试,其效果如下所示:

yolov5火焰识别

摄像头测试:

# -*- coding: UTF-8 -*-
import time
import cv2
import torch
import copy
from models.experimental import attempt_load
from utils.datasets import letterbox
from utils.general import check_img_size, non_max_suppression, scale_coords, xyxy2xywhdef load_model(weights, device):model = attempt_load(weights, map_location=device)  # load FP32 modelreturn modeldef show_results(img, xywh, conf, class_num):h, w, c = img.shapelabels = ['fire']tl = 1 or round(0.002 * (h + w) / 2) + 1  # line/font thicknessx1 = int(xywh[0] * w - 0.5 * xywh[2] * w)y1 = int(xywh[1] * h - 0.5 * xywh[3] * h)x2 = int(xywh[0] * w + 0.5 * xywh[2] * w)y2 = int(xywh[1] * h + 0.5 * xywh[3] * h)cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), thickness=tl, lineType=cv2.LINE_AA)tf = max(tl - 1, 1)  # font thicknesslabel = str(labels[int(class_num)]) + ': ' + str(conf)[:5]cv2.putText(img, label, (x1, y1 - 2), 0, tl / 3, [0, 0, 255], thickness=tf, lineType=cv2.LINE_AA)return imgdef detect_one(model, image_path, device):# Load modelimg_size = 320conf_thres = 0.3iou_thres = 0.2orgimg = image_pathimg0 = copy.deepcopy(orgimg)assert orgimg is not None, 'Image Not Found ' + image_pathh0, w0 = orgimg.shape[:2]  # orig hwr = img_size / max(h0, w0)  # resize image to img_sizeif r != 1:  # always resize down, only resize up if training with augmentationinterp = cv2.INTER_AREA if r < 1  else cv2.INTER_LINEARimg0 = cv2.resize(img0, (int(w0 * r), int(h0 * r)), interpolation=interp)imgsz = check_img_size(img_size, s=model.stride.max())  # check img_sizeimg = letterbox(img0, new_shape=imgsz)[0]# Convertimg = img[:, :, ::-1].transpose(2, 0, 1).copy()  # BGR to RGB, to 3x416x416# Run inferencet0 = time.time()img = torch.from_numpy(img).to(device)img = img.float()  # uint8 to fp16/32img /= 255.0  # 0 - 255 to 0.0 - 1.0if img.ndimension() == 3:img = img.unsqueeze(0)# Inferencepred = model(img)[0]# Apply NMSpred = non_max_suppression(pred, conf_thres, iou_thres)print('pred: ', pred)print('img.shape: ', img.shape)print('orgimg.shape: ', orgimg.shape)# Process detectionsfor i, det in enumerate(pred):  # detections per imagegn = torch.tensor(orgimg.shape)[[1, 0, 1, 0]].to(device)  # normalization gain whwhif len(det):# Rescale boxes from img_size to im0 sizedet[:, :4] = scale_coords(img.shape[2:], det[:, :4], orgimg.shape).round()# Print resultsfor c in det[:, -1].unique():n = (det[:, -1] == c).sum()  # detections per classfor j in range(det.size()[0]):xywh = (xyxy2xywh(torch.tensor(det[j, :4]).view(1, 4)) / gn).view(-1).tolist()conf = det[j, 4].cpu().numpy()class_num = det[j, 4].cpu().numpy()orgimg = show_results(orgimg, xywh, conf, class_num)# Stream resultsprint(f'Done. ({time.time() - t0:.3f}s)')return orgimgif __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")weights = '/home/jiu/project/fire_detect/runs/train/exp/weights/best.pt'model = load_model(weights, device)# using cameracap = cv2.VideoCapture(0)while cap.isOpened():_, frame = cap.read()frame = detect_one(model, frame, device)cv2.imshow("img", frame)cv2.waitKey(1)print('over')

这个测试效果就不贴了

最后,整个项目代码下载地址: fire_detect 密码: kwu1

基于yolov5的火焰识别相关推荐

  1. 基于图像的火焰识别调研总结

    转载请注明出处https://blog.csdn.net/Hey_chaoxia/article/details/85054870 简单总结一下近期的调研结果: 一.简介 火焰的图像识别,主要围绕火焰 ...

  2. 基于FPGA的火焰识别系统开发——简化版

    基于FPGA的火焰识别系统开发的详细版欢迎订阅本博: https://blog.csdn.net/ccsss22/article/details/115406504 1.问题描述:         传 ...

  3. 火焰识别python_基于Python的火焰识别程序

    本期介绍一下笔者在试验数据处理时写的一个用于火焰识别的小程序,该小程序的功能是对拍摄到的火焰图像进行提取.增强.降噪和识别,并输出相应处理过的火焰图像以及火焰参数,如传播距离.面积等.该程序基于Pyt ...

  4. 基于yolov5的火焰+烟雾识别

    1 准备工作 下载yolov5项目代码,并在本机上配置环境:正常按照requirements安装依赖包,下载权重文件即可. 2 训练数据 2.1 创建文件目录 在data文件夹下新建数据文件fire_ ...

  5. 基于FPGA的火焰识别系统开发——详细版

    1.问题描述: 传统的森林火灾检测技术由于效率低.价格昂贵等缺点,并不适用于森林火灾探测.文中提出并设计与实现了一种基于小波变换的森林视频火灾烟雾检测方法,使用帧间差分法和质心算法提取疑似烟雾运动目标 ...

  6. Matlab 火焰识别技术

    课题介绍 森林承担着为人类提供氧气以及回收二氧化碳等废弃气体的作用,森林保护显得尤其重要.但是每年由于火灾引起的事故不计其数,造成重大的损失.如果有一款监测软件,从硬件处获得的图像中监测是否有火焰,从 ...

  7. 基于yolov3和pythorch框架的火焰识别检测算法

    这是本人第一次写博客,就当是自己实现算法的一个记录吧,有什么不好的地方也请多多指教.我会详细的从环境的配置到算法实现都说明一下,希望对大家能有帮助. 本火焰识别算法采用的是pytorch版本的yolo ...

  8. 基于yolov5+deepsort的智能售货机商品目标检测种类识别计数

    起源 智能售货机的摄像头录下用户购物的视频,并上传到服务器,服务器识别商品种类,识别拿出和放入的种类.数量.如下 最终服务器返回json数据给客户端: 第一步,训练yolov5模型 看炮哥的视频:ht ...

  9. 基于Yolov5的草莓病虫害检测识别

    项目介绍 上一篇文章介绍了基于卷积神经网络的交通标志分类识别Python交通标志识别基于卷积神经网络的保姆级教程(Tensorflow),并且最后实现了一个pyqt5的GUI界面,并且还制作了一个简单 ...

最新文章

  1. html中有csstext方法吗,style对象的cssText方法有哪些使用方法
  2. 中控考勤机的二次开发之数据秒上传至服务器功能
  3. 怎样才算熟悉python-怎样才算python入门
  4. java实现md5加密示例
  5. POST方式发起下载请求
  6. android java.lang.linkageerror_使用eclipse中的maven构建web应用出现 java.lang.LinkageError异常...
  7. matlab层次分析法代码_基于主成分分析法和层次分析法的工程项目经理胜任力评价研究...
  8. SpringBoot 之日志logback使用[简单上手版]
  9. VMware虚拟机 网桥模式详细配置(及计算机网络基本知识 IP/子网掩码/网关/DNS)
  10. 使用PS给PDF文件加水印
  11. java程序员一般用什么笔记本_程序员对笔记本电脑有什么要求吗?推荐下哪些牌子笔记本性价比高?...
  12. 云和恩墨做的是oracle,云和恩墨张中靖:立足Oracle技术,顺应去IOE大势 原创
  13. “”中国制造“”专用高速磁盘阵列存储服务器
  14. linux apache 配置文件位置,Apache主配置文件httpd.conf 详解
  15. Lawnmower(洛谷 CF115B)
  16. R语言中写SQL语句
  17. 手把手教你搭建SpringCloud项目(十六)集成Stream消息驱动
  18. Google 三架马车:GFS、BigTable、MapReduce
  19. 机器学习 第三节 第十三课
  20. 北理和国防科技计算机,“国防七子”实力真的非常强大吗?理科考生在他们之间该怎么做选择?...

热门文章

  1. [超详细高达5000字]一篇带你玩转数据分析与数据可视化
  2. 【二叉树】515. 在每个树行中找最大值
  3. 羽毛球比赛规则及场地
  4. 欧美插画系列-张聪-专题视频课程
  5. 北京市2012年职工平均月工资5223元
  6. 数学建模之出租车数目估计
  7. 软件质量测试:Jmeter察看结果树的响应数据中的中文显示乱码问题处理
  8. 平头哥面试——数字IC1
  9. AI轰鸣时代(一):苹果VS麒麟,今年的移动芯片究竟比什么?
  10. 15 个优秀开源的 Spring Boot 学习项目,一网打尽!