0


yolov7-face关于widerface-val数据集的评测

  1. 我复现了yolov7s-face的精度,我没有加载预训练模型,重新训的,300个epoch,最优的模型精度比官方的点还要高一点,下面是我模型的精度和官方的精度:我训出来模型的指标: yolov7s 训练300epoch best.pt ==================== Results ==================== Easy Val AP: 0.9510914378803449 Medium Val AP: 0.9349033662833984 Hard Val AP: 0.8550381774914542 =================================================官方模型的指标: ==================== Results ==================== Easy Val AP: 0.9481596778871507 Medium Val AP: 0.9314085577436426 Hard Val AP: 0.8516288529133722 ================================================= 2.如何对val数据集进行评测,先改一下detect.py代码生成用于评测精度的txt文件,代码如下:
  1. import argparse
  2. import time
  3. from pathlib import Path
  4. import os
  5. import copy
  6. import cv2
  7. import torch
  8. import torch.backends.cudnn as cudnn
  9. from numpy import random
  10. from models.experimental import attempt_load
  11. from utils.datasets import LoadStreams, LoadImages
  12. from utils.general import check_img_size, check_requirements, check_imshow, non_max_suppression, apply_classifier, \
  13. scale_coords, xyxy2xywh, strip_optimizer, set_logging, increment_path, save_one_box
  14. from utils.plots import colors, plot_one_box
  15. from utils.torch_utils import select_device, load_classifier, time_synchronized
  16. defdetect(opt):
  17. source, weights, view_img, save_txt, imgsz, save_txt_tidl, kpt_label ,widerface,save_widerface= opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size, opt.save_txt_tidl, opt.kpt_label,opt.widerface,opt.save_widerface
  18. save_img =not opt.nosave andnot source.endswith('.txt')# save inference images
  19. webcam = source.isnumeric()or source.endswith('.txt')or source.lower().startswith(('rtsp://','rtmp://','http://','https://'))# Directories
  20. save_dir = increment_path(Path(opt.project)/ opt.name, exist_ok=opt.exist_ok)# increment run(save_dir /'labels'if(save_txt or save_txt_tidl)else save_dir).mkdir(parents=True, exist_ok=True)# make dir# Initialize
  21. set_logging()
  22. device = select_device(opt.device)
  23. half = device.type!='cpu'andnot save_txt_tidl # half precision only supported on CUDA# Load model
  24. model = attempt_load(weights, map_location=device)# load FP32 model
  25. stride =int(model.stride.max())# model strideifisinstance(imgsz,(list,tuple)):assertlen(imgsz)==2;"height and width of image has to be specified"
  26. imgsz[0]= check_img_size(imgsz[0], s=stride)
  27. imgsz[1]= check_img_size(imgsz[1], s=stride)else:
  28. imgsz = check_img_size(imgsz, s=stride)# check img_size
  29. names = model.module.names ifhasattr(model,'module')else model.names # get class namesif half:
  30. model.half()# to FP16# Second-stage classifier
  31. classify =Falseif classify:
  32. modelc = load_classifier(name='resnet101', n=2)# initialize
  33. modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']).to(device).eval()# Set Dataloader
  34. vid_path, vid_writer =None,Noneif webcam:
  35. view_img = check_imshow()
  36. cudnn.benchmark =True# set True to speed up constant image size inference
  37. dataset = LoadStreams(source, img_size=imgsz, stride=stride)else:
  38. dataset = LoadImages(source, img_size=imgsz, stride=stride)# Run inferenceif device.type!='cpu':
  39. model(torch.zeros(1,3, imgsz, imgsz).to(device).type_as(next(model.parameters())))# run once
  40. t0 = time.time()for path, img, im0s, vid_cap in dataset:
  41. img = torch.from_numpy(img).to(device)
  42. img = img.half()if half else img.float()# uint8 to fp16/32
  43. img /=255.0# 0 - 255 to 0.0 - 1.0if img.ndimension()==3:
  44. img = img.unsqueeze(0)# Inference
  45. t1 = time_synchronized()
  46. pred = model(img, augment=opt.augment)[0]print(pred[...,4].max())# Apply NMS
  47. pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms, kpt_label=kpt_label)
  48. t2 = time_synchronized()# Apply Classifierif classify:
  49. pred = apply_classifier(pred, modelc, img, im0s)# Process detectionsfor i, det inenumerate(pred):# detections per imageif webcam:# batch_size >= 1
  50. p, s, im0, frame = path[i],'%g: '% i, im0s[i].copy(), dataset.count
  51. else:
  52. p, s, im0, frame = path,'', im0s.copy(),getattr(dataset,'frame',0)
  53. p = Path(p)# to Path
  54. save_path =str(save_dir / p.name)# img.jpg
  55. txt_path =str(save_dir /'labels'/ p.stem)+(''if dataset.mode =='image'elsef'_{frame}')# img.txt
  56. s +='%gx%g '% img.shape[2:]# print string
  57. gn = torch.tensor(im0.shape)[[1,0,1,0]]# normalization gain whwh# print("det----",det)# print("det.Size()---",det.shape[0])# exit(-1)if det.shape[0]==0:# print("det is None:====",det)# exit(-1)
  58. os.makedirs(save_widerface,exist_ok=True)
  59. save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))withopen(save_widerface_txt,"w")as fwider:
  60. widerface_file_name = Path(p).name[:-4]+"\n"print("=========",widerface_file_name)# exit(-1)
  61. fwider.write(widerface_file_name)
  62. fwider.write(str(0)+"\n")iflen(det):# Rescale boxes from img_size to im0 size
  63. scale_coords(img.shape[2:], det[:,:4], im0.shape, kpt_label=False)
  64. scale_coords(img.shape[2:], det[:,6:], im0.shape, kpt_label=kpt_label, step=3)# Print resultsfor c in det[:,5].unique():
  65. n =(det[:,5]== c).sum()# detections per class
  66. s +=f"{n}{names[int(c)]}{'s'*(n >1)}, "# add to stringif widerface:
  67. os.makedirs(save_widerface,exist_ok=True)
  68. save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))
  69. widerface_file_name = Path(p).name[:-4]+"\n"
  70. widerface_bboxs_num =str(len(pred[0]))+"\n"withopen(save_widerface_txt,"a")as fwider:
  71. fwider.write(widerface_file_name)
  72. fwider.write(widerface_bboxs_num)# Write resultsfor det_index,(*xyxy, conf, cls)inenumerate((det[:,:6])):if widerface:if cls ==0:
  73. os.makedirs(save_widerface,exist_ok=True)
  74. save_widerface_txt =str(Path(save_widerface)/Path(Path(p).name[:-3]+"txt"))#widerface_file_name = Path(p).name + "\n"#widerface_bboxs_num = str(len(pred[0])) +"\n"
  75. x1 =int(xyxy[0]+0.5)
  76. y1 =int(xyxy[1]+0.5)
  77. x2 =int(xyxy[2]+0.5)
  78. y2 =int(xyxy[3]+0.5)withopen(save_widerface_txt,"a")as fwider:#fwider.write(widerface_file_name)#fwider.write(widerface_bboxs_num)
  79. fwider.write("%d %d %d %d %.03f"%(x1,y1,x2-x1,y2-y1,conf if conf<=1else1)+"\n")if save_txt:# Write to file
  80. xywh =(xyxy2xywh(torch.tensor(xyxy).view(1,4))/ gn).view(-1).tolist()# normalized xywh
  81. line =(cls,*xywh, conf)if opt.save_conf else(cls,*xywh)# label formatwithopen(txt_path +'.txt','a')as f:
  82. f.write(('%g '*len(line)).rstrip()% line +'\n')# if save_img or opt.save_crop or view_img: # Add bbox to image# c = int(cls) # integer class# label = None if opt.hide_labels else (names[c] if opt.hide_conf else f'{names[c]} {conf:.2f}')# kpts = det[det_index, 6:]# plot_one_box(xyxy, im0, label=label, color=colors(c, True), line_thickness=opt.line_thickness, kpt_label=kpt_label, kpts=kpts, steps=3, orig_shape=im0.shape[:2])# if opt.save_crop:# save_one_box(xyxy, im0s, file=save_dir / 'crops' / names[c] / f'{p.stem}.jpg', BGR=True)if save_txt_tidl:# Write to file in tidl dump formatfor*xyxy, conf, cls in det_tidl:
  83. xyxy = torch.tensor(xyxy).view(-1).tolist()
  84. line =(conf, cls,*xyxy)if opt.save_conf else(cls,*xyxy)# label formatwithopen(txt_path +'.txt','a')as f:
  85. f.write(('%g '*len(line)).rstrip()% line +'\n')# Print time (inference + NMS)print(f'{s}Done. ({t2 - t1:.3f}s)')# Stream resultsif view_img:
  86. cv2.imshow(str(p), im0)
  87. cv2.waitKey(1)# 1 millisecond# Save results (image with detections)if save_img:if dataset.mode =='image':
  88. cv2.imwrite(save_path, im0)else:# 'video' or 'stream'if vid_path != save_path:# new video
  89. vid_path = save_path
  90. ifisinstance(vid_writer, cv2.VideoWriter):
  91. vid_writer.release()# release previous video writerif vid_cap:# video
  92. fps = vid_cap.get(cv2.CAP_PROP_FPS)
  93. w =int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  94. h =int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))else:# stream
  95. fps, w, h =30, im0.shape[1], im0.shape[0]
  96. save_path +='.mp4'
  97. vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps,(w, h))
  98. vid_writer.write(im0)if save_txt or save_txt_tidl or save_img:
  99. s =f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir /'labels'}"if save_txt or save_txt_tidl else''print(f"Results saved to {save_dir}{s}")print(f'Done. ({time.time()- t0:.3f}s)')if __name__ =='__main__':
  100. parser = argparse.ArgumentParser()
  101. parser.add_argument('--weights', nargs='+',type=str, default='yolov5s.pt',help='model.pt path(s)')
  102. parser.add_argument('--source',type=str, default='data/images',help='source')# file/folder, 0 for webcam
  103. parser.add_argument('--img-size', nargs='+',type=int, default=640,help='inference size (pixels)')
  104. parser.add_argument('--conf-thres',type=float, default=0.01,help='object confidence threshold')
  105. parser.add_argument('--iou-thres',type=float, default=0.5,help='IOU threshold for NMS')
  106. parser.add_argument('--device', default='',help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
  107. parser.add_argument('--view-img', action='store_true',help='display results')
  108. parser.add_argument('--save-txt', action='store_true',help='save results to *.txt')
  109. parser.add_argument('--save-txt-tidl', action='store_true',help='save results to *.txt in tidl format')
  110. parser.add_argument('--save-bin', action='store_true',help='save base n/w outputs in raw bin format')
  111. parser.add_argument('--save-conf', action='store_true',help='save confidences in --save-txt labels')
  112. parser.add_argument('--save-crop', action='store_true',help='save cropped prediction boxes')
  113. parser.add_argument('--nosave', action='store_true',help='do not save images/videos')
  114. parser.add_argument('--classes', nargs='+',type=int,help='filter by class: --class 0, or --class 0 2 3')
  115. parser.add_argument('--agnostic-nms', action='store_true',help='class-agnostic NMS')
  116. parser.add_argument('--augment', action='store_true',help='augmented inference')
  117. parser.add_argument('--update', action='store_true',help='update all models')
  118. parser.add_argument('--project', default='runs/detect',help='save results to project/name')
  119. parser.add_argument('--name', default='exp',help='save results to project/name')
  120. parser.add_argument('--exist-ok', action='store_true',help='existing project/name ok, do not increment')
  121. parser.add_argument('--line-thickness', default=3,type=int,help='bounding box thickness (pixels)')
  122. parser.add_argument('--hide-labels', default=False, action='store_true',help='hide labels')
  123. parser.add_argument('--hide-conf', default=False, action='store_true',help='hide confidences')
  124. parser.add_argument('--kpt-label',type=int, default=5,help='number of keypoints')
  125. parser.add_argument("--widerface",action="store_true",help='save widerface_val txt')
  126. parser.add_argument('--save-widerface',type=str, default='./widerface_txt',help=' save widerface_txt folder')
  127. opt = parser.parse_args()print(opt)
  128. check_requirements(exclude=('tensorboard','pycocotools','thop'))with torch.no_grad():if opt.update:# update all models (to fix SourceChangeWarning)for opt.weights in['yolov5s.pt','yolov5m.pt','yolov5l.pt','yolov5x.pt']:
  129. detect(opt=opt)
  130. strip_optimizer(opt.weights)else:
  131. detect(opt=opt)

执行命令

  1. CUDA_VISIBLE_DEVICES=0 python detect-widerface.py --weights your path --source your input_path --widerface --save-widerface 2023-widerface-1600

3.最后一步就是将生成的txt文件移到指定的目录下,代码如下

  1. import os
  2. import os.path as osp
  3. import re
  4. import shutil
  5. from pathlib import Path
  6. if __name__ =="__main__":#用于评测的txt文件夹
  7. path ="./yolov7s_txt-pre-weight"#detect生成的txt文件
  8. source_path ="./2023-widerface-1600"
  9. dir_list =["0--Parade","1--Handshaking","2--Demonstration","3--Riot","4--Dancing","5--Car_Accident","6--Funeral","7--Cheering","8--Election_Campain","9--Press_Conference","10--People_Marching","11--Meeting","12--Group","13--Interview","14--Traffic","15--Stock_Market","16--Award_Ceremony","17--Ceremony","18--Concerts","19--Couple","20--Family_Group","21--Festival","22--Picnic","23--Shoppers","24--Soldier_Firing","25--Soldier_Patrol","26--Soldier_Drilling","27--Spa","28--Sports_Fan","29--Students_Schoolkids","30--Surgeons","31--Waiter_Waitress","32--Worker_Laborer","33--Running","34--Baseball","35--Basketball","36--Football","37--Soccer","38--Tennis","39--Ice_Skating","40--Gymnastics","41--Swimming","42--Car_Racing","43--Row_Boat","44--Aerobics","45--Balloonist","46--Jockey","47--Matador_Bullfighter","48--Parachutist_Paratrooper","49--Greeting","50--Celebration_Or_Party","51--Dresses","52--Photographers","53--Raid","54--Rescue","55--Sports_Coach_Trainer","56--Voter","57--Angler","58--Hockey","59--people--driving--car","61--Street_Battle"]for dir_path in dir_list:
  10. obj_path = osp.join(path,dir_path)
  11. os.makedirs(obj_path,exist_ok=True)# num = 0# print("source_path===",source_path)for file_path in os.listdir(source_path):
  12. file_id_compile = re.compile(r"([\d]+)_")
  13. file_id = re.findall(file_id_compile,file_path)[0]
  14. file_paths = osp.join(source_path,file_path)
  15. dir_id_compile = re.compile(r"([\d]+)--")for path_dir in dir_list:
  16. dir_id = re.findall(dir_id_compile,path_dir)[0]# print("dir_id:%s"%(dir_id))if file_id == dir_id:# print("file_id===%s,dir_id===%s"%(file_id,dir_id))
  17. shutil.copyfile(file_paths,Path(Path(path)/path_dir)/file_path)break

本文转载自: https://blog.csdn.net/qq_35140742/article/details/128727680
版权归原作者 阿吉的CV之路 所有, 如有侵权,请联系我们删除。

“yolov7-face关于widerface-val数据集的评测”的评论:

还没有评论