示例#1
0
class Tracks(object):

    def __init__(self, detection, trackID):

        super(Tracks, self).__init__()
        self.KF = KalmanFilter()
        self.KF.predict()
        self.KF.correct(np.matrix(detection).reshape(3, 1))
        self.trace = deque()
        self.prediction = detection.reshape(1,3)
        self.trackID = trackID
        self.skipped = 0

    def predict(self, detection):
        self.prediction = np.array(self.KF.predict()).reshape(1,3)
        self.KF.correct(np.matrix(detection).reshape(3,1))

    def predictNoDetect(self):
        self.prediction = np.array(self.KF.predict()).reshape(1,3)
        self.KF.update()
    
    def CheckMeasurement(self, cost):
        return self.KF.measurementProbability(cost)
示例#2
0
class Instance(object):
    def __init__(self, config, video_helper):   # fps: frame per second
        self.num_misses = 0
        self.max_misses = config.MAX_NUM_MISSING_PERMISSION

        self.has_match = False

        # flags: self.delete.......

        self.kalman = KalmanFilter(video_helper)
        # self.history

    def add_to_track(self, tag, bbox):
        corrected_bbox = self.kalman.correct(bbox)
        # self.history.append(corrected_bbox)

    def get_predicted_bbox(self):
        # get a prediction
        return self.kalman.get_predicted_bbx()
示例#3
0
    img = cv2.resize(img, (int(img.shape[1]*scale_factor), int(img.shape[0]*scale_factor)))
    # detect ball in frame (just one for now)
    bboxes = detector.detect(img)
    bb = None
    if bboxes is not None and len(bboxes)>0:
        for bb in bboxes:
            cv2.rectangle(img, (bb[0], bb[1]), (bb[2], bb[3]), (0, 255, 0), 2)
            pass
        # assume only 1 object
        bb = bboxes[0]

    # update kalman measurement
    pred_bb = kf.get_predicted_bb()
    if bb is not None:
        # if we have a measurement, correct using measurement
        corr_bb = kf.correct(bb)
        num_missed_det = 0
    else:
        # if no measurement found, use prediction as measurement to correct
        if num_missed_det < max_num_missed_det:
            corr_bb = kf.correct(pred_bb)
            num_missed_det += 1 # count as missed detection
        else:
            corr_bb = None
    # add bbox to track
    if num_missed_det < max_num_missed_det:
        tracked_bbox.append(corr_bb)
    else:
        tracked_bbox = [] # if too many missed detections, kill track
    # draw track history
    if len(tracked_bbox) > 0:
