Exemple #1
0
    def __init__(self, opt, frame_rate=30):             # 帧率的意义
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv)           # 加载模型,
        self.model = load_model(self.model, opt.load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]         # 保存一系列追踪中的轨迹
        self.lost_stracks = []  # type: list[STrack]            # 保存已经丢失的轨迹
        self.removed_stracks = []  # type: list[STrack]         # 保存已经移除的轨迹

        self.frame_id = 0
        self.det_thresh = opt.conf_thres                        # 检测框阈值,这里设置为与tracking的置信度阈值相同
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)            # 还是等于输入视频的真实帧率
        self.max_time_lost = self.buffer_size                   # 最大连续self.buffer_size次没有匹配到目标时,表示该轨迹丢失
        self.max_per_image = 128
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()         # 预测,根据上一帧目标的检测位置和速度,预测当前帧目标的检测位置和速度
def kalman_predict_out_line(track,line,out_direction):
    # print(track.track_id)
    # print(line)
    # print(out_direction)
    # print(track.tlbr)
    if box_line_relative(track.tlbr,line)==out_direction:
        return 0
    predict_num_out=0
    prev_mean,prev_cov=track.mean,track.covariance
    kal_man=KalmanFilter()
    predict_thres=0 if out_direction=='up' else 0
    max_long_predict=5 if out_direction=='up' else 2 if track.infer_type() in ['person','motorcycle','biycycle'] else 8
    while  box_line_relative(mean_to_tlbr(prev_mean),line) !=out_direction:
        predict_num_out+=1
        cur_mean=prev_mean #of t
        mean,cov=kal_man.predict(prev_mean,prev_cov)
        if predict_num_out>predict_thres:
            new_mean,new_cov=mean,cov
        else:
            new_mean,new_cov= kal_man.update(prev_mean,prev_cov,mean[:4])
        prev_mean,prev_cov=new_mean,new_cov #of t+1
        if predict_num_out>=max_long_predict or np.sum(np.abs(cur_mean-mean))==0:
            break
        # print(mean_to_tlbr(mean))

    return predict_num_out
