You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

yolo_detect_mask.py 15 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. import argparse
  2. import os
  3. import platform
  4. import shutil
  5. import time
  6. from pathlib import Path
  7. import os
  8. os.environ['KMP_DUPLICATE_LIB_OK']='True'
  9. import cv2
  10. import torch
  11. import torch.backends.cudnn as cudnn
  12. from numpy import random
  13. from utils.utils import *
  14. from models.experimental import attempt_load
  15. from utils.datasets import LoadStreams, LoadImages
  16. from utils.general import (
  17. check_img_size, non_max_suppression, apply_classifier, scale_coords,
  18. xyxy2xywh, plot_one_box, strip_optimizer, set_logging)
  19. from utils.torch_utils import select_device, load_classifier, time_synchronized
  20. from utils.general import (
  21. check_img_size, non_max_suppression, apply_classifier, scale_coords,
  22. xyxy2xywh, plot_one_box, strip_optimizer, set_logging)
  23. # def detect_image(source,out,imgsz = 640,save_img=False,save_txt = False,weights = "./weights/yolov5s.pt"):
  24. # # out, source, weights, view_img, save_txt, imgsz = \
  25. # # opt.output, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
  26. # # webcam = source == '0' or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')
  27. # webcam = source =='0'
  28. # # Initialize
  29. # set_logging()
  30. # device = select_device('')
  31. # # if os.path.exists(out):
  32. # # shutil.rmtree(out) # delete output folder
  33. # # os.mkdir(out) # make new output folder
  34. # half = device.type != 'cpu' # half precision only supported on CUDA
  35. #
  36. # # Load model
  37. # model = attempt_load(weights, map_location=device) # load FP32 model
  38. # imgsz = check_img_size(imgsz, s=model.stride.max()) # check img_size
  39. # if half:
  40. # model.half() # to FP16
  41. #
  42. # # Second-stage classifier
  43. # # classify = False
  44. # # if classify:
  45. # # modelc = load_classifier(name='resnet101', n=2) # initialize
  46. # # modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']) # load weights
  47. # # modelc.to(device).eval()
  48. #
  49. # # Set Dataloader
  50. # vid_path, vid_writer = None, None
  51. # if webcam:
  52. # view_img = True
  53. # cudnn.benchmark = True # set True to speed up constant image size inference
  54. # dataset = LoadStreams(source, img_size=imgsz)
  55. # else:
  56. # save_img = True
  57. # view_img = False
  58. # dataset = LoadImages(source, img_size=imgsz)
  59. #
  60. # # Get names and colors
  61. # names = model.module.names if hasattr(model, 'module') else model.names
  62. # colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]
  63. #
  64. # # Run inference
  65. # t0 = time.time()
  66. # img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
  67. # _ = model(img.half() if half else img) if device.type != 'cpu' else None
  68. # list_file = open("detection.txt", 'w')# run once
  69. # for path, img, im0s, vid_cap in dataset:
  70. # img = torch.from_numpy(img).to(device)
  71. # img = img.half() if half else img.float() # uint8 to fp16/32
  72. # img /= 255.0 # 0 - 255 to 0.0 - 1.0
  73. # if img.ndimension() == 3:
  74. # img = img.unsqueeze(0)
  75. #
  76. # # Inference
  77. # t1 = time_synchronized()
  78. # pred = model(img, augment='store_true')[0]
  79. #
  80. # # Apply NMS
  81. # pred = non_max_suppression(pred, 0.4,0.5, agnostic='store_true')
  82. # t2 = time_synchronized()
  83. #
  84. # # # Apply Classifier
  85. # # if classify:
  86. # # pred = apply_classifier(pred, modelc, img, im0s)
  87. #
  88. # # Process detections
  89. # for i, det in enumerate(pred): # detections per image
  90. # if webcam: # batch_size >= 1
  91. # p, s, im0 = path[i], '%g: ' % i, im0s[i].copy()
  92. # else:
  93. # p, s, im0 = path, '', im0s
  94. #
  95. # save_path = str(Path(out) / Path(p).name)
  96. # txt_path = str(Path(out) / Path(p).stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '')
  97. # s += '%gx%g ' % img.shape[2:] # print string
  98. # gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh
  99. # if det is not None and len(det):
  100. # # Rescale boxes from img_size to im0 size
  101. # det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
  102. #
  103. # # Print results
  104. # for c in det[:, -1].unique():
  105. # n = (det[:, -1] == c).sum() # detections per class
  106. # s += '%g %ss, ' % (n, names[int(c)]) # add to string
  107. #
  108. # # Write results
  109. #
  110. #
  111. # for *xyxy, conf, cls in reversed(det):
  112. # if save_txt: # Write to file
  113. # xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
  114. # with open(txt_path + '.txt', 'a') as f:
  115. # f.write(('%g ' * 5 + '\n') % (cls, *xywh))
  116. #
  117. # # label format
  118. #
  119. # if save_img or view_img: # Add bbox to image
  120. # label = '%s %.2f' % (names[int(cls)], conf)
  121. # plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
  122. #
  123. # # Print time (inference + NMS)
  124. # # with open(os.getcwd()+'output.txt','w') as f:
  125. # # f.write('%sDone. (%.3fs)' % (s, t2 - t1))
  126. #
  127. # list_file.write('%sDone. (%.3fs)' % (s, t2 - t1))
  128. # list_file.write('\n')
  129. # print('%sDone. (%.3fs)' % (s, t2 - t1))
  130. #
  131. # # Stream results
  132. # if view_img:
  133. # cv2.imshow(p, im0)
  134. # if cv2.waitKey(1) == ord('q'): # q to quit
  135. # raise StopIteration
  136. #
  137. # # Save results (image with detections)
  138. # if save_img:
  139. # if dataset.mode == 'images':
  140. # cv2.imwrite(save_path, im0)
  141. # else:
  142. # if vid_path != save_path: # new video
  143. # vid_path = save_path
  144. # if isinstance(vid_writer, cv2.VideoWriter):
  145. # vid_writer.release() # release previous video writer
  146. #
  147. # fourcc = 'mp4v' # output video codec
  148. # fps = vid_cap.get(cv2.CAP_PROP_FPS)
  149. # w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  150. # h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  151. # vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
  152. # vid_writer.write(im0)
  153. #
  154. # if save_txt or save_img:
  155. # print('Results saved to %s' % Path(out))
  156. # # if platform.system() == 'Darwin' and not opt.update: # MacOS
  157. # # os.system('open ' + save_path)
  158. #
  159. # print('Done. (%.3fs)' % (time.time() - t0))
  160. def detect(save_img=False):
  161. out, source, weights, view_img, save_txt, imgsz = \
  162. opt.output, opt.source, opt.weights, opt.view_img, opt.save_txt, opt.img_size
  163. webcam = source.isnumeric() or source.startswith('rtsp') or source.startswith('http') or source.endswith('.txt')
  164. print('-----')
  165. print(source)
  166. print(type(source))
  167. # Initialize
  168. set_logging()
  169. device = select_device(opt.device)
  170. if os.path.exists(out):
  171. shutil.rmtree(out) # delete output folder
  172. os.makedirs(out) # make new output folder
  173. half = device.type != 'cpu' # half precision only supported on CUDA
  174. # Load model
  175. model = attempt_load(weights, map_location=device) # load FP32 model
  176. imgsz = check_img_size(imgsz, s=model.stride.max()) # check img_size
  177. if half:
  178. model.half() # to FP16
  179. # Second-stage classifier
  180. classify = False
  181. if classify:
  182. modelc = load_classifier(name='resnet101', n=2) # initialize
  183. modelc.load_state_dict(torch.load('weights/resnet101.pt', map_location=device)['model']) # load weights
  184. modelc.to(device).eval()
  185. # Set Dataloader
  186. vid_path, vid_writer = None, None
  187. if webcam:
  188. view_img = True
  189. cudnn.benchmark = True # set True to speed up constant image size inference
  190. dataset = LoadStreams(source, img_size=imgsz)
  191. else:
  192. save_img = True
  193. dataset = LoadImages(source, img_size=imgsz)
  194. # Get names and colors
  195. names = model.module.names if hasattr(model, 'module') else model.names
  196. colors = [[random.randint(0, 255) for _ in range(3)] for _ in range(len(names))]
  197. # Run inference
  198. t0 = time.time()
  199. img = torch.zeros((1, 3, imgsz, imgsz), device=device) # init img
  200. _ = model(img.half() if half else img) if device.type != 'cpu' else None # run once
  201. for path, img, im0s, vid_cap in dataset:
  202. print('path:{0}'.format(path))
  203. print('im0s:{0}'.format(im0s))
  204. print('im0s类型:{0}'.format(type(im0s)))
  205. img = torch.from_numpy(img).to(device)
  206. img = img.half() if half else img.float() # uint8 to fp16/32
  207. img /= 255.0 # 0 - 255 to 0.0 - 1.0
  208. if img.ndimension() == 3:
  209. img = img.unsqueeze(0)
  210. # Inference
  211. t1 = time_synchronized()
  212. pred = model(img, augment=opt.augment)[0]
  213. # Apply NMS
  214. pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, classes=opt.classes, agnostic=opt.agnostic_nms)
  215. t2 = time_synchronized()
  216. # Apply Classifier
  217. if classify:
  218. pred = apply_classifier(pred, modelc, img, im0s)
  219. # 用于存储人员边界坐标的列表 ---linjie
  220. people_coords = []
  221. # Process detections
  222. for i, det in enumerate(pred): # detections per image
  223. if webcam: # batch_size >= 1
  224. p, s, im0 = path[i], '%g: ' % i, im0s[i].copy()
  225. else:
  226. p, s, im0 = path, '', im0s
  227. save_path = str(Path(out) / Path(p).name)
  228. txt_path = str(Path(out) / Path(p).stem) + ('_%g' % dataset.frame if dataset.mode == 'video' else '')
  229. s += '%gx%g ' % img.shape[2:] # print string
  230. gn = torch.tensor(im0.shape)[[1, 0, 1, 0]] # normalization gain whwh
  231. if det is not None and len(det):
  232. # print('先看看这里能不能进行,再看看im0多少:{0}。再看看im0类型:{1}'.format(im0,type(im0)))
  233. # Rescale boxes from img_size to im0 size
  234. det[:, :4] = scale_coords(img.shape[2:], det[:, :4], im0.shape).round()
  235. # Print results
  236. for c in det[:, -1].unique():
  237. n = (det[:, -1] == c).sum() # detections per class
  238. s += '%g %ss, ' % (n, names[int(c)]) # add to string
  239. # Write results
  240. for *xyxy, conf, cls in reversed(det):
  241. if save_txt: # Write to file
  242. xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist() # normalized xywh
  243. with open(txt_path + '.txt', 'a') as f:
  244. f.write(('%g ' * 5 + '\n') % (cls, *xywh)) # label format
  245. if save_img or view_img: # Add bbox to image
  246. label = '%s %.2f' % (names[int(cls)], conf)
  247. plot_one_box(xyxy, im0, label=label, color=colors[int(cls)], line_thickness=3)
  248. #判断标签是否为人 --linjie
  249. if label is not None:
  250. if (label.split())[0] == 'person':
  251. print('标签是人')
  252. distancing(people_coords, im0, dist_thres_lim=(200, 250))
  253. people_coords.append(xyxy)
  254. # plot_one_box(xyxy, im0, line_thickness=3)
  255. plot_dots_on_people(xyxy, im0)
  256. # 画上人与人的连接线 --linjie
  257. distancing(people_coords, im0, dist_thres_lim=(200, 250))
  258. # Print time (inference + NMS)
  259. print('%sDone. (%.3fs)' % (s, t2 - t1))
  260. # Stream results
  261. if view_img:
  262. cv2.imshow(p, im0)
  263. if cv2.waitKey(1) == ord('q'): # q to quit
  264. raise StopIteration
  265. # Save results (image with detections)
  266. if save_img:
  267. if dataset.mode == 'images':
  268. cv2.imwrite(save_path, im0)
  269. else:
  270. if vid_path != save_path: # new video
  271. vid_path = save_path
  272. if isinstance(vid_writer, cv2.VideoWriter):
  273. vid_writer.release() # release previous video writer
  274. fourcc = 'mp4v' # output video codec
  275. fps = vid_cap.get(cv2.CAP_PROP_FPS)
  276. w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  277. h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  278. vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*fourcc), fps, (w, h))
  279. vid_writer.write(im0)
  280. if save_txt or save_img:
  281. print('Results saved to %s' % Path(out))
  282. if platform == 'Darwin' and not opt.update: # MacOS
  283. os.system('open ' + save_path)
  284. print('Done. (%.3fs)' % (time.time() - t0))
  285. if __name__ == '__main__':
  286. parser = argparse.ArgumentParser()
  287. parser.add_argument('--weights', nargs='+', type=str, default='best.pt', help='model.pt path(s)')
  288. parser.add_argument('--source', type=str, default='inference/output/distince', help='source') # file/folder, 0 for webcam
  289. parser.add_argument('--output', type=str, default='inference/output/mask', help='output folder') # output folder
  290. parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
  291. parser.add_argument('--conf-thres', type=float, default=0.4, help='object confidence threshold')
  292. parser.add_argument('--iou-thres', type=float, default=0.5, help='IOU threshold for NMS')
  293. parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
  294. parser.add_argument('--view-img', action='store_true', help='display results')
  295. parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
  296. parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
  297. parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
  298. parser.add_argument('--augment', action='store_true', help='augmented inference')
  299. parser.add_argument('--update', action='store_true', help='update all models')
  300. opt = parser.parse_args()
  301. print(opt)
  302. with torch.no_grad():
  303. if opt.update: # update all models (to fix SourceChangeWarning)
  304. for opt.weights in ['yolov5s.pt', 'yolov5m.pt', 'yolov5l.pt', 'yolov5x.pt']:
  305. print('model1')
  306. detect()
  307. strip_optimizer(opt.weights)
  308. else:
  309. print('model2')
  310. detect()

随着人工智能和大数据的发展,任一方面对自动化工具有着一定的需求,在当下疫情防控期间,使用mindspore来实现yolo模型来进行目标检测及语义分割,对视频或图片都可以进行口罩佩戴检测和行人社交距离检测,来对公共场所的疫情防控来实行自动化管理。