示例#4
0
class Track(object):
    def __init__(self):
        # each history entry is numpy array [frame_id, bbox_x1, bbox_y1, bbox_x2, bbox_y2, fvec_1...128]
        self.history = np.array([])
        self.num_misses = 0  # num of missed assignments
        self.max_misses = const.MAX_NUM_MISSES_TRACK
        self.has_match = False
        self.delete_me = False  # set for manual deletion
        self.kalman = KalmanFilter()
        color = tuple(np.random.random_integers(0, 255, size=3))
        self.drawing_color = color
        self.predicted_next_bb = None
        self.LENGTH_ESTABLISHED = 1  # number of sequential detections before we consider it a track
        self.uid = uuid.uuid4()

    def get_length(self):
        return self.history.shape[0]

    def is_singular(self):
        return True if self.history.shape[
            0] == self.LENGTH_ESTABLISHED else False

    def is_established(self):
        return True if self.history.shape[
            0] > self.LENGTH_ESTABLISHED else False

    def is_empty(self):
        return True if self.history.shape[0] == 0 else False

    def is_dead(self):
        return True if (self.num_misses >= self.max_misses
                        or self.delete_me is True) else False

    def propagate_track(self, frame_id):
        # propagate track as if there was a detection, perhaps object is temporarily occluded or not detected
        # use predicted bb as measurement
        det = Detection.det_from_numpy_array(
            self.history[self.history.shape[0] - 1])
        det.bbox = self.get_predicted_next_bb()
        # TODO: adjust bbox to have same width height but only propegate x,y centroid position
        # pred_c_x, pred_c_y = util.centroid_from_bb(self.get_predicted_next_bb())
        # wid, ht = util.wid_ht_from_bb(det.bbox)
        # det.bbox = np.array([pred_c_x - wid / 2,
        #                      pred_c_y - ht / 2,
        #                      pred_c_x + wid / 2,
        #                      pred_c_y + ht / 2], dtype=np.int32)

        det.frame_id = frame_id
        self.add_to_track(det)

    def get_predicted_next_bb(self):
        # # get a prediction using the latest history as a measurement
        # measurement = np.array([self.get_latest_bb()], dtype=np.float32).T
        return self.kalman.get_predicted_bb()

    def add_to_track(self, det):
        # use detection measurement to predict and correct the kalman filter
        corrected_bb = self.kalman.correct(det.bbox)
        # use corrected bbox
        det.bbox = corrected_bb
        # increment detections number of matches (could be assigned to several tracks, need to keep track of this)
        det.num_matches += 1
        new_history = det.as_numpy_array()
        # print new_history
        if self.history.size > 0:
            self.history = np.vstack((self.history, new_history))
        else:
            self.history = new_history

    def get_latest_fvec(self):
        # get feature vector from the latest detection in the track (already computed during detection phase)
        return self.history[self.history.shape[0] - 1][5:]

    def get_latest_bb(self):
        return self.history[self.history.shape[0] - 1][1:5]

    def draw_history(self, img, draw_at_bottom=False):
        if self.history.shape[0] > 1:
            bb_latest = self.get_latest_bb()
            cv2.rectangle(img, (int(bb_latest[0]), int(bb_latest[1])),
                          (int(bb_latest[2]), int(bb_latest[3])),
                          self.drawing_color, 2)
            # iterate through detection history
            prev_bb = self.history[0][1:5]
            for det in self.history:
                bb = det[1:5]
                # cv2.rectangle(img, tuple(bb[:2]),tuple(bb[2:]),(255,0,0),2)
                centroid = (int(bb[0] + (bb[2] - bb[0]) / 2),
                            int(bb[1] + (bb[3] - bb[1]) / 2))
                bottom = (int(bb[0] + (bb[2] - bb[0]) / 2), int(bb[3]))
                bottom_prev = (int(prev_bb[0] + (prev_bb[2] - prev_bb[0]) / 2),
                               int(prev_bb[3]))
                # cv2.circle(img, centroid, 5, self.drawing_color, 2)
                # cv2.circle(img, bottom, 3, self.drawing_color, 2)
                cv2.line(img, bottom_prev, bottom, self.drawing_color, 4)
                prev_bb = bb