Exemple #3
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv)
        self.model = load_model(self.model, opt.load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
        self.roi_align = RoIAlign(7, 7)
        cfg = get_config()
        cfg.merge_from_file(
            "/home/hongwei/track-human/FairMOT/src/lib/tracker/deep_configs/yolov3.yaml"
        )
        cfg.merge_from_file(
            "/home/hongwei/track-human/FairMOT/src/lib/tracker/deep_configs/deep_sort.yaml"
        )
        self.detector = build_detector(cfg, True)
Exemple #4
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv)
        self.model = load_model(self.model, opt.load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        # convert to onnx
        # input_names = ["input0"]
        # output_names = ["hm", "wh", "id", "reg"]
        # inputs = torch.randn(1, 3, 480, 640).to('cpu')
        # torch_out = torch.onnx._export(self.model, inputs, 'pruned.onnx', export_params=True, verbose=False,
        #                                input_names=input_names, output_names=output_names)
        # print("export onnx sucess")

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
Exemple #5
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv)
        self.model = load_model(self.model, opt.load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        # input = torch.randn(1, 3, 640, 640, requires_grad=True)
        # input=input.to(opt.device)
        # out = self.model(input)
        # torch.onnx.export(self.model,  # model being run
        #                   input,  # model input (or a tuple for multiple inputs)
        #                   "./test.onnx",  # where to save the model (can be a file or file-like object)
        #                   export_params=True,  # store the trained parameter weights inside the model file# )
        #                   opset_version=9
        #                   )

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
Exemple #6
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv)
        self.model = load_model(self.model, opt.load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = 128
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
def kalman_predict_out_line(track, line, out_direction, predict_long=None):
    # print(track.track_id)
    # print(line)
    # print(out_direction)
    # print(track.tlbr)
    if box_line_relative(track.tlbr, line) == out_direction:
        return 0
    predict_num_out = 0
    prev_mean, prev_cov = track.mean, track.covariance
    kal_man = KalmanFilter()
    predict_thres = 15 if out_direction == 'up' else 0
    if predict_long is not None:
        max_long_predict = predict_long
    else:
        max_long_predict = 50 if out_direction == 'up' else 4
    while box_line_relative(mean_to_tlbr(prev_mean), line) != out_direction:
        predict_num_out += 1
        cur_mean = prev_mean  #of t
        mean, cov = kal_man.predict(prev_mean, prev_cov)
        if predict_num_out > predict_thres:
            new_mean, new_cov = mean, cov
        else:
            new_mean, new_cov = kal_man.update(prev_mean, prev_cov, mean[:4])
        prev_mean, prev_cov = new_mean, new_cov  #of t+1
        if predict_num_out >= max_long_predict or np.sum(
                np.abs(cur_mean - mean)) == 0:
            break
        # print(mean_to_tlbr(mean))

    return predict_num_out
Exemple #8
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        self.model = create_model(opt.arch, opt.heads, opt.head_conv,
                                  num_gnn_layers=opt.num_gnn_layers,
                                  gnn_type=opt.gnn_type,
                                  use_residual=opt.use_residual,
                                  return_pre_gnn_layer_outputs=opt.return_pre_gnn_layer_outputs,
                                  heads_share_params=opt.heads_share_params,
                                  omit_gnn=opt.omit_gnn,
                                  use_roi_align=opt.use_roi_align,
                                  viz_attention=opt.viz_attention)

        self.model = load_model(self.model, opt.load_model, distributed=True, copy_head_weights=False)
        self.model = self.model.to(opt.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        # self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
        self.viz_attention = opt.viz_attention
Exemple #9
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt
        if opt.use_hog_reid:
            print('USE HOG AS FEATURE EXTRACTION !!!!')
            self.re_im_h, self.re_im_w = 300, 120
            cell_size = (50, 24)
            block_size = (6, 5)
            nbins = 9
            self.reid_model = cv2.HOGDescriptor(
                _winSize=(self.re_im_w // cell_size[1] * cell_size[1],
                          self.re_im_h // cell_size[0] * cell_size[0]),
                _blockSize=(block_size[1] * cell_size[1],
                            block_size[0] * cell_size[0]),
                _blockStride=(cell_size[1], cell_size[0]),
                _cellSize=(cell_size[1], cell_size[0]),
                _nbins=nbins)

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size

        self.prev_img = None

        self.kalman_filter = KalmanFilter()
Exemple #10
0
    def reset(self):
        """
        :return:
        """
        # Reset tracks dict
        self.tracked_tracks_dict = defaultdict(list)  # value type: list[Track]
        self.lost_tracks_dict = defaultdict(list)  # value type: list[Track]
        self.removed_tracks_dict = defaultdict(list)  # value type: list[Track]

        # Reset frame id
        self.frame_id = 0

        # Reset kalman filter to stabilize tracking
        self.kalman_filter = KalmanFilter()
Exemple #11
0
    def __init__(self, opt):
        self.opt = opt

        # ---------- Init model
        max_ids_dict = {
            0: 330,
            1: 102,
            2: 104,
            3: 312,
            4: 53
        }  # cls_id -> track id number for traning
        device = opt.device

        # model in track mode(do detection and reid feature vector extraction)
        self.model = Darknet(opt.cfg, opt.img_size, False, max_ids_dict, 128, 'track').to(device)

        # Load checkpoint
        if opt.weights.endswith('.pt'):  # pytorch format
            ckpt = torch.load(opt.weights, map_location=device)
            self.model.load_state_dict(ckpt['model'])
            if 'epoch' in ckpt.keys():
                print('Checkpoint of epoch {} loaded.'.format(ckpt['epoch']))
        else:  # darknet format
            load_darknet_weights(self.model, opt.weights)

        # Put model to device and set eval mode
        self.model.to(device).eval()
        # ----------

        # Define tracks dict
        self.tracked_tracks_dict = defaultdict(list)  # value type: list[Track]
        self.lost_tracks_dict = defaultdict(list)  # value type: list[Track]
        self.removed_tracks_dict = defaultdict(list)  # value type: list[Track]

        # init frame index
        self.frame_id = 0

        # init hyp
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(opt.track_buffer)
        self.max_time_lost = self.buffer_size
        # self.mean = np.array([0.408, 0.447, 0.470]).reshape(1, 1, 3)
        # self.std = np.array([0.289, 0.274, 0.278]).reshape(1, 1, 3)

        # init kalman filter(to stabilize tracking)
        self.kalman_filter = KalmanFilter()
    def __init__(self, opt, model, frame_rate=30):
        self.opt = opt
        print('Creating model...')
        self.model = model

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K
        self.mean = np.array(opt.mean, dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array(opt.std, dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
Exemple #13
0
    def __init__(self, opt, frame_rate=30):
        self.opt = opt

        print('Creating model...')
        self.model = create_model('dla_34', opt.heads, opt.head_conv)
        if opt.multi_load_model != '':
            self.model = load_model(self.model, opt.multi_load_model)
        self.model = self.model.to(opt.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K

        self.kalman_filter = KalmanFilter()
    def __init__(self, gpus, load_model_name, frame_rate=30):
        # self.opt = opt
        # if opt.gpus[0] >= 0:
        #     opt.device = torch.device('cuda')
        # else:
        #     opt.device = torch.device('cpu')
        if len(gpus) > 0:
            self.device = torch.device('cuda')
        else:
            self.device = torch.device('cpu')
        print('Creating model...')
        heads = {'hm': 1, 'wh': 4, 'id': 128, 'reg': 2}
        head_conv = 256
        self.model = create_model(heads, head_conv)
        self.model = load_model(self.model, load_model_name)
        self.model = self.model.to(self.device)
        self.model.eval()

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = 0.4
        self.buffer_size = int(frame_rate / 30.0 * 30)
        self.max_time_lost = self.buffer_size
        self.max_per_image = 500
        self.mean = np.array([0.408, 0.447, 0.47],
                             dtype=np.float32).reshape(1, 1, 3)
        self.std = np.array([0.289, 0.274, 0.278],
                            dtype=np.float32).reshape(1, 1, 3)

        self.kalman_filter = KalmanFilter()
        self.num_classes = 1
        self.down_ratio = 4
        self.reg_offset = True
        self.ltrb = True
        self.K = 500
        self.conf_thres = 0.4
Exemple #15
0
class STrack(BaseTrack):
    shared_kalman = KalmanFilter()
    def __init__(self, tlwh, score, temp_feat, buffer_size=30):

        # wait activate
        self._tlwh = np.asarray(tlwh, dtype=np.float)
        self.kalman_filter = None
        self.mean, self.covariance = None, None
        self.is_activated = False

        self.score = score
        self.tracklet_len = 0

        self.smooth_feat = None
        self.update_features(temp_feat)
        self.features = deque([], maxlen=buffer_size)
        self.alpha = 0.9

        self.history = []

    def update_features(self, feat):
        feat /= np.linalg.norm(feat)
        self.curr_feat = feat
        if self.smooth_feat is None:
            self.smooth_feat = feat
        else:
            self.smooth_feat = self.alpha * self.smooth_feat + (1 - self.alpha) * feat
        self.features.append(feat)
        self.smooth_feat /= np.linalg.norm(self.smooth_feat)

    def predict(self):
        mean_state = self.mean.copy()
        if self.state != TrackState.Tracked:
            mean_state[7] = 0
        self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance)

    @staticmethod
    def multi_predict(stracks):
        if len(stracks) > 0:
            multi_mean = np.asarray([st.mean.copy() for st in stracks])
            multi_covariance = np.asarray([st.covariance for st in stracks])
            for i, st in enumerate(stracks):
                if st.state != TrackState.Tracked:
                    multi_mean[i][7] = 0
            multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(multi_mean, multi_covariance)
            for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)):
                stracks[i].mean = mean
                stracks[i].covariance = cov

    def activate(self, kalman_filter, frame_id):
        """Start a new tracklet"""
        self.kalman_filter = kalman_filter
        self.track_id = self.next_id()
        self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh))

        self.tracklet_len = 0
        self.state = TrackState.Tracked
        if frame_id == 1:
            self.is_activated = True
        #self.is_activated = True
        self.frame_id = frame_id
        self.start_frame = frame_id

    def re_activate(self, new_track, frame_id, new_id=False):
        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh)
        )

        self.update_features(new_track.curr_feat)
        self.tracklet_len = 0
        self.state = TrackState.Tracked
        self.is_activated = True
        self.frame_id = frame_id
        if new_id:
            self.track_id = self.next_id()

    def update(self, new_track, frame_id, update_feature=True):
        """
        Update a matched track
        :type new_track: STrack
        :type frame_id: int
        :type update_feature: bool
        :return:
        """
        self.frame_id = frame_id
        self.tracklet_len += 1

        new_tlwh = new_track.tlwh

        # log historical track up to previous 10 frames
        if len(self.history) == 10:
            self.history = self.history[1:]
        self.history.append(new_tlwh.copy())

        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh))
        self.state = TrackState.Tracked
        self.is_activated = True

        self.score = new_track.score
        if update_feature:
            self.update_features(new_track.curr_feat)
    
    @property
    def tlwh_raw(self):
        if len(self.history) > 0:
            return self.history[-1]
        return self._tlwh.copy()
    
    @property
    # @jit(nopython=True)
    def tlwh(self):
        """Get current position in bounding box format `(top left x, top left y,
                width, height)`.
        """
        if self.mean is None:
            return self._tlwh.copy()
        ret = self.mean[:4].copy()
        ret[2] *= ret[3]
        ret[:2] -= ret[2:] / 2
        return ret

    @property
    # @jit(nopython=True)
    def tlbr(self):
        """Convert bounding box to format `(min x, min y, max x, max y)`, i.e.,
        `(top left, bottom right)`.
        """
        ret = self.tlwh.copy()
        ret[2:] += ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_xyah(tlwh):
        """Convert bounding box to format `(center x, center y, aspect ratio,
        height)`, where the aspect ratio is `width / height`.
        """
        ret = np.asarray(tlwh).copy()
        ret[:2] += ret[2:] / 2
        ret[2] /= ret[3]
        return ret

    def to_xyah(self):
        return self.tlwh_to_xyah(self.tlwh)

    @staticmethod
    # @jit(nopython=True)
    def tlbr_to_tlwh(tlbr):
        ret = np.asarray(tlbr).copy()
        ret[2:] -= ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_tlbr(tlwh):
        ret = np.asarray(tlwh).copy()
        ret[2:] += ret[:2]
        return ret

    def __repr__(self):
        return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame)
    def __init__(self, opt, polygon, paths, polygon2=None, frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        anchor_ratios = [(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)]
        anchor_scales = [2**0, 2**(1.0 / 3.0), 2**(2.0 / 3.0)]
        input_sizes = [512, 640, 768, 896, 1024, 1280, 1280, 1536]
        self.input_size = input_sizes[opt.compound_coef]
        self.obj_list = [
            'person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus',
            'train', 'truck', 'boat', 'traffic light', 'fire hydrant', '',
            'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog',
            'horse', 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe',
            '', 'backpack', 'umbrella', '', '', 'handbag', 'tie', 'suitcase',
            'frisbee', 'skis', 'snowboard', 'sports ball', 'kite',
            'baseball bat', 'baseball glove', 'skateboard', 'surfboard',
            'tennis racket', 'bottle', '', 'wine glass', 'cup', 'fork',
            'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 'orange',
            'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 'chair',
            'couch', 'potted plant', 'bed', '', 'dining table', '', '',
            'toilet', '', 'tv', 'laptop', 'mouse', 'remote', 'keyboard',
            'cell phone', 'microwave', 'oven', 'toaster', 'sink',
            'refrigerator', '', 'book', 'clock', 'vase', 'scissors',
            'teddy bear', 'hair drier', 'toothbrush'
        ]
        self.person_or_motorcycle = ['motorcycle', 'bicycle']
        self.obj_interest = [
            'motorcycle', 'bicycle', 'bus', 'truck', 'car'
        ] if self.person_or_motorcycle[0] != 'person' else [
            'person', 'bus', 'truck', 'car'
        ]
        print(self.obj_interest)
        self.detetection_model = EfficientDetBackbone(
            compound_coef=opt.compound_coef,
            num_classes=len(self.obj_list),
            ratios=anchor_ratios,
            scales=anchor_scales)

        self.detetection_model.load_state_dict(
            torch.load(
                f'EfficientDet/weights/efficientdet-d{opt.compound_coef}.pth'))
        self.detetection_model.eval()
        device = torch.device('cuda:0')
        self.detetection_model = self.detetection_model.to(device)

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K

        self.kalman_filter = KalmanFilter()

        self.polygon = polygon
        self.paths = paths
        self.polygon2 = polygon2
        self.line2 = [self.polygon[1], self.polygon[2]]
        self.line1 = [self.polygon[4], self.polygon[3]] if len(
            self.polygon) == 5 else [self.polygon[0], self.polygon[3]] if len(
                self.polygon) == 4 else None
        self.two_polygon_system = False
        self.warmup_frame = 6 if self.two_polygon_system else 0
        self.virtual_polygon = [[0, 573], [0, 109], [1270, 109], [1270, 573]]
class STrack(BaseTrack):
    shared_kalman = KalmanFilter()
    out_of_frame_patience=5
    num_cluster=5
    type_infer_patience=4
    score_infer_type_thres=0.6
    def __init__(self, tlwh, score, vehicle_type, buffer_size=30,temp_feat=None,huge_vehicle=False):

        # wait activate
        self._tlwh = np.asarray(tlwh, dtype=np.float)
        self.kalman_filter = None
        self.mean, self.covariance = None, None
        self.is_activated = False

        self.score = score
        
        self.tracklet_len = 0

        self.smooth_feat = None
        # self.update_features(temp_feat,None)
        self.features = deque([], maxlen=buffer_size)
        self.alpha = 0.6
        self.num_out_frame=0
        self.cluster_features={'centers':[],'cluster':[]}
        self.track_frames=[]
        self.w_hs=[]
        self.occlusion_status=False # use for bbox only
        self.iou_box=None #use for bbox only
        self.box_hist=[]
        self.vehicle_types_list=[]
        self.vehicle_types_list.append(vehicle_type)
        self.track_trajectory=[]
        self.track_trajectory.append(self.tlwh_to_tlbr(tlwh))
        self.huge_vehicle=huge_vehicle
    def update_cluster(self,feat):
        feat /= np.linalg.norm(feat)
        if len(self.cluster_features['cluster'])<STrack.num_cluster:
            self.cluster_features['cluster'].append([feat])
            self.cluster_features['centers'].append(feat)
        else:
            min_center=np.argmin(np.squeeze(cdist(self.cluster_features['centers'], [feat], metric='cosine')))
            self.cluster_features['cluster'][min_center].append(feat)
            self.cluster_features['centers'][min_center]=np.mean(self.cluster_features['cluster'][min_center],axis=0)
            self.cluster_features['centers']/=np.linalg.norm( self.cluster_features['centers'])
    
        
    def update_features(self, feat,iou_box):
        #feat /= np.linalg.norm(feat)
        self.curr_feat = feat
        if self.smooth_feat is None:
            self.smooth_feat = feat
        else:
            if iou_box==None: iou_box=0
            update_param=(1-self.alpha)*iou_box+self.alpha
            #self.smooth_feat = self.alpha * self.smooth_feat + (1 - self.alpha) * feat
            self.smooth_feat = update_param * self.smooth_feat + (1 -update_param) * feat
            self.box_hist.append(update_param)
            
                               
        self.features.append(feat)
        #self.smooth_feat /= np.linalg.norm(self.smooth_feat)

    def predict(self):
        mean_state = self.mean.copy()
        if self.state != TrackState.Tracked:
            mean_state[7] = 0
        self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance)

    @staticmethod
    def multi_predict(stracks):
        if len(stracks) > 0:
            multi_mean = np.asarray([st.mean.copy() for st in stracks])
            multi_covariance = np.asarray([st.covariance for st in stracks])
            for i, st in enumerate(stracks):
                if st.state != TrackState.Tracked:
                    multi_mean[i][7] = 0

            multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(multi_mean, multi_covariance)
            for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)):
                stracks[i].mean = mean
                stracks[i].covariance = cov

    def activate(self, kalman_filter, frame_id):
        """Start a new tracklet"""
        # self.track_trajectory.append(self.tlbr)
        self.kalman_filter = kalman_filter
        self.track_id = self.next_id()
        self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh))

        self.tracklet_len = 0
        self.state = TrackState.Tracked
        #self.is_activated = True
        self.frame_id = frame_id
        self.start_frame = frame_id
        self.track_frames.append(frame_id)

    def re_activate(self, new_track, frame_id, new_id=False):
        new_tlwh = new_track.tlwh
        self.track_trajectory.append(self.tlwh_to_tlbr(new_tlwh))
        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh)
        )

        #self.update_features(new_track.curr_feat,new_track.iou_box)
        #self.update_cluster(new_track.curr_feat)
        self.tracklet_len = 0
        self.state = TrackState.Tracked
        self.is_activated = True
        self.frame_id = frame_id
        if new_id:
            self.track_id = self.next_id()
        self.track_frames.append(frame_id)

    def update(self, new_track, frame_id, update_feature=False):
        """
        Update a matched track
        :type new_track: STrack
        :type frame_id: int
        :type update_feature: bool
        :return:
        """
        self.frame_id = frame_id
        self.tracklet_len += 1
        self.vehicle_types_list.append(new_track.vehicle_types_list[-1])

        new_tlwh = new_track.tlwh
        self.track_trajectory.append(self.tlwh_to_tlbr(new_tlwh))

        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh))
        self.state = TrackState.Tracked
        self.is_activated = True

        self.score = new_track.score
        if update_feature:
            self.update_features(new_track.curr_feat,new_track.iou_box) ###########
            #self.update_cluster(new_track.curr_feat)
        self.track_frames.append(frame_id)
    def infer_type(self):
        def most_frequent(List): 
            return max(set(List), key = List.count)
        types=most_frequent(self.vehicle_types_list)
        return types
        # if classes in ['bicycle', 'motorcycle']:
        #     return 1
        # elif classes =='car':
        #     return 2
        # elif classes=='bus':
        #     return 3
        # else:
        #     return 4
    @property
    def vehicle_type(self):
        def most_frequent(List): 
            return max(set(List), key = List.count)
        if len(self.track_frames)>=self.type_infer_patience:
            return most_frequent(self.vehicle_types_list)
        elif self.score >=self.score_infer_type_thres:
            return most_frequent(self.vehicle_types_list)
        else:
            return 'Undetermine'

    @property
    # @jit(nopython=True)
    def tlwh(self):
        """Get current position in bounding box format `(top left x, top left y,
                width, height)`.
        """
        if self.mean is None:
            return self._tlwh.copy()
        ret = self.mean[:4].copy()
        ret[2] *= ret[3]
        ret[:2] -= ret[2:] / 2
        return ret

    @property
    # @jit(nopython=True)
    def tlbr(self):
        """Convert bounding box to format `(min x, min y, max x, max y)`, i.e.,
        `(top left, bottom right)`.
        """
        ret = self.tlwh.copy()
        ret[2:] += ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_xyah(tlwh):
        """Convert bounding box to format `(center x, center y, aspect ratio,
        height)`, where the aspect ratio is `width / height`.
        """
        ret = np.asarray(tlwh).copy()
        ret[:2] += ret[2:] / 2
        ret[2] /= ret[3]
        return ret

    def to_xyah(self):
        return self.tlwh_to_xyah(self.tlwh)

    @staticmethod
    # @jit(nopython=True)
    def tlbr_to_tlwh(tlbr):
        ret = np.asarray(tlbr).copy()
        ret[2:] -= ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_tlbr(tlwh):
        ret = np.asarray(tlwh).copy()
        ret[2:] += ret[:2]
        return ret

    def __repr__(self):
        return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame)
