位置: IT常识 - 正文

YOLOv5实战之输电线路绝缘子缺陷检测识别(yolov5 output)

编辑:rootadmin
YOLOv5实战之输电线路绝缘子缺陷检测识别

推荐整理分享YOLOv5实战之输电线路绝缘子缺陷检测识别(yolov5 output),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:yolov5tiny,yolov3输出是什么,yolov5tiny,yolov1输出,yolov5 output,yolov1输出,yolov5 原理,yolov5 output,内容如对您有帮助,希望把文章链接给更多的朋友!

在前面的文章中已经详细介绍了在本机上安装YOLOv5的教程,安装YOLOv5可参考前面的文章YOLOv5训练自己的数据集(超详细)https://blog.csdn.net/qq_40716944/article/details/118188085https://blog.csdn.net/qq_40716944/article/details/118188085

目录

一、数据集介绍

二、构建训练数据集 

1、先构建数据集文件夹

2、数据集格式转换

3、训练集划分代码

4、生成yolo格式的标签

三、修改配置文件

1、数据配置文件

2、网络参数修改

3、trian.py修改

四、训练及测试

1、训练

 2、测试


一、数据集介绍

        本教程主要是利用YOLOv5算法实现对输电线路绝缘子缺陷进行检测识别。通过无人机搭载相机头云台对输电线路上的绝缘子进行数据采集,挑选出绝缘子上有故障的图片数据,共2000张左右图片,输电线路绝缘子缺陷数据集中的部分图片如下图所示。

​对收集到的2000张左右绝缘子缺陷数据集进行数据标注, 标注了3种常见的绝缘子缺陷类型:insulator、damaged、Flashover,利用LabelImg标注软件对数据进行标注,对标注后的数据进行统计,3种缺陷的标签分布情况如下图所示。

二、构建训练数据集 1、先构建数据集文件夹

        本人按照VOC格式创建数据集,具体格式如下:

├── data│ ├── xml 进行 detection 任务时的标签文件,xml 形式,文件名与图片名一一对应│ ├── images 存放.jpg 格式的图片文件│ ├── labels 存放label标注信息的txt文件,与图片一一对应│ ├── txt 存放原始标注信息,x1,y1,x2,y2,type├── dataSet(train,val,test建议按照8:1:1比例划分)│ ├── train.txt 写着用于训练的图片名称│ ├── val.txt 写着用于验证的图片名称│ ├── trainval.txt train与val的合集│ ├── test.txt 写着用于测试的图片名称2、数据集格式转换

        原始的标注信息是保存成txt文件,txt文件里面的每一行都包含一个标注信息,格式为x1,y1,x2,y2,type,这里 (x1,y1) 和 (x2,y2) 是缺陷边界框的左上角和右下角,type是匹配后的整数 ID:0:insulator、1:damaged、2:Flashover。通过一下代码进行转换:

import osimport cv2import timefrom xml.dom import minidomname_dict = {'0': 'insulator', '1': 'damaged', '2': 'Flashover'}def transfer_to_xml(pic, txt, file_name,xml_save_path): if not os.path.exists(xml_save_path): os.makedirs(xml_save_path,exist_ok=True) img = cv2.imread(pic) img_w = img.shape[1] img_h = img.shape[0] img_d = img.shape[2] doc = minidom.Document() annotation = doc.createElement("annotation") doc.appendChild(annotation) folder = doc.createElement('folder') folder.appendChild(doc.createTextNode('visdrone')) annotation.appendChild(folder) filename = doc.createElement('filename') filename.appendChild(doc.createTextNode(file_name)) annotation.appendChild(filename) source = doc.createElement('source') database = doc.createElement('database') database.appendChild(doc.createTextNode("Unknown")) source.appendChild(database) annotation.appendChild(source) size = doc.createElement('size') width = doc.createElement('width') width.appendChild(doc.createTextNode(str(img_w))) size.appendChild(width) height = doc.createElement('height') height.appendChild(doc.createTextNode(str(img_h))) size.appendChild(height) depth = doc.createElement('depth') depth.appendChild(doc.createTextNode(str(img_d))) size.appendChild(depth) annotation.appendChild(size) segmented = doc.createElement('segmented') segmented.appendChild(doc.createTextNode("0")) annotation.appendChild(segmented) with open(txt, 'r') as f: lines = [f.readlines()] for line in lines: for boxes in line: box = boxes.strip('\n') box = box.split(" ") x_min = box[0] y_min = box[1] x_max = box[2] y_max = box[3] object_name = name_dict[box[4]] if object_name != "background": object = doc.createElement('object') nm = doc.createElement('name') nm.appendChild(doc.createTextNode(object_name)) object.appendChild(nm) pose = doc.createElement('pose') pose.appendChild(doc.createTextNode("Unspecified")) object.appendChild(pose) truncated = doc.createElement('truncated') truncated.appendChild(doc.createTextNode("1")) object.appendChild(truncated) difficult = doc.createElement('difficult') difficult.appendChild(doc.createTextNode("0")) object.appendChild(difficult) bndbox = doc.createElement('bndbox') xmin = doc.createElement('xmin') xmin.appendChild(doc.createTextNode(x_min)) bndbox.appendChild(xmin) ymin = doc.createElement('ymin') ymin.appendChild(doc.createTextNode(y_min)) bndbox.appendChild(ymin) xmax = doc.createElement('xmax') xmax.appendChild(doc.createTextNode(str(x_max))) bndbox.appendChild(xmax) ymax = doc.createElement('ymax') ymax.appendChild(doc.createTextNode(str(y_max))) bndbox.appendChild(ymax) object.appendChild(bndbox) annotation.appendChild(object) with open(os.path.join(xml_save_path, file_name + '.xml'), 'w') as x: x.write(doc.toprettyxml()) x.close() f.close()if __name__ == '__main__': t = time.time() print('Transfer .txt to .xml...ing....') txt_folder = 'data/power_transmission_line_datasets/txt' txt_file = os.listdir(txt_folder) img_folder = 'data/power_transmission_line_datasets/image' xml_save_path = 'data/power_transmission_line_datasets/xml/' for txt in txt_file: txt_full_path = os.path.join(txt_folder, txt) img_full_path = os.path.join(img_folder, txt.split('.')[0] + '.jpg') try: transfer_to_xml(img_full_path, txt_full_path, txt.split('.')[0],xml_save_path) except Exception as e: print(e) print("Transfer .txt to .XML sucessed. costed: {:.3f}s...".format(time.time() - t))3、训练集划分代码

        主要是将数据集分类成训练数据集和测试数据集,默认train,val,test按照比例进行随机分类,运行后dataSet文件夹中会出现四个文件,主要是生成的训练数据集和测试数据集的图片名称,如下图。同时data目录下也会出现这四个文件,内容是训练数据集和测试数据集的图片路径。

import osimport randomtrainval_percent = 0.9train_percent = 0.9xmlfilepath = 'data/power_transmission_line_datasets/xml/'txtsavepath = 'data/power_transmission_line_datasets/dataSet/'total_xml = os.listdir(xmlfilepath)num = len(total_xml)list = range(num)tv = int(num * trainval_percent)tr = int(tv * train_percent)trainval = random.sample(list, tv)train = random.sample(trainval, tr)ftrainval = open('data/power_transmission_line_datasets/dataSet/trainval.txt', 'w')ftest = open('data/power_transmission_line_datasets/dataSet/test.txt', 'w')ftrain = open('data/power_transmission_line_datasets/dataSet/train.txt', 'w')fval = open('data/power_transmission_line_datasets/dataSet/val.txt', 'w')for i in list: name = total_xml[i][:-4] + '\n' if i in trainval: ftrainval.write(name) if i in train: ftrain.write(name) else: fval.write(name) else: ftest.write(name)ftrainval.close()ftrain.close()fval.close()ftest.close()4、生成yolo格式的标签YOLOv5实战之输电线路绝缘子缺陷检测识别(yolov5 output)

        主要是将图片数据集标注后的xml文件中的标注信息读取出来并写入txt文件,运行后在label文件夹中出现所有图片数据集的标注信息。

