Skip to content

Commit

Permalink
bug fixes in prediction and summary
Browse files Browse the repository at this point in the history
  • Loading branch information
HeshanSudarshana committed Apr 29, 2019
1 parent da83a83 commit a82c601
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 157 deletions.
295 changes: 148 additions & 147 deletions src/centroid_tracker/centroidtracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,151 +3,152 @@
from collections import OrderedDict
import numpy as np


class CentroidTracker():
def __init__(self, maxDisappeared=5):
# initialize the next unique object ID along with two ordered
# dictionaries used to keep track of mapping a given object
# ID to its centroid and number of consecutive frames it has
# been marked as "disappeared", respectively
self.nextObjectID = 0
self.objects = OrderedDict()
self.disappeared = OrderedDict()

# store the number of maximum consecutive frames a given
# object is allowed to be marked as "disappeared" until we
# need to deregister the object from tracking
self.maxDisappeared = maxDisappeared

def register(self, centroid):
# when registering an object we use the next available object
# ID to store the centroid
self.objects[self.nextObjectID] = centroid
self.disappeared[self.nextObjectID] = 0
self.nextObjectID += 1

def deregister(self, objectID):
# to deregister an object ID we delete the object ID from
# both of our respective dictionaries
del self.objects[objectID]
del self.disappeared[objectID]

def update(self, rects):
# check to see if the list of input bounding box rectangles
# is empty
if len(rects) == 0:
# loop over any existing tracked objects and mark them
# as disappeared
for objectID in self.disappeared.keys():
self.disappeared[objectID] += 1

# if we have reached a maximum number of consecutive
# frames where a given object has been marked as
# missing, deregister it
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)

# return early as there are no centroids or tracking info
# to update
return self.objects

# initialize an array of input centroids for the current frame
inputCentroids = np.zeros((len(rects), 2), dtype="int")

# loop over the bounding box rectangles
for (i, (startX, startY, endX, endY)) in enumerate(rects):
# use the bounding box coordinates to derive the centroid
cX = int((startX + endX) / 2.0)
cY = int((startY + endY) / 2.0)
inputCentroids[i] = (cX, cY)

# if we are currently not tracking any objects take the input
# centroids and register each of them
if len(self.objects) == 0:
for i in range(0, len(inputCentroids)):
self.register(inputCentroids[i])

# otherwise, are are currently tracking objects so we need to
# try to match the input centroids to existing object
# centroids
else:
# grab the set of object IDs and corresponding centroids
objectIDs = list(self.objects.keys())
objectCentroids = list(self.objects.values())

# compute the distance between each pair of object
# centroids and input centroids, respectively -- our
# goal will be to match an input centroid to an existing
# object centroid
D = dist.cdist(np.array(objectCentroids), inputCentroids)

# in order to perform this matching we must (1) find the
# smallest value in each row and then (2) sort the row
# indexes based on their minimum values so that the row
# with the smallest value as at the *front* of the index
# list
rows = D.min(axis=1).argsort()

# next, we perform a similar process on the columns by
# finding the smallest value in each column and then
# sorting using the previously computed row index list
cols = D.argmin(axis=1)[rows]

# in order to determine if we need to update, register,
# or deregister an object we need to keep track of which
# of the rows and column indexes we have already examined
usedRows = set()
usedCols = set()

# loop over the combination of the (row, column) index
# tuples
for (row, col) in zip(rows, cols):
# if we have already examined either the row or
# column value before, ignore it
# val
if row in usedRows or col in usedCols:
continue

# otherwise, grab the object ID for the current row,
# set its new centroid, and reset the disappeared
# counter
objectID = objectIDs[row]
self.objects[objectID] = inputCentroids[col]
self.disappeared[objectID] = 0

# indicate that we have examined each of the row and
# column indexes, respectively
usedRows.add(row)
usedCols.add(col)

# compute both the row and column index we have NOT yet
# examined
unusedRows = set(range(0, D.shape[0])).difference(usedRows)
unusedCols = set(range(0, D.shape[1])).difference(usedCols)

