听说yolor是YOLO系列里在coco上表现最好的算法 下载代码来跑一跑。
官网地址 github.comhttps://github.com/WongKinYiu/yolor
一、配置环境#创建虚拟环境 conda create -n yolor python 3.8 #激活虚拟环境 conda activate yolor #10.2为cuda版本 在cmd中用nvcc --version 查看cuda版本 conda install pytorch 1.7 torchvision cudatoolkit 10.2 -c pytorch
#进入虚拟环境 cd yolor-main #安装依赖 pip install -r requirements.txt
记得下载权重文件
# 测试环境是否配置完成 python detect.py --source inference/images/horses.jpg --cfg cfg/yolor_p6.cfg --weights yolor_p6.pt --conf 0.25 --img-size 1280 --device 0
二、准备数据集
原本是VOC格式的数据集 算法要求yolo形式。
首先要从xml变成txt 将voc2yolo4.py和voc_label.py放到VOCdevkit同级目录下。
voc2yolo4.py
#----------------------------------------------------------------------# # 验证集的划分在train.py代码里面进行 # test.txt和val.txt里面没有内容是正常的。训练不会使用到。 #----------------------------------------------------------------------# #--------------------------------注意----------------------------------# 如果在pycharm中运行时提示 FileNotFoundError: [WinError 3] 系统找不到指定的路径。: ./VOCdevkit/VOC2007/Annotations 这是pycharm运行目录的问题 最简单的方法是将该文件复制到根目录后运行。 可以查询一下相对目录和根目录的概念。在VSCODE中没有这个问题。 #--------------------------------注意----------------------------------# import os import random random.seed(0) xmlfilepath r ./VOCdevkit/VOC2007/Annotations savebasePath r ./VOCdevkit/VOC2007/ImageSets/Main/ #----------------------------------------------------------------------# # 想要增加测试集修改trainval_percent trainval 0时 都用来测试 # train_percent不需要修改 #----------------------------------------------------------------------# trainval_percent 0.9 train_percent 0.9 temp_xml os.listdir(xmlfilepath) total_xml [] for xml in temp_xml: if xml.endswith( .xml ): total_xml.append(xml) 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) print( train and val size ,tv) print( traub suze ,tr) ftrainval open(os.path.join(savebasePath, trainval.txt ), w ) ftest open(os.path.join(savebasePath, test.txt ), w ) ftrain open(os.path.join(savebasePath, train.txt ), w ) fval open(os.path.join(savebasePath, 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()
voc_label.py
import xml.etree.ElementTree as ET import pickle import os from os import listdir, getcwd from os.path import join # 2012代表年份 2012train.txt 就是ImageSetsMain 下对应的txt名称 其依次类推 换成自己数据集需修改sets sets [( 2007 , train ), ( 2007 , val ), ( 2007 , test )] # classes 是所有类别名称 换成自己数据集需要修改classes classes [ drone ] # params size 图片宽高 # params box groud truth 框的x y w h def convert(size, box): dw 1./size[0] # 用于下面框的坐标和高宽归一化 dh 1./size[1] x (box[0] box[1])/2.0 # 求中心坐标 y (box[2] box[3])/2.0 w box[1] - box[0] h box[3] - box[2] x x*dw w w*dw y y*dh h h*dh return (x,y,w,h) def convert_annotation(year, image_id): in_file open( VOCdevkit/VOC%s/Annotations/%s.xml %(year, image_id)) # 读取 image_id 的xml文件 out_file open( VOCdevkit/VOC%s/labels/%s.txt %(year, image_id), w ) # 保存txt文件地址 tree ET.parse(in_file) root tree.getroot() size root.find( size ) # 读取图片 w h w int(size.find( width ).text) h int(size.find( height ).text) for obj in root.iter( object ): difficult obj.find( difficult ).text cls obj.find( name ).text if cls not in classes or int(difficult) 1: continue cls_id classes.index(cls) xmlbox obj.find( bndbox ) b (float(xmlbox.find( xmin ).text), float(xmlbox.find( xmax ).text), float(xmlbox.find( ymin ).text), float(xmlbox.find( ymax ).text)) bb convert((w,h), b) # w,h,x,y归一化操作 out_file.write(str(cls_id) .join([str(a) for a in bb]) n ) # 一个框写入 wd getcwd() # 获取当前地址 for year, image_set in sets: if not os.path.exists( VOCdevkit/VOC%s/labels/ %(year)): os.makedirs( VOCdevkit/VOC%s/labels/ %(year)) image_ids open( VOCdevkit/VOC%s/ImageSets/Main/%s.txt %(year, image_set)).read().strip().split() # 读取图片名称 list_file open( %s_%s.txt %(year, image_set), w ) # 保存所有图片的绝对路径 for image_id in image_ids: list_file.write( %s/VOCdevkit/VOC%s/JPEGImages/%s.bmpn %(wd, year, image_id)) convert_annotation(year, image_id) list_file.close()