# xml解析包import xml.etree.ElementTree as ETimport pickleimport os# os.listdir() 方法用于返回指定的文件夹包含的文件或文件夹的名字的列表from os import listdir, getcwdfrom os.path import joinsets = ['train', 'test', 'val']classes = ["insulator","damaged","Flashover"]# 进行归一化操作def convert(size, box): # size:(原图w,原图h) , box:(xmin,xmax,ymin,ymax) dw = 1./size[0] # 1/w dh = 1./size[1] # 1/h x = (box[0] + box[1])/2.0 # 物体在图中的中心点x坐标 y = (box[2] + box[3])/2.0 # 物体在图中的中心点y坐标 w = box[1] - box[0] # 物体实际像素宽度 h = box[3] - box[2] # 物体实际像素高度 x = x*dw # 物体中心点x的坐标比(相当于 x/原图w) w = w*dw # 物体宽度的宽度比(相当于 w/原图w) y = y*dh # 物体中心点y的坐标比(相当于 y/原图h) h = h*dh # 物体宽度的宽度比(相当于 h/原图h) return (x, y, w, h) # 返回 相对于原图的物体中心点的x坐标比,y坐标比,宽度比,高度比,取值范围[0-1]def convert_annotation(image_id): ''' 将对应文件名的xml文件转化为label文件,xml文件包含了对应的bunding框以及图片长款大小等信息, 通过对其解析,然后进行归一化最终读到label文件中去,也就是说 一张图片文件对应一个xml文件,然后通过解析和归一化,能够将对应的信息保存到唯一一个label文件中去 labal文件中的格式:calss x y w h  同时,一张图片对应的类别有多个,所以对应的bounding的信息也有多个 ''' # 对应的通过year 找到相应的文件夹,并且打开相应image_id的xml文件,其对应bund文件 in_file = open('data/power_transmission_line_datasets/xml/%s.xml' % (image_id), encoding='utf-8') # 准备在对应的image_id 中写入对应的label,分别为 # <object-class> <x> <y> <width> <height> out_file = open('data/power_transmission_line_datasets/label/%s.txt' % (image_id), 'w', encoding='utf-8') # 解析xml文件 tree = ET.parse(in_file) # 获得对应的键值对 root = tree.getroot() # 获得图片的尺寸大小 size = root.find('size') # 如果xml内的标记为空,增加判断条件 if size != None: # 获得宽 w = int(size.find('width').text) # 获得高 h = int(size.find('height').text) # 遍历目标obj for obj in root.iter('object'): # 获得difficult difficult = obj.find('difficult').text # 获得类别 =string 类型 cls = obj.find('name').text # 如果类别不是对应在我们预定好的class文件中,或difficult==1则跳过 if cls not in classes or int(difficult) == 1: continue # 通过类别名称找到id cls_id = classes.index(cls) # 找到bndbox 对象 xmlbox = obj.find('bndbox') # 获取对应的bndbox的数组 = ['xmin','xmax','ymin','ymax'] b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) print(image_id, cls, b) # 带入进行归一化操作 # w = 宽, h = 高, b= bndbox的数组 = ['xmin','xmax','ymin','ymax'] bb = convert((w, h), b) # bb 对应的是归一化后的(x,y,w,h) # 生成 calss x y w h 在label文件中 out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')# 返回当前工作目录wd = getcwd()print(wd)for image_set in sets: ''' 对所有的文件数据集进行遍历 做了两个工作:    1.将所有图片文件都遍历一遍,并且将其所有的全路径都写在对应的txt文件中去,方便定位    2.同时对所有的图片文件进行解析和转化,将其对应的bundingbox 以及类别的信息全部解析写到label 文件中去      最后再通过直接读取文件,就能找到对应的label 信息 ''' # 先找labels文件夹如果不存在则创建 if not os.path.exists('data/power_transmission_line_datasets/labels/'): os.makedirs('data/power_transmission_line_datasets/labels/') # 读取在ImageSets/Main 中的train、test..等文件的内容 # 包含对应的文件名称 image_ids = open('data/power_transmission_line_datasets/dataSet/%s.txt' % (image_set)).read().strip().split() list_file = open('data/power_transmission_line_datasets/%s.txt' % (image_set), 'w') # 将对应的文件_id以及全路径写进去并换行 for image_id in image_ids: list_file.write('data/power_transmission_line_datasets/image/%s.jpg\n' % (image_id)) # 调用 year = 年份 image_id = 对应的文件名_id convert_annotation(image_id) # 关闭文件 list_file.close()