Exemple #18
0
class Track(BaseTrack):
    shared_kalman = KalmanFilter()

    def __init__(self, tlwh, score, temp_feat, buff_size=30):
        """
        :param tlwh:
        :param score:
        :param temp_feat:
        :param buff_size:
        """

        # wait activate
        self._tlwh = np.asarray(tlwh, dtype=np.float)
        self.kalman_filter = None
        self.mean, self.covariance = None, None
        self.is_activated = False

        self.score = score
        self.track_len = 0

        self.smooth_feat = None
        self.update_features(temp_feat)
        self.features = deque([], maxlen=buff_size)  # 指定了限制长度
        self.alpha = 0.9

    def update_features(self, feat):
        # L2 normalizing
        feat /= np.linalg.norm(feat)

        self.curr_feat = feat
        if self.smooth_feat is None:
            self.smooth_feat = feat
        else:
            self.smooth_feat = self.alpha * self.smooth_feat + (1 - self.alpha) * feat

        self.features.append(feat)
        self.smooth_feat /= np.linalg.norm(self.smooth_feat)

    def predict(self):
        mean_state = self.mean.copy()
        if self.state != TrackState.Tracked:
            mean_state[7] = 0
        self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance)

    @staticmethod
    def multi_predict(tracks):
        if len(tracks) > 0:
            multi_mean = np.asarray([track.mean.copy() for track in tracks])
            multi_covariance = np.asarray([track.covariance for track in tracks])

            for i, st in enumerate(tracks):
                if st.state != TrackState.Tracked:
                    multi_mean[i][7] = 0

            multi_mean, multi_covariance = Track.shared_kalman.multi_predict(multi_mean, multi_covariance)

            for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)):
                tracks[i].mean = mean
                tracks[i].covariance = cov

    def reset_track_id(self):
        self.reset_track_count()

    def activate(self, kalman_filter, frame_id):
        """Start a new tracklet"""
        self.kalman_filter = kalman_filter  # assign a filter to each tracklet?

        # update the track id
        self.track_id = self.next_id()

        self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh))

        self.track_len = 0
        self.state = TrackState.Tracked  # set flag 'tracked'

        # self.is_activated = True
        if frame_id == 1:  # to record the first frame's detection result
            self.is_activated = True

        self.frame_id = frame_id
        self.start_frame = frame_id

    def re_activate(self, new_track, frame_id, new_id=False):
        self.mean, self.covariance = self.kalman_filter.update(self.mean,
                                                               self.covariance,
                                                               self.tlwh_to_xyah(new_track.tlwh))

        self.update_features(new_track.curr_feat)
        self.track_len = 0
        self.state = TrackState.Tracked  # set flag 'tracked'
        self.is_activated = True
        self.frame_id = frame_id

        if new_id:  # update the track id
            self.track_id = self.next_id()

    def update(self, new_track, frame_id, update_feature=True):
        """
        Update a matched track
        :type new_track: Track
        :type frame_id: int
        :type update_feature: bool
        :return:
        """
        self.frame_id = frame_id
        self.track_len += 1

        new_tlwh = new_track.tlwh
        self.mean, self.covariance = self.kalman_filter.update(self.mean,
                                                               self.covariance,
                                                               self.tlwh_to_xyah(new_tlwh))
        self.state = TrackState.Tracked  # set flag 'tracked'
        self.is_activated = True  # set flag 'activated'

        self.score = new_track.score
        if update_feature:
            self.update_features(new_track.curr_feat)

    @property
    # @jit(nopython=True)
    def tlwh(self):
        """Get current position in bounding box format `(top left x, top left y,
                width, height)`.
        """
        if self.mean is None:
            return self._tlwh.copy()

        ret = self.mean[:4].copy()
        ret[2] *= ret[3]
        ret[:2] -= ret[2:] / 2
        return ret

    @property
    # @jit(nopython=True)
    def tlbr(self):
        """Convert bounding box to format `(min x, min y, max x, max y)`, i.e.,
        `(top left, bottom right)`.
        """
        ret = self.tlwh.copy()
        ret[2:] += ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_xyah(tlwh):
        """Convert bounding box to format `(center x, center y, aspect ratio,
        height)`, where the aspect ratio is `width / height`.
        """
        ret = np.asarray(tlwh).copy()
        ret[:2] += ret[2:] / 2
        ret[2] /= ret[3]
        return ret

    def to_xyah(self):
        return self.tlwh_to_xyah(self.tlwh)

    @staticmethod
    # @jit(nopython=True)
    def tlbr_to_tlwh(tlbr):
        ret = np.asarray(tlbr).copy()  # numpy中的.copy()是深拷贝
        ret[2:] -= ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_tlbr(tlwh):
        ret = np.asarray(tlwh).copy()
        ret[2:] += ret[:2]
        return ret

    def __repr__(self):
        return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame)
    def __init__(self, opt,polygon, paths, polygon2=None,frame_rate=30):
        self.opt = opt
        if opt.gpus[0] >= 0:
            opt.device = torch.device('cuda')
        else:
            opt.device = torch.device('cpu')
        print('Creating model...')
        anchor_ratios = [(1.0, 1.0), (1.4, 0.7), (0.7, 1.4)]
        anchor_scales = [2 ** 0, 2 ** (1.0 / 3.0), 2 ** (2.0 / 3.0)]
        input_sizes = [512, 640, 768, 896, 1024, 1280, 1280, 1536]
        self.input_size = input_sizes[opt.compound_coef] 
        if opt.detection_model=='Efficient' :
            self.obj_list =['person', 'bicycle', 'car', 'motorcycle', 'airplane', 'bus', 'train', 'truck', 'boat', 'traffic light',
                'fire hydrant', '', 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 'sheep',
                'cow', 'elephant', 'bear', 'zebra', 'giraffe', '', 'backpack', 'umbrella', '', '', 'handbag', 'tie',
                'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove',
                'skateboard', 'surfboard', 'tennis racket', 'bottle', '', 'wine glass', 'cup', 'fork', 'knife', 'spoon',
                'bowl', 'banana', 'apple', 'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut',
                'cake', 'chair', 'couch', 'potted plant', 'bed', '', 'dining table', '', '', 'toilet', '', 'tv',
                'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 'oven', 'toaster', 'sink',
                'refrigerator', '', 'book', 'clock', 'vase', 'scissors', 'teddy bear', 'hair drier',
                'toothbrush']
            self.person_or_motorcycle=['person']
            self.obj_interest=[ 'motorcycle','bicycle', 'bus', 'truck','car'] if self.person_or_motorcycle[0]!='person' else [ 'person', 'bus', 'truck','car']
            self.detetection_model= EfficientDetBackbone(compound_coef=opt.compound_coef, num_classes=len(self.obj_list),
                                ratios=anchor_ratios, scales=anchor_scales)
        
            self.detetection_model.load_state_dict(torch.load(f'EfficientDet/weights/efficientdet-d{opt.compound_coef}.pth'))
            self.detetection_model.eval()
            device = torch.device('cuda:0')
            self.detetection_model = self.detetection_model.to(device)
        elif  opt.detection_model=='FasterRcnn' :
            config_file = "Drone_FasterRCNN/drone_demo/e2e_faster_rcnn_X_101_32x8d_FPN_1x_visdrone.yaml"
            cfg.merge_from_file(config_file)
            cfg.merge_from_list(["MODEL.WEIGHT", "Drone_FasterRCNN/drone_demo/visdrone_model_0360000.pth"])
            self.detetection_model = COCODemo(
                cfg,
                min_image_size=opt.min_img_size,
                confidence_threshold=opt.conf_thres,
            )
            label_of_interest=[
                    # "__background",
                    # "unused",
                    # "pedestrian",
                    # "person",
                    # "bicycle",
                    "car",
                    "van",
                    "truck",
                    # "tricycle",
                    # "awning-tricycle",
                    "bus",
                    "motor"
            ]
            self.person_or_motorcycle=["motor"]
            #'bicycle'
            self.obj_interest=[ 'motor', 'bus', 'truck','car','van', "tricycle"] if self.person_or_motorcycle[0]!='person' else [ 'person', 'bus', 'truck','car','van', "tricycle"]
        else:
            raise('Not supported detector model')

        self.tracked_stracks = []  # type: list[STrack]
        self.lost_stracks = []  # type: list[STrack]
        self.removed_stracks = []  # type: list[STrack]

        self.frame_id = 0
        self.det_thresh = opt.conf_thres
        self.buffer_size = int(frame_rate / 30.0 * opt.track_buffer)
        self.max_time_lost = self.buffer_size
        self.max_per_image = opt.K

        self.kalman_filter = KalmanFilter()

        self.polygon=polygon
        self.paths=paths
        self.polygon2=polygon2
        self.line1=[polygon[0],polygon[1]]
        self.line2=[polygon[1],polygon[2]]
        self.line3=[polygon[2],polygon[3]]
        self.line4=[polygon[0],polygon[4]]
        self.two_polygon_system=True
        self.warmup_frame=0 
        self.virtual_polygon= [
                [
                    0,
                    680
                ],
                [
                    0,
                    149
                ],
                [
                    1270,
                    149
                ],
                [
                    1270,
                    680
                ]
            ]
