赞
踩
话说,测试mAP有什么作用呢?就算有作用,在训练结束的时候也会生成对验证集的每一轮的mAP为什么还要单独测呢?
首先对上面两个问题进行解答:
1.通过测mAP可以直观的看到对这批数据的检测效果,观察每个类的AP知道哪几个类的检测效果比较好哪几个的检测效果比较弱,进行相关的维护。
2.自动生成的mAP只代表对验证集的检测效果,如果在实际项目中,会有各种各样的环境下的数据集,当出现新的一批数据的时候我们需要检测对新的数据的效果,从而提取FN或FP的数据集(即误检数据)增加至训练集进行不断训练,使模型的鲁棒性越来越好。
下面开始正题。
首先使用模型对要检测的数据进行detect,生成的txt标签使用如下代码进行转换:
import os from numpy.lib.twodim_base import triu_indices_from import pandas as pd from glob import glob import cv2 import codecs def darknet2ap(txt_path): data = pd.DataFrame() filelist = os.listdir(txt_path) for file in filelist: file_path = os.path.join(txt_path, file) filename = os.path.splitext(file)[0] data = "" with open(file_path, 'r', encoding='utf-8') as f1: for line in f1.readlines(): line = line.strip('\n') a = line.split(' ') # 这部分要按照训练时label的类的顺序,有几个类就加几个分支 if a[0] == '0': a[0] = 'head' elif a[0] == '1': a[0] = 'hat' elif a[0] == '2': a[0] = 'helmet' center_x = float(a[1]) * 416 center_y = float(a[2]) * 416 w = float(a[3]) * 416 h = float(a[4]) * 416 x1 = center_x - w / 2 y1 = center_y - h / 2 x2 = center_x + w / 2 y2 = center_y + h / 2 # det score = a[5] b = a[0] + ' ' + score + ' ' + str(x1) + ' ' + str(y1) + ' ' + str(x2) + ' ' + str(y2) # grt # b = a[0] + ' ' + str(x1) + ' ' + str(y1) + ' ' + str(x2) + ' ' + str(y2) print(b) data += b + '\n' with open(saved_path + '/' + filename + ".txt", 'w', encoding='utf-8') as f2: f2.writelines(data) txt_path = '/cch/.../labels' # 存放标签的目录 saved_path = '/cch/.../dr' # 存放转换后的保存目录 if __name__ == '__main__': darknet2ap(txt_path)
对要测试的数据先进行画框处理,一般我会用旧模型对数据测试的txt转为json然后进行手工调整数据,这样就不用一个一个标框会比较快。yolov5检测出来的数据集是txt文件夹混在图片里面的,所以要先并列建一个专门存图片的文件夹,并将图片mv进去。txt转json代码如下:
# -*- coding: utf-8 -*- import json import cv2 from glob import glob import os txt_path = '/cch/.../labels/' # darknet格式 saved_path = '/cch/.../json/' img_path = '/cch/.../images/' files = glob(txt_path + "*.txt") # files = os.listdir(txt_path) # print(files) files = [i.split('/')[-1].split('.txt')[0] for i in files] print(files) for file in files: print(file) txt_file = txt_path + file + '.txt' img_file = img_path + file + '.jpg' if not os.path.exists(img_file): img_file = img_path + file + '.png' if not os.path.exists(img_file): img_file = img_path + file + '.jpeg' print(img_file) img = cv2.imread(img_file) # print(img) imgw = img.shape[1] imgh = img.shape[0] xi = [] yi = [] xa = [] ya = [] Label = [] with open(txt_file, 'r') as f: # 读取txt文件将所有标签名存入数组 for line in f.readlines(): line = line.strip('\n') a = line.split(' ') label = 'other' # 这部分要按照训练时label的类的顺序,有几个类就加几个分支 if a[0] == '0': label = 'head' elif a[0] == '1': label = 'hat' elif a[0] == '2': label = 'helmet' Label.append(label) print(Label) centerx=float(a[1])*imgw centery=float(a[2])*imgh w=float(a[3])*imgw h=float(a[4])*imgh xmin = centerx - w/2 xmax= centerx + w/2 ymin= centery - h/2 ymax = centery + h/2 xi.append(xmin) yi.append(ymin) xa.append(xmax) ya.append(ymax) # for j in range(0, len(files)): labelme_formate = { "version": "4.2.9", "flags": { }, "lineColor": [0, 255, 0, 128], "fillColor": [255, 0, 0, 128], "imagePath": os.path.split(img_file)[-1], "imageHeight": imgh, "imageWidth": imgw } labelme_formate['imageData'] = None shapes = [] for i in range(0, len(xi)): s = { "label": Label[i], "line_color": None, "fill_color": None, "shape_type": "rectangle"} points = [ [xi[i], yi[i]], [xa[i], ya[i]] ] s['points'] = points shapes.append(s) labelme_formate['shapes'] = shapes json.dump(labelme_formate, open(saved_path + file + ".json", 'w'), ensure_ascii=False, indent=2) print(saved_path + file + ".json")
然后标注完转回darknet的训练格式:
import json import os import shutil import cv2 import os from numpy.lib.twodim_base import triu_indices_from import pandas as pd from glob import glob import codecs print(cv2.__version__) def getBoundingBox(points): # 找到两个点的x最大最小值,y最大最小值 xmin = points[0][0] xmax = points[0][0] ymin = points[0][1] ymax = points[0][1] for p in points: if p[0] > xmax: xmax = p[0] elif p[0] < xmin: xmin = p[0] if p[1] > ymax: ymax = p[1] elif p[1] < ymin: ymin = p[1] return [int(xmin), int(xmax), int(ymin), int(ymax)] def json2txt(json_path, midTxt_path): json_data = json.load(open(json_path)) img_h = json_data["imageHeight"] img_w = json_data["imageWidth"] shape_data = json_data["shapes"] shape_data_len = len(shape_data) img_name = os.path.split(json_path)[-1].split(".json")[0] name = img_name + '.jpg' data = '' for i in range(shape_data_len): lable_name = shape_data[i]["label"] points = shape_data[i]["points"] [xmin, xmax, ymin, ymax] = getBoundingBox(points) if xmin <= 0: xmin = 0 if ymin <= 0: ymin = 0 if xmax >= img_w: xmax = img_w - 1 if ymax >= img_h: ymax = img_h - 1 b = name + ' ' + lable_name + ' ' + str(xmin) + ' ' + str(ymin) + ' ' + str(xmax) + ' ' + str(ymax) print(b) data += b + '\n' with open(midTxt_path + '/' + img_name + ".txt", 'w', encoding='utf-8') as f: f.writelines(data) def txt2darknet(midTxt_path, img_path): data = pd.DataFrame() filelist = os.listdir(midTxt_path) for file in filelist: file_path = os.path.join(midTxt_path, file) filename = os.path.splitext(file)[0] imgName = filename + '.jpg' imgPath = os.path.join(img_path, imgName) img = cv2.imread(imgPath) [img_h, img_w, _] = img.shape data = "" with codecs.open(file_path, 'r', encoding='utf-8',errors='ignore') as f1: for line in f1.readlines(): line = line.strip('\n') a = line.split(' ') if a[1] == 'other' or a[1] == 'mask' or a[1] == 'del': continue if a[1] == 'head': a[1] = '0' elif a[1] == 'hat': a[1] = '1' elif a[1] == 'helmet': a[1] = '2' # 这里是自己命名的类别及对应的数字 x1 = float(a[2]) y1 = float(a[3]) w = float(a[4]) - float(a[2]) h = float(a[5]) - float(a[3]) if w <= 15 and h <= 15: continue center_x = float(a[2]) + w / 2 center_y = float(a[3]) + h / 2 a[2] = str(center_x / img_w) a[3] = str(center_y / img_h) a[4] = str(w / img_w) a[5] = str(h / img_h) b = a[1] + ' ' + a[2] + ' ' + a[3] + ' ' + a[4] + ' ' + a[5] print(b) data += b + '\n' with open(saved_path + '/' + filename + ".txt", 'w', encoding='utf-8') as f2: f2.writelines(data) json_path = "json文件的文件夹路径" midTxt_path = "中间存放的tmp文件夹会自动删除" img_path = '图片文件夹路径' saved_path = '存放darknet格式文件的文件夹路径' if not os.path.exists(midTxt_path): os.mkdir(midTxt_path) filelist = os.listdir(json_path) for file in filelist: old_dir = os.path.join(json_path, file) if os.path.isdir(old_dir)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。