label文件夹中某文件内容如下:

1 0.5128302845528456 0.1638719512195122 0.012957317073170733 0.018292682926829271 0.5325203252032521 0.16482469512195122 0.012195121951219513 0.017911585365853661 0.5572916666666667 0.20579268292682928 0.011941056910569106 0.018292682926829271 0.42238313008130085 0.4026295731707317 0.009908536585365856 0.0133384146341463411 0.41450711382113825 0.7050304878048781 0.009908536585365856 0.016006097560975611 0.005970528455284553 0.405297256097561 0.011432926829268294 0.017149390243902440 0.6451981707317074 0.8746189024390244 0.12372967479674798 0.129573170731707320 0.6006097560975611 0.5482088414634146 0.12804878048780488 0.129192073170731720 0.5552591463414634 0.1953125 0.1323678861788618 0.129954268292682950 0.3654725609756098 0.05811737804878049 0.11864837398373985 0.068978658536585370 0.1899136178861789 0.5483993902439025 0.13185975609756098 0.13643292682926830 0.02870934959349594 0.40415396341463417 0.05691056910569106 0.062118902439024390 0.04128556910569106 0.7789634146341464 0.08155487804878049 0.074695121951219510 0.2170985772357724 0.936547256097561 0.12982723577235775 0.126905487804878060 0.44804369918699194 0.7155106707317074 0.11153455284552846 0.0781250 0.41133130081300817 0.4005335365853659 0.11077235772357724 0.07393292682926829三、修改配置文件1、数据配置文件

        首先需要在/yolov5-6.1/data文件夹中,新建一个power_transmission_line_datasets.yaml文件,内容设置如下:

2、网络参数修改

        对yolov5-6.1/model文件夹中,对yolov5x.yaml(根据自己选择的模型而定)文件内容修改。

3、trian.py修改

        主要用到的几个参数:–weights,–cfg,–data,–epochs,–batch-size,–img-size,–project,-workers

        重点注意:–weights,–cfg,–data,其他的默认即可(batch_size,workers根据自己电脑属性进行设置)。

四、训练及测试1、训练

        在完成上述所有的操作之后,就可以进行训练,在命令窗口输入python train.py即可以进行训练。

可以看出,输入数据在送入yolov5训练时是成批次的,且采用了多种数据增强方法,如下图所示。 

 2、测试

        在训练完成后可以利用测试集对训练后的模型进行测试,利用val.py文件进行测试,主要修改一下地方:

 测试完成后会输出map、precision、recall等指标,具体如下图所示:

 P-R曲线如下图所示:

同时也可以利用detect.py文件对测试集进行测试,将检测后的框绘制在图像上,部分测试结果如下图所示:

本文链接地址:https://www.jiuchutong.com/zhishi/298808.html 转载请保留说明!

