yolov5-deepsort代码精读(三)

利用pycharm阅读代码,进行Debug

objdetector.py 注释

import torch
import numpy as np
from models.experimental import attempt_load
from utils.general import non_max_suppression, scale_coords
from utils.datasets import letterbox
from utils.torch_utils import select_device

import objtracker

# 要检测的类别,这里只检测人,车(小车、巴士、卡车)
OBJ_LIST = ['person', 'car', 'bus', 'truck']
# yolov5模型
DETECTOR_PATH = 'weights/yolov5m.pt'

class baseDet(object):
    def __init__(self):
        self.img_size = 640
        self.threshold = 0.3
        self.stride = 1

    def build_config(self):
        # 帧数统计变量初始化
        self.frameCounter = 0

    def feedCap(self, im, func_status):
        # 初始化dict,用于返回结果, 在这里初始化了键list_of_ids, 但后面没用到
        retDict = {
            'frame': None,
            'list_of_ids': None,
            'obj_bboxes': []
        }
        # 帧数统计
        self.frameCounter += 1
        # feed to 检测器+deepsort,  注意第一个参数self《=》det. 返回带绘制检测+deepsort结果的im,和检测+deepsort结果信息:[(x1, y1, x2, y2, '', track_id),...,(...)]
        im, obj_bboxes = objtracker.update(self, im)
        retDict['frame'] = im
        retDict['obj_bboxes'] = obj_bboxes

        return retDict

    def init_model(self):
        raise EOFError("Undefined model type.")

    def preprocess(self):
        raise EOFError("Undefined model type.")

    def detect(self):
        raise EOFError("Undefined model type.")

# 定义类Detector,继承自baseDet
class Detector(baseDet):
    # 构造函数
    def __init__(self):
        # 调用父类构造函数初始化继承自父类的属性,具体是父类构造函数中定义的属性
        super(Detector, self).__init__()
        # 调用init_model方法
        self.init_model()
        # 调用父类方法
        self.build_config()

    def init_model(self):
        # 权重文件 yolov5s.pt
        self.weights = DETECTOR_PATH
        # 选择使用gpu or cpu,我这里会使用cpu
        self.device = '0' if torch.cuda.is_available() else 'cpu'
        # yolov5中提供的select_device方法直接复用
        self.device = select_device(self.device)
        # 加载权重文件
        model = attempt_load(self.weights, map_location=self.device)
        # 将model transfer to device, 推理阶段使用model.eval() 训练阶段使用model.train()
        model.to(self.device).eval()
        # GPU支持半精度
        #model.half()
        # 使用cpu时不支持.half,改为.float(), 这里比较奇怪,我明明有gpu但选择的cpu,后面再细究
        model.float()
        self.m = model
        # 模型能够检测的所有类别标签。yolov5中提供的方法直接复用
        self.names = model.module.names if hasattr(
            model, 'module') else model.names

    def preprocess(self, img):
        # 对原图进行拷贝
        img0 = img.copy()
        # yolov5图像预处理之lettexbox, [1080,1920,3]->[384,640,3]
        img = letterbox(img, new_shape=self.img_size)[0]
        # [384,640,3] -> [3,384,640]
        img = img[:, :, ::-1].transpose(2, 0, 1)
        # 在内存上使用连续的内存存储图像
        img = np.ascontiguousarray(img)
        # 由numpy array创建torch Tensor; transfer to device
        img = torch.from_numpy(img).to(self.device)
        #img = img.half()  # 半精度
        img = img.float()
        img /= 255.0  # 图像归一化
        # [3,384,640] -> [1,3,384,640]
        if img.ndimension() == 3:
            img = img.unsqueeze(0)
        # 返回原图像img0和预处理之后的图像img
        return img0, img

    def detect(self, im):
        # 图像预处理,返回原图im0,预处理之后的图像img
        im0, img = self.preprocess(im)
        # feed to yolov5 进行检测,调用yolo.py Class Model中的forward方法。返回检测结果
        pred = self.m(img, augment=False)[0]
        pred = pred.float()
        # NMS
        pred = non_max_suppression(pred, self.threshold, 0.4)
        # 初始化返回结果
        pred_boxes = []
        # yolov5检测结果解析,yolov5源码方法复用
        for det in pred:
            if det is not None and len(det):
                # 调整检测框坐标。检测框是基于预处理后640x640的图像的,调整为基于原图的检测框
                det[:, :4] = scale_coords(
                    img.shape[2:], det[:, :4], im0.shape).round()
                for *x, conf, cls_id in det:
                    lbl = self.names[int(cls_id)]
                    # 筛选出要检测的类别,过滤掉其它类别
                    if not lbl in OBJ_LIST:
                        continue
                    x1, y1 = int(x[0]), int(x[1])
                    x2, y2 = int(x[2]), int(x[3])
                    # 检测框坐标(左上右下),类别标签,置信度
                    pred_boxes.append(
                        (x1, y1, x2, y2, lbl, conf))
        # 返回原图,检测结果 pred_boxes:[(...),(,,,), ... ,(...)]
        return im, pred_boxes

你可能感兴趣的:(tracking,pytorch,python,深度学习)