示例#5
0
class Instance(object):
    def __init__(self, config, video_helper, frame):
        #each history entry is an array with [frame_id, tag, bbx_left, bbx_right, bbx_up, bbx_down]
        self.history = []
        self.history_size = config.HISTORY_SIZE = 10
        self.face_id = 'None'  # 人脸识别
        self.his_face_id = 'None'  # 记录上一次预测的人脸ID
        self.emotion = 'None'  # 表情识别
        self.his_emotion = 'None'  # 记录上一次表情
        self.detector = config.detector
        self.num_misses = 0  # num of missed assignments
        self.max_misses = config.MAX_NUM_MISSING_PERMISSION
        self.has_match = False
        self.delete_duplicate = False
        self.delete_still = False
        self.delete_singular = False
        self.num_of_still = 0  # num of detector num

        self.kcf = KcfFilter(video_helper,
                             frame)  # video_helper here can provide us the fps
        self.kalman = KalmanFilter(video_helper)

        # this color is for bbx (color assigned to this instance itself)
        color = np.random.randint(0, 255, (1, 3))[0]
        self.color = [int(color[0]),
                      int(color[1]),
                      int(color[2])]  # color needs to be a tuple

        # this color is for central point
        # because we need to fade the color
        self.center_color = []
        self.center_color.append([int(color[0]), int(color[1]), int(color[2])])

        self.predicted_next_bbx = None

        self.num_established = 1  # num of sequential detections before we consider it a track

        self.COLOR_FADING_PARAM = config.COLOR_FADING_PARAM

        # we still need to change it later
        self.speed = 0
        self.direction = 0  # degree of velocity direction with [1, 0]

        self.still_history = 0

    # def add_to_track(self, det):
    def add_to_track(self, tag, bbx, frame):
        # Same function with correct_track
        # Just make it more clear when it is the case that this particular detection is a new one and need to be
        # tracked later.

        # since here we are assured that this instance is detected, so it's not missed
        # self.num_misses = 0

        # use measured data to correct the  filter
        # still a list [x_left, x_right, y_up, y_bottom]

        if self.detector == "kcf":
            corrected_bbx = self.kcf.correct(bbx, frame)
        else:
            corrected_bbx = self.kalman.correct(bbx)

        # history: [tag, bbx_left, bbx_right, bbx_up, bbx_down, [color_b, color_g, color_r]]
        new_history = [
            tag, corrected_bbx[0], corrected_bbx[1], corrected_bbx[2],
            corrected_bbx[3], [self.color[0], self.color[1], self.color[2]]
        ]

        if (len(self.history) == 0):

            self.history.append(new_history)
        else:
            for i in range(len(self.history)):
                for c in range(3):
                    temp = self.history[i][5][c]
                    self.history[i][5][c] = int(
                        ((self.COLOR_FADING_PARAM - 1) /
                         self.COLOR_FADING_PARAM) * temp)
                    if self.history[i][5][c] < 0:
                        self.history[i][5][c] = 0
            self.history.insert(0, new_history)
            # we need to cut if we set
            if len(self.history) == self.COLOR_FADING_PARAM - 1:
                del self.history[-1]
        self.num_of_still += 1

    def add_to_track_with_no_correction(self, tag, bbx, frame):
        new_history = [
            tag, bbx[0], bbx[1], bbx[2], bbx[3],
            [self.color[0], self.color[1], self.color[2]]
        ]
        for i in range(len(self.history)):
            for c in range(3):
                temp = self.history[i][5][c]
                self.history[i][5][c] = int(
                    ((self.COLOR_FADING_PARAM - 1) / self.COLOR_FADING_PARAM) *
                    temp)
                if self.history[i][5][c] < 0:
                    self.history[i][5][c] = 0
        self.history.insert(0, new_history)
        # we need to cut if we set
        if len(self.history) == self.COLOR_FADING_PARAM - 1:
            del self.history[-1]

    def correct_track(self, det, frame):
        # Same function with add_to_track.
        # Just make it more clear when it is the case that we have a track and we need to correct that after we
        # have the measurement.
        # det: {'tag' : [bbx_left, bbx_right, bbx_up, bbx_bottom]}
        tag = list(det.keys())[0]
        bbx = det[tag]
        self.add_to_track(tag, bbx, frame)

    def get_predicted_bbx(self, frame):
        # get a prediction
        if self.detector == "kcf":
            return self.kcf.get_predicted_bbx(frame)
        elif self.detector == "kalman":
            return self.kalman.get_predicted_bbox()

    def get_latest_bbx(self):
        if len(self.history) == 0:
            return []
        res = self.history[0]
        last_bbx = [res[1], res[2], res[3], res[4]]
        return last_bbx

    def get_ith_bbx(self, i):
        # if input i is int type
        if isinstance(i, int):
            if (i > 0 and i < len(self.history)) or (i < 0 and
                                                     -i <= len(self.history)):
                res = self.history[i]
                ith_bbx = [res[1], res[2], res[3], res[4]]
                return ith_bbx

        # if input i is other type
        else:
            print("Wrong type!")
            return []

    def get_first_bbx(self):
        return self.get_ith_bbx(-1)

    def get_latest_record(self):
        if len(self.history) == 0:
            return []
        return self.history[0]

    def get_age(self):
        return len(self.history)