本文将要来介绍一个好用的计算mAP的工具。工具的github地址为:https://github.com/Cartucho/mAP
一般数据集有train,valid,test图片以及对应的txt文档,需要先用train,valid进行训练,test则是接下来用来测试mAP。
首先git clone mAP工具包:git clone https://github.com/Cartucho/mAP
然后进入到该mAP文件夹中,该文件夹有以下文件:
在input文件夹中有detection-results, ground-truth, images-optional 文件夹,分别存放预测值txt,真实值txt以及图片。
下面来看一下预测值txt和真实值txt文件内容格式。
- 预测值txt文件内容格式如下,其中
<left><top>
是指预测框的左上角坐标,<right><bottom>
是指预测框的右下角坐标。
<class_name> <confidence> <left> <top> <right> <bottom>
- 真实值txt内容格式如下,与预测值txt的区别在于不需要写入confidence
如果需要将文件格式进行转换,该github提供了转换代码,放在scripts/extra
文件夹里面。
预测值写入txt文档的代码如下:
import cv2
import os
import numpy as np
weightsPath = "weights/yolov4-tiny_best.weights"
configPath = "cfg/yolov4-tiny.cfg"
labelsPath = "cfg/label.names"
imgdir = "test"
save_result_dir = "detect_result"
save_txt_dir = "detect_txt"
if not os.path.exists(save_result_dir):
os.mkdir(save_result_dir)
if not os.path.exists(save_txt_dir):
os.mkdir(save_txt_dir)
LABELS = open(labelsPath).read().strip().split("\n")
# Set according to the number of categories
COLORS = [(0, 255, 255), (255, 255, 0)]
CONFIDENCE_THRESHOLD = 0.8
NMS_THRESHOLD = 0.4
net = cv2.dnn.readNet(weightsPath, configPath)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA_FP16)
model = cv2.dnn_DetectionModel(net)
# Set according to the size of input
model.setInputParams(size=(416, 416), scale=1/255, swapRB=True)
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)
for image_name in os.listdir(imgdir):
print("detect " + image_name + " ...")
name = image_name.split('.jpg')[0]
img = cv2.imread(os.path.join(imgdir, image_name))
image_size = [img.shape[1],img.shape[0]]
classes, scores, boxes = model.detect(img, CONFIDENCE_THRESHOLD, NMS_THRESHOLD)
for (classid, score, box) in zip(classes, scores, boxes):
color = COLORS[int(classid) % len(COLORS)]
label = "%s" % (LABELS[classid[0]])
xmin = int(box[0])
xmax = int(box[0])+int(box[2])
ymin = int(box[1])
ymax = int(box[1])+int(box[3])
bndbox = [xmin, xmax, ymin, ymax]
x, y, w, h = convert(image_size, bndbox)
cv2.rectangle(img, box, color, 2)
text = label+ ":"+str(score[0])
cv2.putText(img, text, (box[0], box[1] - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
with open(os.path.join(save_txt_dir, name+'.txt'), 'a+') as f:
# yolo txt
#f.write('%s %s %s %s %s\n' % (classid[0], x, y, w, h))
# write to test mAP
f.write('%s %s %s %s %s %s\n' % (label, str(score[0]), xmin, ymin, xmax, ymax))
if not os.path.exists(os.path.join(save_txt_dir, name+'.txt')):
with open(os.path.join(save_txt_dir, name+'.txt'), 'a+') as f:
f.write('')
cv2.imwrite(os.path.join(save_result_dir, name+".jpg"), img)
转换文件格式以后,开始计算mAP,这里使用的是口罩侦测的模型,开始执行:
cd mAP
python main.py
口
罩
数
据
m
A
P
计
算
结
果
口罩数据mAP计算结果
口罩数据mAP计算结果
计算完以后,在mAP/output中可以看到结果,mAP/output/classes中有各个类别的PR曲线、mAP/output/images则是每张图片的预测情况。
参考目录
https://medium.com/ching-i/%E8%A9%95%E4%BC%B0-object-detection-map-%E5%B7%A5%E5%85%B7-79c509d05bfe