From 73c41991c721a6d943a015c57096f7904bbb6983 Mon Sep 17 00:00:00 2001 From: alpha-carinae29 Date: Fri, 29 May 2020 09:23:33 -0700 Subject: [PATCH 1/3] delete centroid tracker class --- libs/centroid_object_tracker.py | 109 -------------------------------- 1 file changed, 109 deletions(-) delete mode 100755 libs/centroid_object_tracker.py diff --git a/libs/centroid_object_tracker.py b/libs/centroid_object_tracker.py deleted file mode 100755 index d848bf8d..00000000 --- a/libs/centroid_object_tracker.py +++ /dev/null @@ -1,109 +0,0 @@ -# import the necessary packages -from collections import OrderedDict - -import numpy as np -from scipy.spatial import distance as dist - - -class CentroidTracker: - """ - A simple object tracker based on euclidean distance of bounding boxe centroids of two consecutive frames. - if a box is lost between two frames the tracker keeps the box for next max_disappeared frames. - - :param max_disappeared: If a box is losted betweeb two frames the tracker keep the box for next - max_disappeared frames. - """ - - def __init__(self, max_disappeared=50): - self.nextobject_id = 0 - self.tracked_objects = OrderedDict() - self.disappeared = OrderedDict() - self.max_disappeared = max_disappeared - - def register(self, object_item): - # Register a new detected object and set a unique id for it - self.tracked_objects[self.nextobject_id] = object_item - self.disappeared[self.nextobject_id] = 0 - self.nextobject_id += 1 - - def diregister(self, object_id): - """ - Remove an object from objects and disappeared list. - - Args: - object_id: Unique object ID for detected objects which is at objects list - - """ - del self.tracked_objects[object_id] - del self.disappeared[object_id] - - def update(self, detected_objects): - """ - Updates the objects from the previous frame. - This function compares previous frame with current frame and take following actions: - - 1- For each object that is being tracked, update its bounding box if it matches a - detected object in the current frame. - 2- For any detection in the current frame that doesn't match any tracked object, - register it as a new object. - 3- For each object that is being tracked and doesn't match a detection in the - current frame, register it as lost and increment its disappeared counter. - - Args: - detected_objects: List of detected objects. - - Return: - tracked_objects: List of updated objects. - """ - if len(detected_objects) == 0: - for object_id in list(self.disappeared.keys()): - self.disappeared[object_id] += 1 - # Removed an object from the tracker when the object is missing in the 'max_disappeared' previous frames. - if self.disappeared[object_id] > self.max_disappeared: - self.diregister(object_id) - return self.tracked_objects - - input_centroids = np.zeros((len(detected_objects), 2)) - for i, object_item in enumerate(detected_objects): - input_centroids[i] = (object_item["centroid"][0], object_item["centroid"][1]) - if len(self.tracked_objects) == 0: - for i in range(0, len(input_centroids)): - self.register(detected_objects[i]) - else: - object_ids = list(self.tracked_objects.keys()) - object_centroids = [object_item["centroid"][0:2] for object_item in self.tracked_objects.values()] - computed_dist = dist.cdist(np.array(object_centroids), input_centroids) - rows = computed_dist.min(axis=1).argsort() - cols = computed_dist.argmin(axis=1)[rows] - used_rows = set() - used_cols = set() - for (row, col) in zip(rows, cols): - if row in used_rows or col in used_cols: - continue - object_id = object_ids[row] - self.tracked_objects[object_id] = detected_objects[col] - self.disappeared[object_id] = 0 - used_rows.add(row) - used_cols.add(col) - - unused_rows = set(range(0, computed_dist.shape[0])).difference(used_rows) - unused_cols = set(range(0, computed_dist.shape[1])).difference(used_cols) - - if computed_dist.shape[0] >= computed_dist.shape[1]: - biggest_existing_id = int(detected_objects[-1]["id"].split("-")[-1]) - - for row in unused_rows: - object_id = object_ids[row] - self.tracked_objects[object_id]["id"] = self.tracked_objects[object_id]["id"].split("-")[ - 0] + "-" + str( - biggest_existing_id + 1) - self.disappeared[object_id] += 1 - biggest_existing_id += 1 - if self.disappeared[object_id] > self.max_disappeared: - self.diregister(object_id) - - else: - for col in unused_cols: - self.register(detected_objects[col]) - - return self.tracked_objects From 587cba8e4017b6e66a289b71f83e7439bb360661 Mon Sep 17 00:00:00 2001 From: alpha-carinae29 Date: Fri, 29 May 2020 09:34:55 -0700 Subject: [PATCH 2/3] cleanup core.py --- libs/core.py | 70 ++-------------------------------------------------- 1 file changed, 2 insertions(+), 68 deletions(-) diff --git a/libs/core.py b/libs/core.py index 639da9e3..e202c1e0 100755 --- a/libs/core.py +++ b/libs/core.py @@ -3,7 +3,6 @@ import math from libs import pubsub -from libs.centroid_object_tracker import CentroidTracker from libs.loggers.loggers import Logger from tools.environment_score import mx_environment_scoring_consider_crowd from tools.objects_post_process import extract_violating_objects @@ -17,8 +16,6 @@ def __init__(self, config): self.detector = None self.device = self.config.get_section_dict('Detector')['Device'] self.running_video = False - self.tracker = CentroidTracker( - max_disappeared=int(self.config.get_section_dict("PostProcessor")["MaxTrackFrame"])) self.logger = Logger(self.config) if self.device == 'Jetson': from libs.detectors.jetson.detector import Detector @@ -156,9 +153,7 @@ def calculate_distancing(self, objects_list): this function post-process the raw boxes of object detector and calculate a distance matrix for detected bounding boxes. post processing is consist of: - 1. omitting large boxes by filtering boxes which are biger than the 1/4 of the size the image. - 2. omitting duplicated boxes by applying an auxilary non-maximum-suppression. - 3. apply a simple object tracker to make the detection more robust. + omitting large boxes by filtering boxes which are biger than the 1/4 of the size the image. params: object_list: a list of dictionaries. each dictionary has attributes of a detected object such as @@ -170,15 +165,7 @@ def calculate_distancing(self, objects_list): distances: a NxN ndarray which i,j element is distance between i-th and l-th bounding box """ - new_objects_list = self.ignore_large_boxes(objects_list) - new_objects_list = self.non_max_suppression_fast(new_objects_list, - float(self.config.get_section_dict("PostProcessor")[ - "NMSThreshold"])) - tracked_boxes = self.tracker.update(new_objects_list) - new_objects_list = [tracked_boxes[i] for i in tracked_boxes.keys()] - for i, item in enumerate(new_objects_list): - item["id"] = item["id"].split("-")[0] + "-" + str(i) - + new_objects_list = self.ignore_large_boxes(objects_list) centroids = np.array( [obj["centroid"] for obj in new_objects_list] ) distances = self.calculate_box_distances(new_objects_list) @@ -203,59 +190,6 @@ def ignore_large_boxes(object_list): updated_object_list = [j for i, j in enumerate(object_list) if i not in large_boxes] return updated_object_list - @staticmethod - def non_max_suppression_fast(object_list, overlapThresh): - - """ - omitting duplicated boxes by applying an auxilary non-maximum-suppression. - params: - object_list: a list of dictionaries. each dictionary has attributes of a detected object such - "id", "centroid" (a tuple of the normalized centroid coordinates (cx,cy,w,h) of the box) and "bbox" (a tuple - of the normalized (xmin,ymin,xmax,ymax) coordinate of the box) - - overlapThresh: threshold of minimum IoU of to detect two box as duplicated. - - returns: - object_list: input object list without duplicated boxes - """ - # if there are no boxes, return an empty list - boxes = np.array([item["centroid"] for item in object_list]) - corners = np.array([item["bbox"] for item in object_list]) - if len(boxes) == 0: - return [] - if boxes.dtype.kind == "i": - boxes = boxes.astype("float") - # initialize the list of picked indexes - pick = [] - cy = boxes[:, 1] - cx = boxes[:, 0] - h = boxes[:, 3] - w = boxes[:, 2] - x1 = corners[:, 0] - x2 = corners[:, 2] - y1 = corners[:, 1] - y2 = corners[:, 3] - area = (h + 1) * (w + 1) - idxs = np.argsort(cy + (h / 2)) - while len(idxs) > 0: - last = len(idxs) - 1 - i = idxs[last] - pick.append(i) - xx1 = np.maximum(x1[i], x1[idxs[:last]]) - yy1 = np.maximum(y1[i], y1[idxs[:last]]) - xx2 = np.minimum(x2[i], x2[idxs[:last]]) - yy2 = np.minimum(y2[i], y2[idxs[:last]]) - - w = np.maximum(0, xx2 - xx1 + 1) - h = np.maximum(0, yy2 - yy1 + 1) - # compute the ratio of overlap - overlap = (w * h) / area[idxs[:last]] - # delete all indexes from the index list that have - idxs = np.delete(idxs, np.concatenate(([last], - np.where(overlap > overlapThresh)[0]))) - updated_object_list = [j for i, j in enumerate(object_list) if i in pick] - return updated_object_list - def calculate_distance_of_two_points_of_boxes(self,first_point, second_point): From ec91a1f10cd8c411f6db4fd138cb13768aa9efdf Mon Sep 17 00:00:00 2001 From: alpha-carinae29 Date: Fri, 29 May 2020 09:38:39 -0700 Subject: [PATCH 3/3] delete nms and tracker configs from config files --- config-jetson.ini | 2 -- config-skeleton.ini | 2 -- config-x86-openvino.ini | 2 -- config-x86.ini | 2 -- 4 files changed, 8 deletions(-) diff --git a/config-jetson.ini b/config-jetson.ini index 5d72fd3c..e201112c 100644 --- a/config-jetson.ini +++ b/config-jetson.ini @@ -16,8 +16,6 @@ ClassID: 0 MinScore: 0.25 [PostProcessor] -MaxTrackFrame: 5 -NMSThreshold: 0.98 ; distance threshold for smart distancing in (cm) DistThreshold: 150 ; ditance mesurement method, CenterPointsDistance: compare center of pedestrian boxes together, FourCornerPointsDistance: compare four corresponding points of pedestrian boxes and get the minimum of them. diff --git a/config-skeleton.ini b/config-skeleton.ini index e05ac908..5d9a8e7b 100644 --- a/config-skeleton.ini +++ b/config-skeleton.ini @@ -18,8 +18,6 @@ ClassID: 0 MinScore: 0.25 [PostProcessor] -MaxTrackFrame: 5 -NMSThreshold: 0.98 ; distance threshold for smart distancing in (cm) DistThreshold: 150 ; ditance mesurement method, CenterPointsDistance: compare center of pedestrian boxes together, FourCornerPointsDistance: compare four corresponding points of pedestrian boxes and get the minimum of them. diff --git a/config-x86-openvino.ini b/config-x86-openvino.ini index 6b3fe04c..ec0d41d7 100644 --- a/config-x86-openvino.ini +++ b/config-x86-openvino.ini @@ -16,8 +16,6 @@ ClassID: 1 MinScore: 0.25 [PostProcessor] -MaxTrackFrame: 5 -NMSThreshold: 0.98 ; distance threshold for smart distancing in (cm) DistThreshold: 150 DistMethod: CenterPointsDistance diff --git a/config-x86.ini b/config-x86.ini index ebdb296a..fbad5a44 100644 --- a/config-x86.ini +++ b/config-x86.ini @@ -16,8 +16,6 @@ ClassID: 1 MinScore: 0.25 [PostProcessor] -MaxTrackFrame: 5 -NMSThreshold: 0.98 ; distance threshold for smart distancing in (cm) DistThreshold: 150 DistMethod: CenterPointsDistance