上一篇:【AI】AI 工具合集(ai工具用法)

下一篇:真实世界的人工智能应用落地——OpenAI篇 ⛵(真实世界人工智能)

  • 订阅的自动续费怎么取消(订阅的自动续费怎么取消支付宝)

    订阅的自动续费怎么取消(订阅的自动续费怎么取消支付宝)

  • 微信群里踢人怎么踢人(微信群里踢人怎么踢不出去)

    微信群里踢人怎么踢人(微信群里踢人怎么踢不出去)

  • 借呗如何清除借款及还款记录呢(借呗如何清除借款及还款记录 永远)

    借呗如何清除借款及还款记录呢(借呗如何清除借款及还款记录 永远)

  • 华为nova4e手机怎么隐藏应用(华为nova4e手机怎么拆开)

    华为nova4e手机怎么隐藏应用(华为nova4e手机怎么拆开)

  • 华为p30和p30pro的拍照效果差别大吗(华为p30和p30pro的区别在哪里)

    华为p30和p30pro的拍照效果差别大吗(华为p30和p30pro的区别在哪里)

  • mwnd2ch/a是什么版本(mwnd2ch/a是什么型号)

    mwnd2ch/a是什么版本(mwnd2ch/a是什么型号)

  • 苹果手机反转颜色怎么关闭(苹果手机反转颜色怎么打开)

    苹果手机反转颜色怎么关闭(苹果手机反转颜色怎么打开)

  • 苹果电脑没有usb接口怎么办(苹果电脑没有usb驱动怎么办)

    苹果电脑没有usb接口怎么办(苹果电脑没有usb驱动怎么办)

  • 通话音量关不彻底(通话音量打开)

    通话音量关不彻底(通话音量打开)

  • 苹果无线充在哪里开启(苹果无线充在哪买)

    苹果无线充在哪里开启(苹果无线充在哪买)

  • 抖音小店评分低于多少就封店铺(抖音小店评分低于4.0怎么办)

    抖音小店评分低于多少就封店铺(抖音小店评分低于4.0怎么办)

  • oppoa11微信视频美颜怎么开(oppoa11微信视频小窗口)

    oppoa11微信视频美颜怎么开(oppoa11微信视频小窗口)

  • 微信没有删除好友却没有了(微信没有删除好友怎么不存在了)

    微信没有删除好友却没有了(微信没有删除好友怎么不存在了)

  • 怎么用邮箱发照片(怎么用邮箱发照片文件夹)

    怎么用邮箱发照片(怎么用邮箱发照片文件夹)

  • 台式电脑黑屏只有鼠标箭头(台式电脑黑屏只剩下一个鼠标箭头)

    台式电脑黑屏只有鼠标箭头(台式电脑黑屏只剩下一个鼠标箭头)

  • 中国的5g网络什么时候开始用(中国5g网络什么时候全面覆盖)

    中国的5g网络什么时候开始用(中国5g网络什么时候全面覆盖)

  • solopro和studio3区别(solo3pro和studio3哪个好)

    solopro和studio3区别(solo3pro和studio3哪个好)

  • 手机膜为什么有白边(手机膜为什么有彩虹纹)

    手机膜为什么有白边(手机膜为什么有彩虹纹)

  • 电子健康证怎么打印(电子健康证怎么查看)

    电子健康证怎么打印(电子健康证怎么查看)

  • 滴滴司机绕路怎么赔偿(滴滴司机绕路怎么惩罚)

    滴滴司机绕路怎么赔偿(滴滴司机绕路怎么惩罚)

  • 苹果11拍夜景怎么设置(苹果11拍夜景怎么调相机)

    苹果11拍夜景怎么设置(苹果11拍夜景怎么调相机)

  • 佳能80d和6d的区别(佳能6d与80d)

    佳能80d和6d的区别(佳能6d与80d)

  • 抖音海外版怎么下(抖音海外版怎么没网络)

    抖音海外版怎么下(抖音海外版怎么没网络)

  • apple watch 无法配对怎么办(apple watch 无法配对现有手表)

    apple watch 无法配对怎么办(apple watch 无法配对现有手表)

  • 小米突然打不出去电话(小米手机怎么打不通也打不进)

    小米突然打不出去电话(小米手机怎么打不通也打不进)

  • Vue2 Element description组件 列合并

    Vue2 Element description组件 列合并

  • JavaScript 30 JavaScript 日期格式

    JavaScript 30 JavaScript 日期格式

  • 织梦DEDE系统会员中心限制IP和时间注册防骚扰办法(织梦系统基本参数)

    织梦DEDE系统会员中心限制IP和时间注册防骚扰办法(织梦系统基本参数)

  • 国税如何零申报
  • 企业为员工缴纳公积金的通知
  • 增值税10000交多少税
  • 应税工资怎么计算出来的
  • 个体工商户月销售额超10万怎么报税
  • 附加税减半征收的条件
  • 股份支付为什么计入股本溢价
  • 小微企业印花税减免最新政策
  • 企业工商注销啥意思
  • 申请开红字发票,原蓝字发票要退回来吗
  • 进项税额转出要补所得税吗
  • 个人垫付费用报销申请怎么写
  • 公司代垫个税会计分录
  • 银行汇票怎么填写
  • 利润是负数如何计算利润率
  • 实收资本印花税怎么申报税目
  • 折扣零售商是什么意思
  • 申报开票是什么意思
  • 土地证是商业用地
  • 同程旅行酒店预订
  • 印花税核定表申请
  • 转账支票可不可以挂失止付
  • 污水处理费怎么收取的
  • 收到个税手续费返还现金流量表
  • 店铺拆除费用
  • 进口原木的增值税率
  • 确认整个会计年度的依据
  • 税收滞纳金可以税前扣除吗
  • 企业销售食品过期处罚
  • 购房专票可以抵扣进项税吗为什么
  • 库存现金的主要内容有哪些
  • 固定资产入账价值计算公式
  • 如何让游戏速度加快
  • springboot集成camunda+bpmn
  • 售后回租经营租赁可以抵扣吗
  • 资产划转增值税 开票怎么开
  • 兼职如何交税款
  • 在途物资运费会计科目怎么写
  • 人工智能课程心得体会
  • 固定资产的使用寿命超过一个会计年度
  • 网络安全技术
  • js浅拷贝和深拷贝的方法
  • 基于php判断客户是否存在
  • 政府补助为什么是递延收益
  • c 语言 static
  • Spring(十五):Spring整合MyBatis的两种方式
  • 从事特殊行业
  • 开增值税发票规格是否可以不用填?
  • 暂估成本账务处理办法
  • 待报解预算收入什么意思
  • 不动产计税金额
  • 固定资产改造多少直接进费用
  • 现金支票取现的法律规定
  • 用工资冲借款报税可以吗
  • 银行对账单和银行流水的区别
  • php mysql连接
  • Linux下MySQL 5.5/5.6的修改字符集编码为UTF8的方法
  • centos清理磁盘空间
  • win8如何添加启动项
  • mac safari浏览器翻译功能
  • 错误代码0x8007007B
  • g++编译debug
  • linux ls命令什么意思
  • cocos2dx-3.2+lua 启动项目小技巧
  • python怎么打印完整的信息
  • glsurfaceview特性
  • 用原生js写项目
  • 批处理常用命令
  • bat批处理文件运行不了
  • 超级链接是什么意思
  • unity mrt
  • Javascript事件实例详解
  • node 微信公众号开发
  • python代码视频
  • 蓝色的css代码
  • python元祖内置函数
  • jquery是怎样实现链式调用的?
  • 土地税源编码怎么填
  • 视频号带货个人和个体工商户的区别
  • 国家税务总局服务中心
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设