Exemple #20
0
 def __init__(self, opt):
     self.opt = opt
     self.tracked_stracks = []  # type: list[STrack]
     self.frame_id = 0
     self.kalman_filter = KalmanFilter()
Exemple #21
0
class STrack(BaseTrack):
    shared_kalman = KalmanFilter()
    out_of_frame_patience = 5
    num_cluster = 5

    def __init__(self, tlwh, score, temp_feat, buffer_size=30):

        # wait activate
        self._tlwh = np.asarray(tlwh, dtype=np.float)
        self.kalman_filter = None
        self.mean, self.covariance = None, None
        self.is_activated = False

        self.score = score
        self.tracklet_len = 0

        self.smooth_feat = None

        self.update_features(temp_feat, None)
        self.alpha = 0.9
        self.occlusion_status = False  # use for bbox only
        self.iou_box = None  #use for bbox only
        self.num_out_frame = 0

    def update_features(self, feat, new_track):
        feat /= np.linalg.norm(feat)
        self.curr_feat = feat
        if self.smooth_feat is None:
            self.smooth_feat = feat
        else:
            self.smooth_feat = self.alpha * self.smooth_feat + (
                1 - self.alpha) * feat
        self.smooth_feat /= np.linalg.norm(self.smooth_feat)

    @staticmethod
    def warp_predict(mean, cov, warp_matrix, warp_mode):
        if warp_matrix is None:
            return mean, cov
        track_xyah = mean[:4]
        track_tlwh = STrack.xyah_to_tlwh(track_xyah)
        track_tlbr = STrack.tlwh_to_tlbr(track_tlwh)
        t, l, b, r = track_tlbr
        if warp_mode == cv2.MOTION_HOMOGRAPHY:
            warp_tlbr = cv2.perspectiveTransform(np.array([[[t, l], [b, r]]]),
                                                 warp_matrix)[0].flatten()
        else:
            warp_tlbr = cv2.transform(np.array([[[t, l], [b, r]]]),
                                      warp_matrix)[0].flatten()

        warp_tlwh = STrack.tlbr_to_tlwh(warp_tlbr)
        warp_xyah = STrack.tlwh_to_xyah(warp_tlwh)
        track_mean, track_cov = list(warp_xyah) + list(mean[4:]), cov
        return np.array(track_mean), track_cov

    @staticmethod
    def get_camera_intension(warp_matrix, warp_mode):
        if warp_matrix is None:
            return 0
        warp_matrix_flattern = warp_matrix.flatten()
        if warp_mode == cv2.MOTION_HOMOGRAPHY:
            non_change_warp = np.array([1, 0, 0, 0, 1, 0, 0, 0, 1])
        else:
            non_change_warp = np.array([1, 0, 0, 0, 1, 0])
        similarity = np.dot(warp_matrix_flattern, non_change_warp) / (
            np.sqrt(np.sum(warp_matrix_flattern**2)) *
            np.sqrt(np.sum(non_change_warp**2)))
        return 1 - similarity

    def predict(self, warp_matrix, warp_mode, smooth=0.0):
        mean_state = self.mean.copy()
        if self.state != TrackState.Tracked:
            mean_state[7] = 0
        motion_intensity = STrack.get_camera_intension(warp_matrix,
                                                       warp_mode) * smooth
        self.mean, self.covariance = self.kalman_filter.predict(
            mean_state, self.covariance, motion_intensity=motion_intensity)
        self.mean, self.covariance = STrack.warp_predict(
            self.mean, self.covariance, warp_matrix, warp_mode)

    @staticmethod
    def multi_predict(stracks, warp_matrix, warp_mode, smooth=0.0):
        if len(stracks) > 0:
            multi_mean = np.asarray([st.mean.copy() for st in stracks])
            multi_covariance = np.asarray([st.covariance for st in stracks])
            for i, st in enumerate(stracks):
                if st.state != TrackState.Tracked:
                    multi_mean[i][7] = 0
            motion_intensity = STrack.get_camera_intension(
                warp_matrix, warp_mode) * smooth
            multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(
                multi_mean,
                multi_covariance,
                motion_intensity=motion_intensity)
            for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)):
                stracks[i].mean = mean
                stracks[i].covariance = cov
                stracks[i].mean, stracks[i].covariance = STrack.warp_predict(
                    stracks[i].mean, stracks[i].covariance, warp_matrix,
                    warp_mode)

    def activate(self, kalman_filter, frame_id):
        """Start a new tracklet"""
        self.kalman_filter = kalman_filter
        self.track_id = self.next_id()
        self.mean, self.covariance = self.kalman_filter.initiate(
            self.tlwh_to_xyah(self._tlwh))

        self.tracklet_len = 0
        self.state = TrackState.Tracked
        #self.is_activated = True
        self.frame_id = frame_id
        self.start_frame = frame_id

        # self.box_hist.append(self.tlwh)
        # self.track_frames.append(frame_id)

    def re_activate(self, new_track, frame_id, new_id=False):
        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh))

        self.update_features(new_track.curr_feat, new_track)
        #self.update_cluster(new_track.curr_feat)
        self.tracklet_len = 0
        self.state = TrackState.Tracked
        self.is_activated = True
        self.frame_id = frame_id
        if new_id:
            self.track_id = self.next_id()

    def update(self, new_track, frame_id, update_feature=True):
        """
        Update a matched track
        :type new_track: STrack
        :type frame_id: int
        :type update_feature: bool
        :return:
        """
        self.frame_id = frame_id
        self.tracklet_len += 1

        new_tlwh = new_track.tlwh
        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh))
        self.state = TrackState.Tracked
        self.is_activated = True

        self.score = new_track.score
        if update_feature:
            self.update_features(new_track.curr_feat, new_track)

    @property
    # @jit(nopython=True)
    def tlwh(self):
        """Get current position in bounding box format `(top left x, top left y,
                width, height)`.
        """
        if self.mean is None:
            return self._tlwh.copy()
        ret = self.mean[:4].copy()
        ret[2] *= ret[3]
        ret[:2] -= ret[2:] / 2
        return ret

    @property
    # @jit(nopython=True)
    def tlbr(self):
        """Convert bounding box to format `(min x, min y, max x, max y)`, i.e.,
        `(top left, bottom right)`.
        """
        ret = self.tlwh.copy()
        ret[2:] += ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_xyah(tlwh):
        """Convert bounding box to format `(center x, center y, aspect ratio,
        height)`, where the aspect ratio is `width / height`.
        """
        ret = np.asarray(tlwh).copy()
        ret[:2] += ret[2:] / 2
        ret[2] /= ret[3]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def xyah_to_tlwh(xyah):
        w, h = xyah[2] * xyah[3], xyah[3]
        x, y = xyah[0], xyah[1]
        t, l = x - w / 2, y - h / 2
        return [t, l, w, h]

    def to_xyah(self):
        return self.tlwh_to_xyah(self.tlwh)

    @staticmethod
    # @jit(nopython=True)
    def tlbr_to_tlwh(tlbr):
        ret = np.asarray(tlbr).copy()
        ret[2:] -= ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_tlbr(tlwh):
        ret = np.asarray(tlwh).copy()
        ret[2:] += ret[:2]
        return ret

    def __repr__(self):
        return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame,
                                      self.end_frame)
