当前位置:   article > 正文

测试yolov5训练的模型对某一批数据的检测结果的mAP_yolov5怎么看map

yolov5怎么看map

话说,测试mAP有什么作用呢?就算有作用,在训练结束的时候也会生成对验证集的每一轮的mAP为什么还要单独测呢?

首先对上面两个问题进行解答:
1.通过测mAP可以直观的看到对这批数据的检测效果,观察每个类的AP知道哪几个类的检测效果比较好哪几个的检测效果比较弱,进行相关的维护。
2.自动生成的mAP只代表对验证集的检测效果,如果在实际项目中,会有各种各样的环境下的数据集,当出现新的一批数据的时候我们需要检测对新的数据的效果,从而提取FN或FP的数据集(即误检数据)增加至训练集进行不断训练,使模型的鲁棒性越来越好。

下面开始正题。

检测集label转换

首先使用模型对要检测的数据进行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) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

数据标注GT值

对要测试的数据先进行画框处理,一般我会用旧模型对数据测试的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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94

然后标注完转回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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/554438
推荐阅读
相关标签
  

闽ICP备14008679号