0


[深度学习]人工智能本科毕业设计基于yolov5的步态识别多目标跨镜头跟踪检测算法系统源码+实现过程

毕业设计题目:基于步态识别的多目标跨镜头跟踪算法研究 主算法:基于yoloV5-deepsort框架进行目标检测和跟踪+GaitSet算法

效果演示:

介绍

此存储库包含一个高度可配置的两阶段跟踪器,可根据不同的部署场景进行调整。YOLOv5是一系列在COCO数据集上预训练的对象检测架构和模型,它生成的检测结果被传递给跟踪对象的深度排序算法。它可以跟踪Yolov5模型训练用来检测的任何对象。

教程

Yolov5自定义数据培训(链接到外部存储库)

DeepSort深度描述符训练(链接到外部存储库)

Yolov5-pytorch评估

在运行跟踪器之前

如果您已经克隆并忘记使用--recurse子模块,则可以运行git-submodule update--init

确保满足所有要求:Python 3.8或更高版本,安装了所有requirements.txt依赖项,包括torch>=1.7。要安装,请运行:

pip install-r requirements.txt

追踪源

视频推理

  1. $ python track.py --source 0 # webcam
  2. img.jpg # image
  3. vid.mp4 # video
  4. path/ # directory
  5. path/*.jpg # glob
  6. 'https://youtu.be/Zgi9g1ksQHc' # YouTube
  7. 'rtsp://example.com/media.mp4' # RTSP, RTMP, HTTP stream

选择对象检测和ReID模型

Yolov5

模型推理速度和准确性之间存在明显的权衡。为了满足您的推理速度/准确性需求,您可以选择Yolov5模型进行自动下载

  1. python track.py --source 0 --yolo_model yolov5n.pt --img 640
  2. yolov5s.pt
  3. yolov5m.pt
  4. yolov5l.pt
  5. yolov5x.pt --img 1280
  6. ...

DeepSort

以上内容也适用于DeepSort模型。根据您的需求从ReID模型动物园选择ReID模型

  1. python track.py --source 0 --deep_sort_model osnet_x0_5_market1501
  2. resnet50_MSMT17
  3. mobilenetv2_x1_4_dukemtmcreid
  4. ...

筛选跟踪的类

默认情况下,跟踪器跟踪所有MS COCO类。

如果你只想跟踪别人,我建议你使用这些重量来提高表现

  1. python3 track.py --source 0 --yolo_model yolov5/weights/crowdhuman_yolov5m.pt --classes 0 # tracks persons, only

如果要跟踪MS COCO类的子集,请在classes标志后面添加它们相应的索引

  1. python3 track.py --source 0 --yolo_model yolov5s.pt --classes 16 17 # tracks cats and dogs, only

以下是在MS COCO上训练的Yolov5模型可以检测到的所有可能对象的列表。请注意,此repo中类的索引从零开始。

符合MOT的结果

可以通过保存到您的实验文件夹track/exN

python3 track.py--source --save-txt

核心代码track.py

  1. # limit the number of cpus used by high performance libraries
  2. import os
  3. os.environ["OMP_NUM_THREADS"] = "1"
  4. os.environ["OPENBLAS_NUM_THREADS"] = "1"
  5. os.environ["MKL_NUM_THREADS"] = "1"
  6. os.environ["VECLIB_MAXIMUM_THREADS"] = "1"
  7. os.environ["NUMEXPR_NUM_THREADS"] = "1"
  8. import sys
  9. sys.path.insert(0, './yolov5')
  10. import argparse
  11. import os
  12. import platform
  13. import shutil
  14. import time
  15. from pathlib import Path
  16. import cv2
  17. import torch
  18. import torch.backends.cudnn as cudnn
  19. from yolov5.models.experimental import attempt_load
  20. from yolov5.utils.downloads import attempt_download
  21. from yolov5.models.common import DetectMultiBackend
  22. from yolov5.utils.datasets import LoadImages, LoadStreams
  23. from yolov5.utils.general import (LOGGER, check_img_size, non_max_suppression, scale_coords,
  24. check_imshow, xyxy2xywh, increment_path)
  25. from yolov5.utils.torch_utils import select_device, time_sync
  26. from yolov5.utils.plots import Annotator, colors, save_one_box,save_one_boxmod
  27. from deep_sort.utils.parser import get_config
  28. from deep_sort.deep_sort import DeepSort
  29. FILE = Path(__file__).resolve()
  30. ROOT = FILE.parents[0] # yolov5 deepsort root directory
  31. if str(ROOT) not in sys.path:
  32. sys.path.append(str(ROOT)) # add ROOT to PATH
  33. ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative
  34. def detect(opt):
  35. out, source, yolo_model, deep_sort_model, show_vid, save_vid, save_txt, imgsz, evaluate, half, project, name, exist_ok= \
  36. opt.output, opt.source, opt.yolo_model, opt.deep_sort_model, opt.show_vid, opt.save_vid, \
  37. opt.save_txt, opt.imgsz, opt.evaluate, opt.half, opt.project, opt.name, opt.exist_ok
  38. webcam = source == '0' or source.startswith(
  39. 'rtsp') or source.startswith('http') or source.endswith('.txt')
  40. device = select_device(opt.device)
  41. # initialize deepsort
  42. cfg = get_config()
  43. cfg.merge_from_file(opt.config_deepsort)
  44. deepsort = DeepSort(deep_sort_model,
  45. device,
  46. max_dist=cfg.DEEPSORT.MAX_DIST,
  47. max_iou_distance=cfg.DEEPSORT.MAX_IOU_DISTANCE,
  48. max_age=cfg.DEEPSORT.MAX_AGE, n_init=cfg.DEEPSORT.N_INIT, nn_budget=cfg.DEEPSORT.NN_BUDGET,
  49. )
  50. # Initialize
  51. half &= device.type != 'cpu' # half precision only supported on CUDA
  52. # The MOT16 evaluation runs multiple inference streams in parallel, each one writing to
  53. # its own .txt file. Hence, in that case, the output folder is not restored
  54. if not evaluate:
  55. if os.path.exists(out):
  56. pass
  57. shutil.rmtree(out) # delete output folder
  58. os.makedirs(out) # make new output folder
  59. # Directories
  60. if type(yolo_model) is str:
  61. exp_name = yolo_model.split(".")[0]
  62. elif type(yolo_model) is list and len(yolo_model) == 1:
  63. exp_name = yolo_model[0].split(".")[0]
  64. else:
  65. exp_name = "ensemble"
  66. exp_name = exp_name + "_" + deep_sort_model.split('/')[-1].split('.')[0]
  67. save_dir = increment_path(Path(project) / "out", exist_ok=exist_ok) # increment run if project name exists
  68. save_dir.mkdir(parents=True, exist_ok=True) # make dir
  69. # Load model
  70. device = select_device(device)
  71. model = DetectMultiBackend(yolo_model, device=device, dnn=opt.dnn)
  72. stride, names, pt, jit, _ = model.stride, model.names, model.pt, model.jit, model.onnx
  73. imgsz = check_img_size(imgsz, s=stride) # check image size
  74. # Half
  75. half &= pt and device.type != 'cpu' # half precision only supported by PyTorch on CUDA
  76. if pt:
  77. model.model.half() if half else model.model.float()
  78. # Set Dataloader
  79. vid_path, vid_writer = None, None
  80. # Check if environment supports image displays
  81. if show_vid:
  82. show_vid = check_imshow()
  83. # Dataloader
  84. if webcam:
  85. show_vid = check_imshow()
  86. cudnn.benchmark = True # set True to speed up constant image size inference
  87. dataset = LoadStreams(source, img_size=imgsz, stride=stride, auto=pt and not jit)
  88. bs = len(dataset) # batch_size
  89. else:
  90. dataset = LoadImages(source, img_size=imgsz, stride=stride, auto=pt and not jit)
  91. bs = 1 # batch_size
  92. vid_path, vid_writer = [None] * bs, [None] * bs
  93. # Get names and colors
  94. names = model.module.names if hasattr(model, 'module') else model.names
  95. # extract what is in between the last '/' and last '.'
  96. txt_file_name = source.split('/')[-1].split('.')[0]
  97. txt_path = str(Path(save_dir)) + '/' + txt_file_name + '.txt'
  98. if pt and device.type != 'cpu':
  99. model(torch.zeros(1, 3, *imgsz).to(device).type_as(next(model.model.parameters()))) # warmup
  100. dt, seen = [0.0, 0.0, 0.0, 0.0], 0
  101. index = 1
  102. for frame_idx, (path, img, im0s, vid_cap, s) in enumerate(dataset):
  103. t1 = time_sync()
  104. img = torch.from_numpy(img).to(device)
  105. img = img.half() if half else img.float() # uint8 to fp16/32
  106. img /= 255.0 # 0 - 255 to 0.0 - 1.0
  107. if img.ndimension() == 3:
  108. img = img.unsqueeze(0)
  109. t2 = time_sync()
  110. dt[0] += t2 - t1
  111. # Inference yolo处理
  112. visualize = increment_path(save_dir / Path(path[0]).stem, mkdir=True) if opt.visualize else False
  113. pred = model(img, augment=opt.augment, visualize=visualize)
  114. t3 = time_sync()
  115. dt[1] += t3 - t2
  116. # Apply NMS
  117. pred = non_max_suppression(pred, opt.conf_thres, opt.iou_thres, opt.classes, opt.agnostic_nms, max_det=opt.max_det)
  118. dt[2] += time_sync() - t3
  119. # Process detections
  120. for i, det in enumerate(pred): # detections per image
  121. seen += 1
  122. if webcam: # batch_size >= 1
  123. p, im0, _ = path[i], im0s[i].copy(), dataset.count
  124. s += f'{i}: '
  125. else:
  126. p, im0, _ = path, im0s.copy(), getattr(dataset, 'frame', 0)
  127. p = Path(p) # to Path
  128. save_path = str(save_dir / p.name) # im.jpg, vid.mp4, ...
  129. s += '%gx%g ' % img.shape[2:] # print string
  130. imc = im0.copy()
  131. # 画框
  132. annotator = Annotator(im0, line_width=1, pil=not ascii)
  133. if det is not None and len(det):
  134. # Rescale boxes from img_size to im0 size
  135. det[:, :4] = scale_coords(
  136. img.shape[2:], det[:, :4], im0.shape).round()
  137. # Print results
  138. for c in det[:, -1].unique():
  139. n = (det[:, -1] == c).sum() # detections per class
  140. s += f"{n} {names[int(c)]}{'s' * (n > 1)}, " # add to string
  141. xywhs = xyxy2xywh(det[:, 0:4])
  142. confs = det[:, 4]
  143. clss = det[:, 5]
  144. # Deepsort 处理 pass detections to deepsort
  145. t4 = time_sync()
  146. outputs = deepsort.update(xywhs.cpu(), confs.cpu(), clss.cpu(), im0)
  147. t5 = time_sync()
  148. dt[3] += t5 - t4
  149. # index = 0
  150. # for *xyxy, conf, cls in reversed(det):
  151. # save_one_box(xyxy, imc, file=save_dir / 'person' /str(output[4])/ f'{index}.jpg', BGR=True)
  152. # index = index + 1
  153. # draw boxes for visualization
  154. if len(outputs) > 0:
  155. for j, (output, conf) in enumerate(zip(outputs, confs)):
  156. bboxes = output[0:4]
  157. # 这里的ID就是画面中任务头上的ID
  158. id = output[4]
  159. cls = output[5]
  160. c = int(cls) # integer class
  161. label = f'{id} {names[c]} {conf:.2f}'
  162. # Todo 保存每一帧检测框中的图片
  163. bgrImg = cv2.imread('./data/back.jpg')
  164. # print(bgrImg)
  165. # save_one_box(bboxes, imc,file=save_dir / 'person' / str(id)/ f'{index}.jpg', BGR=True)
  166. save_one_boxmod(bboxes, imc,bgrImg,file=save_dir / 'person' / str(id)/ 'temp'/f'{index}.jpg',
  167. lasted=save_dir / 'person' / str(id)/f'{index}.jpg', BGR=True)
  168. index = index+1
  169. # 画标记
  170. annotator.box_label(bboxes, label, color=colors(c, True))
  171. if save_txt:
  172. # to MOT format
  173. bbox_left = output[0]
  174. bbox_top = output[1]
  175. bbox_w = output[2] - output[0]
  176. bbox_h = output[3] - output[1]
  177. # Write MOT compliant results to file
  178. with open(txt_path, 'a') as f:
  179. f.write(('%g ' * 10 + '\n') % (frame_idx + 1, id, bbox_left, # MOT format
  180. bbox_top, bbox_w, bbox_h, -1, -1, -1, -1))
  181. LOGGER.info(f'{s}Done. YOLO:({t3 - t2:.3f}s), DeepSort:({t5 - t4:.3f}s)')
  182. else:
  183. deepsort.increment_ages()
  184. LOGGER.info('No detections')
  185. # Stream results
  186. im0 = annotator.result()
  187. if show_vid:
  188. cv2.imshow(str(p), im0)
  189. if cv2.waitKey(1) == ord('q'): # q to quit
  190. raise StopIteration
  191. # Save results (image with detections)
  192. if save_vid:
  193. if vid_path != save_path: # new video
  194. vid_path = save_path
  195. if isinstance(vid_writer, cv2.VideoWriter):
  196. vid_writer.release() # release previous video writer
  197. if vid_cap: # video
  198. fps = vid_cap.get(cv2.CAP_PROP_FPS)
  199. w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
  200. h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
  201. else: # stream
  202. fps, w, h = 30, im0.shape[1], im0.shape[0]
  203. vid_writer = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
  204. vid_writer.write(im0)
  205. # Print results
  206. t = tuple(x / seen * 1E3 for x in dt) # speeds per image
  207. LOGGER.info(f'Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS, %.1fms deep sort update \
  208. per image at shape {(1, 3, *imgsz)}' % t)
  209. if save_txt or save_vid:
  210. print('Results saved to %s' % save_path)
  211. if platform == 'darwin': # MacOS
  212. os.system('open ' + save_path)
  213. if __name__ == '__main__':
  214. parser = argparse.ArgumentParser()
  215. parser.add_argument('--yolo_model', nargs='+', type=str, default='yolov5m.pt', help='model.pt path(s)')
  216. parser.add_argument('--deep_sort_model', type=str, default='osnet_ibn_x1_0_MSMT17')
  217. parser.add_argument('--source', type=str, default='0', help='source') # file/folder, 0 for webcam
  218. parser.add_argument('--output', type=str, default='inference/output', help='output folder') # output folder
  219. parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
  220. parser.add_argument('--conf-thres', type=float, default=0.5, help='object confidence threshold')
  221. parser.add_argument('--iou-thres', type=float, default=0.5, help='IOU threshold for NMS')
  222. parser.add_argument('--fourcc', type=str, default='mp4v', help='output video codec (verify ffmpeg support)')
  223. parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
  224. parser.add_argument('--show-vid', action='store_true', help='display tracking video results')
  225. parser.add_argument('--save-vid', action='store_true', help='save video tracking results')
  226. parser.add_argument('--save-txt', action='store_true', help='save MOT compliant results to *.txt')
  227. # class 0 is person, 1 is bycicle, 2 is car... 79 is oven
  228. parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 16 17')
  229. parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
  230. parser.add_argument('--augment', action='store_true', help='augmented inference')
  231. parser.add_argument('--evaluate', action='store_true', help='augmented inference')
  232. parser.add_argument("--config_deepsort", type=str, default="deep_sort/configs/deep_sort.yaml")
  233. parser.add_argument("--half", action="store_true", help="use FP16 half-precision inference")
  234. parser.add_argument('--visualize', action='store_true', help='visualize features')
  235. parser.add_argument('--max-det', type=int, default=1000, help='maximum detection per image')
  236. parser.add_argument('--dnn', action='store_true', help='use OpenCV DNN for ONNX inference')
  237. parser.add_argument('--project', default=ROOT / 'runs/track', help='save results to project/name')
  238. parser.add_argument('--name', default='exp', help='save results to project/name')
  239. parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
  240. opt = parser.parse_args()
  241. opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1 # expand
  242. with torch.no_grad():
  243. detect(opt)

完整代码下载地址:https://download.csdn.net/download/FL1768317420/89232934


本文转载自: https://blog.csdn.net/FL1768317420/article/details/139016996
版权归原作者 FL1768317420 所有, 如有侵权,请联系我们删除。

“[深度学习]人工智能本科毕业设计基于yolov5的步态识别多目标跨镜头跟踪检测算法系统源码+实现过程”的评论:

还没有评论