Exemple #22
0
class STrack(BaseTrack):
    shared_kalman = KalmanFilter()                                  # 类变量
    def __init__(self, tlwh, score, temp_feat, buffer_size=30):

        # wait activate
        self._tlwh = np.asarray(tlwh, dtype=np.float)
        self.kalman_filter = None
        self.mean, self.covariance = None, None
        self.is_activated = False

        self.score = score
        self.tracklet_len = 0

        self.smooth_feat = None
        self.update_features(temp_feat)
        self.features = deque([], maxlen=buffer_size)
        self.alpha = 0.9

    def update_features(self, feat):                # 增加新的feature,添加到self.feature、self.curr_feat
        feat /= np.linalg.norm(feat)
        self.curr_feat = feat
        if self.smooth_feat is None:
            self.smooth_feat = feat
        else:
            self.smooth_feat = self.alpha * self.smooth_feat + (1 - self.alpha) * feat  # 指数移动加权平均,self.smooth_feat综合了过去一定量的feature
        self.features.append(feat)
        self.smooth_feat /= np.linalg.norm(self.smooth_feat)            # 归一化处理

    def predict(self):
        mean_state = self.mean.copy()
        if self.state != TrackState.Tracked:
            mean_state[7] = 0
        self.mean, self.covariance = self.kalman_filter.predict(mean_state, self.covariance)

    @staticmethod
    def multi_predict(stracks):
        if len(stracks) > 0:
            multi_mean = np.asarray([st.mean.copy() for st in stracks])
            multi_covariance = np.asarray([st.covariance for st in stracks])
            for i, st in enumerate(stracks):
                if st.state != TrackState.Tracked:
                    multi_mean[i][7] = 0
            multi_mean, multi_covariance = STrack.shared_kalman.multi_predict(multi_mean, multi_covariance) # 返回预测状态的均值向量和协方差矩阵
            for i, (mean, cov) in enumerate(zip(multi_mean, multi_covariance)):         # 然后再将各自的均值向量、协方差矩阵分别分配给对应的stracks
                stracks[i].mean = mean
                stracks[i].covariance = cov

    def activate(self, kalman_filter, frame_id):            # 创建一个新的 track
        """Start a new tracklet"""
        self.kalman_filter = kalman_filter
        self.track_id = self.next_id()
        self.mean, self.covariance = self.kalman_filter.initiate(self.tlwh_to_xyah(self._tlwh))
                                                            # 使用当前位置状态进行初始化
        self.tracklet_len = 0
        self.state = TrackState.Tracked
        #self.is_activated = True
        self.frame_id = frame_id
        self.start_frame = frame_id

    def re_activate(self, new_track, frame_id, new_id=False):       # 新创建一个 track
        self.mean, self.covariance = self.kalman_filter.update(
            self.mean, self.covariance, self.tlwh_to_xyah(new_track.tlwh)
        )

        self.update_features(new_track.curr_feat)
        self.tracklet_len = 0
        self.state = TrackState.Tracked
        self.is_activated = True
        self.frame_id = frame_id
        if new_id:
            self.track_id = self.next_id()

    def update(self, new_track, frame_id, update_feature=True):         # 更新对应的 KF 中的均值向量、协方差矩阵
        """
        Update a matched track
        :type new_track: STrack
        :type frame_id: int
        :type update_feature: bool
        :return:
        """
        self.frame_id = frame_id        # 当前的帧id
        self.tracklet_len += 1          # 追踪片段长度增加 1

        new_tlwh = new_track.tlwh
        self.mean, self.covariance = self.kalman_filter.update(         # 卡尔曼滤波器
            self.mean, self.covariance, self.tlwh_to_xyah(new_tlwh))
        self.state = TrackState.Tracked
        self.is_activated = True

        self.score = new_track.score
        if update_feature:
            self.update_features(new_track.curr_feat)

    @property
    # @jit(nopython=True)
    def tlwh(self):
        """Get current position in bounding box format `(top left x, top left y,
                width, height)`.
        """
        if self.mean is None:
            return self._tlwh.copy()
        ret = self.mean[:4].copy()
        ret[2] *= ret[3]
        ret[:2] -= ret[2:] / 2
        return ret

    @property
    # @jit(nopython=True)
    def tlbr(self):
        """Convert bounding box to format `(min x, min y, max x, max y)`, i.e.,
        `(top left, bottom right)`.
        """
        ret = self.tlwh.copy()
        ret[2:] += ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_xyah(tlwh):
        """Convert bounding box to format `(center x, center y, aspect ratio,
        height)`, where the aspect ratio is `width / height`.
        """
        ret = np.asarray(tlwh).copy()
        ret[:2] += ret[2:] / 2
        ret[2] /= ret[3]
        return ret

    def to_xyah(self):
        return self.tlwh_to_xyah(self.tlwh)

    @staticmethod
    # @jit(nopython=True)
    def tlbr_to_tlwh(tlbr):
        ret = np.asarray(tlbr).copy()
        ret[2:] -= ret[:2]
        return ret

    @staticmethod
    # @jit(nopython=True)
    def tlwh_to_tlbr(tlwh):
        ret = np.asarray(tlwh).copy()
        ret[2:] += ret[:2]
        return ret

    def __repr__(self):
        return 'OT_{}_({}-{})'.format(self.track_id, self.start_frame, self.end_frame)