# in the event that the number of object centroids is
# equal or greater than the number of input centroids
# we need to check and see if some of these objects have
# potentially disappeared
if D.shape[0] >= D.shape[1]:
# loop over the unused row indexes
for row in unusedRows:
# grab the object ID for the corresponding row
# index and increment the disappeared counter
objectID = objectIDs[row]
self.disappeared[objectID] += 1

# check to see if the number of consecutive
# frames the object has been marked "disappeared"
# for warrants deregistering the object
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)

# otherwise, if the number of input centroids is greater
# than the number of existing object centroids we need to
# register each new input centroid as a trackable object
else:
for col in unusedCols:
self.register(inputCentroids[col])

# return the set of trackable objects
return self.objects
def __init__(self, maxDisappeared=30):
# initialize the next unique object ID along with two ordered
# dictionaries used to keep track of mapping a given object
# ID to its centroid and number of consecutive frames it has
# been marked as "disappeared", respectively
self.nextObjectID = 0
self.objects = OrderedDict()
self.disappeared = OrderedDict()

# store the number of maximum consecutive frames a given
# object is allowed to be marked as "disappeared" until we
# need to deregister the object from tracking
self.maxDisappeared = maxDisappeared

def register(self, centroid):
# when registering an object we use the next available object
# ID to store the centroid
self.objects[self.nextObjectID] = centroid
self.disappeared[self.nextObjectID] = 0
self.nextObjectID += 1

def deregister(self, objectID):
# to deregister an object ID we delete the object ID from
# both of our respective dictionaries
del self.objects[objectID]
del self.disappeared[objectID]

def update(self, rects):
# check to see if the list of input bounding box rectangles
# is empty
if len(rects) == 0:
# loop over any existing tracked objects and mark them
# as disappeared
for objectID in self.disappeared.keys():
self.disappeared[objectID] += 1

# if we have reached a maximum number of consecutive
# frames where a given object has been marked as
# missing, deregister it
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)

# return early as there are no centroids or tracking info
# to update
return self.objects

# initialize an array of input centroids for the current frame
inputCentroids = np.zeros((len(rects), 2), dtype="int")

# loop over the bounding box rectangles
for (i, (startX, startY, endX, endY)) in enumerate(rects):
# use the bounding box coordinates to derive the centroid
cX = int((startX + endX) / 2.0)
cY = int((startY + endY) / 2.0)
inputCentroids[i] = (cX, cY)

# if we are currently not tracking any objects take the input
# centroids and register each of them
if len(self.objects) == 0:
for i in range(0, len(inputCentroids)):
self.register(inputCentroids[i])

# otherwise, are are currently tracking objects so we need to
# try to match the input centroids to existing object
# centroids
else:
# grab the set of object IDs and corresponding centroids
objectIDs = list(self.objects.keys())
objectCentroids = list(self.objects.values())

# compute the distance between each pair of object
# centroids and input centroids, respectively -- our
# goal will be to match an input centroid to an existing
# object centroid
D = dist.cdist(np.array(objectCentroids), inputCentroids)

# in order to perform this matching we must (1) find the
# smallest value in each row and then (2) sort the row
# indexes based on their minimum values so that the row
# with the smallest value as at the *front* of the index
# list
rows = D.min(axis=1).argsort()

# next, we perform a similar process on the columns by
# finding the smallest value in each column and then
# sorting using the previously computed row index list
cols = D.argmin(axis=1)[rows]

# in order to determine if we need to update, register,
# or deregister an object we need to keep track of which
# of the rows and column indexes we have already examined
usedRows = set()
usedCols = set()

# loop over the combination of the (row, column) index
# tuples
for (row, col) in zip(rows, cols):
# if we have already examined either the row or
# column value before, ignore it
# val
if row in usedRows or col in usedCols:
continue

# otherwise, grab the object ID for the current row,
# set its new centroid, and reset the disappeared
# counter
objectID = objectIDs[row]
self.objects[objectID] = inputCentroids[col]
self.disappeared[objectID] = 0

