4、picodet 小目标训练全流程

文章目录3、转换成VOC4、生成训练数据5、模型训练6、模型推理
使用进行小目标检测 。
本文以检测小目标乒乓球为例 , 包括数据的准备及训练全流程 。1、数据准备
这次有两个分辩率的输入分别是416和256 , 对应的切图多尺度是这么做的:
416:[320, 352, 384, 416, 448, 480, 512] , 对应//.yml这个配置文件
256: [160, 192, 224, 256, 288, 320, 352] , 对应//.yml这个配置文件
以上各自的分辩率 。
配置文件的多尺度如下:
batch_transforms:# - BatchRandomResize: {target_size: [320, 352, 384, 416, 448, 480, 512], random_size: True, random_interp: True, keep_ratio: False}- BatchRandomResize: {target_size: [160, 192, 224, 256, 288, 320, 352], random_size: True, random_interp: True, keep_ratio: False}
数据准备流程是:
voc->coco->sahi切图->转voc->生成训练数据
官方的主流是支持coco的 , 但我们使用voc是为了使用进行查看
原始数据位置:/
pqdetection_voc|----images||----a.jpg||----b.jpg|----labels||----a.xml||----ab.xml|----label_list.txt#写有类别名称
1.1 VOC转COCO
这个有我的其它博客链接 , 这里写一部分单独的代码
import osimport glob import jsonfrom tqdm import tqdmimport xml.etree.ElementTree as ETdef voc_xmls_to_cocojson(annpath,imgpath,labelpath, output_dir, output_file):"""voc xmls 转cocojson,只生成一个json的文件Args:annpath (_type_): 标注文件xml的路径imgpath (_type_): 图片的路径labelpath (_type_): 标签文件的路径output_dir (_type_): json保存路径output_file (_type_): json文件名"""img_names = os.listdir(imgpath)annotation_paths = glob.glob(os.path.join(annpath,'*.xml'))with open(labelpath, 'r') as f:labels_str = f.read().split()labels_ids = list(range(1, len(labels_str) + 1))label2id=dict(zip(labels_str, labels_ids))output_json_dict = {"images": [],"type": "instances","annotations": [],"categories": []}bnd_id = 1# bounding box start idim_id = 0print('Start converting !')for xml_path in tqdm(annotation_paths): # 在这里我们以xml为基础 , 而不是图片 , 因为有些图片没有目标 , 没有生成xml文件;这样必须用到glob , 这会一定程度上减小程序运行速度# Read annotation xmlim_dir = glob.glob(os.path.join(imgpath,os.path.splitext(os.path.basename(xml_path))[0]+".*"))[0]img_name = os.path.basename(im_dir)ann_tree = ET.parse(xml_path)ann_root = ann_tree.getroot()size = ann_root.find('size')width = float(size.findtext('width'))height = float(size.findtext('height'))img_info = {'file_name': img_name,'height': height,'width': width,'id': im_id}# temp={"file_name":}output_json_dict['images'].append(img_info)for obj in ann_root.findall('object'):label = obj.findtext('name')assert label in label2id, "label is not in label2id."category_id = label2id[label]bndbox = obj.find('bndbox')xmin = float(bndbox.findtext('xmin'))ymin = float(bndbox.findtext('ymin'))xmax = float(bndbox.findtext('xmax'))ymax = float(bndbox.findtext('ymax'))assert xmax > xmin and ymax > ymin, "Box size error."o_width = xmax - xmino_height = ymax - yminann = {'area': o_width * o_height,'iscrowd': 0,'bbox': [xmin, ymin, o_width, o_height],'category_id': category_id,'ignore': 0,}ann.update({'image_id': im_id, 'id': bnd_id})output_json_dict['annotations'].append(ann)bnd_id = bnd_id + 1im_id += 1for label, label_id in label2id.items():category_info = {'supercategory': 'none', 'id': label_id, 'name': label}output_json_dict['categories'].append(category_info)output_file = os.path.join(output_dir, output_file)if not os.path.exists(output_dir):os.makedirs(output_dir,exist_ok=True)with open(output_file, 'w',encoding='utf-8') as f:# output_json = json.dumps(output_json_dict)# f.write(output_json)json.dump(output_json_dict, f, indent=4, ensure_ascii=False) #支持中文