# indicate that we have examined each of the row and
# column indexes, respectively
usedRows.add(row)
usedCols.add(col)

# compute both the row and column index we have NOT yet
# examined
unusedRows = set(range(0, D.shape[0])).difference(usedRows)
unusedCols = set(range(0, D.shape[1])).difference(usedCols)

# in the event that the number of object centroids is
# equal or greater than the number of input centroids
# we need to check and see if some of these objects have
# potentially disappeared
if D.shape[0] >= D.shape[1]:
# loop over the unused row indexes
for row in unusedRows:
# grab the object ID for the corresponding row
# index and increment the disappeared counter
objectID = objectIDs[row]
self.disappeared[objectID] += 1

# check to see if the number of consecutive
# frames the object has been marked "disappeared"
# for warrants deregistering the object
if self.disappeared[objectID] > self.maxDisappeared:
self.deregister(objectID)

# otherwise, if the number of input centroids is greater
# than the number of existing object centroids we need to
# register each new input centroid as a trackable object
else:
for col in unusedCols:
self.register(inputCentroids[col])

# return the set of trackable objects
return self.objects
14 changes: 12 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import datetime
from shutil import copyfile

import video_to_frames
import video_to_frames_no_skipping
from frame_seperater import FrameSeperator
import create_shot_boundaries
import objects_identifier_of_frames
import summary_from_frames_with_obj
import frames_to_video


def run():
Expand All @@ -31,7 +32,7 @@ def run():
print('Error: Creating directory of data')

# video broken to frames
video_to_frames.get_frames(original_video_location, location_to_store_all_frames)
video_to_frames_no_skipping.get_frames(original_video_location, location_to_store_all_frames)

# shot boundaries are identified
shot_boundaries = create_shot_boundaries.run(location_to_store_all_frames)
Expand Down Expand Up @@ -77,6 +78,15 @@ def run():

print(
"\n**************** Keyframes moved to the ./test_data/generated_summary_keyframes/ location ****************")

output_video_path = "./test_data/output_video/"
output_video_name = "output_video.avi"
fps = 8.0
frames_to_video.convert_frames_to_video(location_to_store_summary_keyframes, output_video_path, output_video_name, fps)

print(
"\n**************** summary video generated ./test_data/output_video/ location ****************")

elapsed_time = datetime.datetime.now() - t1
print("elapsed time is " + str(elapsed_time))

Expand Down
7 changes: 5 additions & 2 deletions src/net/netarch.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,17 @@ def predict(self, image):
output = self._inf_model.predict(image)[0]

if output.size == 0:
list1 = []
return list1
return [], []

boxes = output[:, :4]
label_idxs = output[:,5].astype(int)

labels = [YoloParams.CLASS_LABELS[l] for l in label_idxs]

# if (boxes is None) and (labels is None):
# boxes = []
# labels = []

return boxes, labels


Expand Down
10 changes: 4 additions & 6 deletions src/summary_from_frames_with_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def summary_from_frames_with_obj(frame_dic_with_objects):
elif set(frames_with_max_obj[obj_frame_index]).issubset(set(frame)):
if frames_with_max_obj[obj_frame_index] not in redundant_frames:
redundant_frames.append(frames_with_max_obj[obj_frame_index])
break

if new_obj:
frames_with_max_obj.append(frame)

Expand All @@ -24,16 +24,14 @@ def summary_from_frames_with_obj(frame_dic_with_objects):
if frame_name not in summary_frames:
summary_frames.append(frame_name)

# for index in range(len(frames_with_max_obj) - 1):
# for j in range(index + 1, len(frames_with_max_obj)):
# if set(frames_with_max_obj[index]).issubset(set(frames_with_max_obj[j])):
# redundant_frames.append(index)

for obj_set in redundant_frames:
redundant_index = frames_with_max_obj.index(obj_set)
frames_with_max_obj.pop(redundant_index)
summary_frames.pop(redundant_index)

for i in frames_with_max_obj:
print(i)

return summary_frames


Expand Down

0 comments on commit a82c601

Please sign in to comment.