Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #207

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open

Dev #207

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 3 additions & 43 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so
Expand All @@ -12,9 +11,7 @@ env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
Expand All @@ -24,12 +21,6 @@ var/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt
Expand All @@ -38,52 +29,21 @@ pip-delete-this-directory.txt
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject
model_data
model_data/
.ipynb_checkpoints/

# Rope project settings
.ropeproject
6 changes: 6 additions & 0 deletions MyReadMe.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
python my_deep_sort_app.py \
--sequence_dir=$HOME/e/dataset_tiptical/MOT16/MOT16-06 \
--detection_file=$HOME/e/dataset_tiptical/MOT16/MOT16-06/MOT16-06.npy \
--min_confidence=0.3 \
--nn_budget=100 \
--display=True
12 changes: 11 additions & 1 deletion deep_sort/linear_assignment.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
# vim: expandtab:ts=4:sw=4
from __future__ import absolute_import
import numpy as np
from sklearn.utils.linear_assignment_ import linear_assignment

import sklearn
#FutureWarning: The linear_assignment function is deprecated in 0.21 and will be removed from 0.23. Use scipy.optimize.linear_sum_assignment instead.
if sklearn.__version__>'0.22':
from scipy.optimize import linear_sum_assignment as linear_assignment # tf1.15, sklearn=>0.23
else:
from sklearn.utils.linear_assignment_ import linear_assignment # tf1.14, sklearn=>0.22
from . import kalman_filter


Expand Down Expand Up @@ -57,6 +63,10 @@ def min_cost_matching(
cost_matrix[cost_matrix > max_distance] = max_distance + 1e-5
indices = linear_assignment(cost_matrix)

# Fix for tf1.15 envirement when use scipy.optimize.linear_sum_assignment instead from sklearn.utils.linear_assignment_
if type(indices)==tuple:
indices = np.array([[x,y] for x,y in zip(*indices)])

matches, unmatched_tracks, unmatched_detections = [], [], []
for col, detection_idx in enumerate(detection_indices):
if col not in indices[:, 1]:
Expand Down
4 changes: 2 additions & 2 deletions deep_sort/nn_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def _cosine_distance(a, b, data_is_normalized=False):

"""
if not data_is_normalized:
a = np.asarray(a) / np.linalg.norm(a, axis=1, keepdims=True)
b = np.asarray(b) / np.linalg.norm(b, axis=1, keepdims=True)
a = np.asarray(a) / (np.linalg.norm(a, axis=1, keepdims=True)+1e-5)
b = np.asarray(b) / (np.linalg.norm(b, axis=1, keepdims=True)+1e-5)
return 1. - np.dot(a, b.T)


Expand Down
1 change: 1 addition & 0 deletions deep_sort_ex/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# vim: expandtab:ts=4:sw=4
67 changes: 67 additions & 0 deletions deep_sort_ex/detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# vim: expandtab:ts=4:sw=4
import numpy as np


class Detection(object):
"""
This class represents a bounding box detection in a single image.

Parameters
----------
tlwh : array_like
Bounding box in format `(x, y, w, h)`.
confidence : float
Detector confidence score.
feature : array_like
A feature vector that describes the object contained in this image.

Attributes
----------
tlwh : ndarray
Bounding box in format `(top left x, top left y, width, height)`.
confidence : ndarray
Detector confidence score.
feature : ndarray | NoneType
A feature vector that describes the object contained in this image.

"""

def __init__(self, tlwh, confidence, feature, t=None, exts1=None, exts2=None, binding_obj=None, flag=None):
'''
@param tlwh - bbox: top, left, width, height
@param confidence - 目标检测置信度
@param ffeature - 目标图像特征码
@param t - 检测时间(秒)
@param exts1 - 扩展属性: 扩展卡尔曼滤波器的向量(mean), 需要与 tracker,track的n_extend参数配合使用
@param exts2 - 扩展属性: 独立于卡尔曼滤波器,对扩展通道单独处理
@param binding_obj - 绑定原始目标检测的序号(或结构体对象),方便数据源跟踪
@param flag - 跟踪目标标记, 如用于目标类别,由外部解析
'''
self.tlwh = np.asarray(tlwh, dtype=np.float)
self.t = t
self.exts1 = exts1
self.exts2 = exts2
self.binding_obj = binding_obj
self.flag = flag
self.confidence = float(confidence)
self.feature = np.asarray(feature, dtype=np.float32)

def to_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

def to_xyah(self):
"""Convert bounding box to format `(center x, center y, aspect ratio,
height)`, where the aspect ratio is `width / height`.
"""
ret = self.tlwh.copy()
ret[:2] += ret[2:] / 2
ret[2] /= ret[3]
if self.exts1 is None:
return ret
else:
return np.hstack([ret, self.exts1])
81 changes: 81 additions & 0 deletions deep_sort_ex/iou_matching.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# vim: expandtab:ts=4:sw=4
from __future__ import absolute_import
import numpy as np
from . import linear_assignment


def iou(bbox, candidates):
"""Computer intersection over union.

Parameters
----------
bbox : ndarray
A bounding box in format `(top left x, top left y, width, height)`.
candidates : ndarray
A matrix of candidate bounding boxes (one per row) in the same format
as `bbox`.

Returns
-------
ndarray
The intersection over union in [0, 1] between the `bbox` and each
candidate. A higher score means a larger fraction of the `bbox` is
occluded by the candidate.

"""
bbox_tl, bbox_br = bbox[:2], bbox[:2] + bbox[2:]
candidates_tl = candidates[:, :2]
candidates_br = candidates[:, :2] + candidates[:, 2:]

tl = np.c_[np.maximum(bbox_tl[0], candidates_tl[:, 0])[:, np.newaxis],
np.maximum(bbox_tl[1], candidates_tl[:, 1])[:, np.newaxis]]
br = np.c_[np.minimum(bbox_br[0], candidates_br[:, 0])[:, np.newaxis],
np.minimum(bbox_br[1], candidates_br[:, 1])[:, np.newaxis]]
wh = np.maximum(0., br - tl)

area_intersection = wh.prod(axis=1)
area_bbox = bbox[2:].prod()
area_candidates = candidates[:, 2:].prod(axis=1)
return area_intersection / (area_bbox + area_candidates - area_intersection)


def iou_cost(tracks, detections, track_indices=None,
detection_indices=None):
"""An intersection over union distance metric.

Parameters
----------
tracks : List[deep_sort.track.Track]
A list of tracks.
detections : List[deep_sort.detection.Detection]
A list of detections.
track_indices : Optional[List[int]]
A list of indices to tracks that should be matched. Defaults to
all `tracks`.
detection_indices : Optional[List[int]]
A list of indices to detections that should be matched. Defaults
to all `detections`.

Returns
-------
ndarray
Returns a cost matrix of shape
len(track_indices), len(detection_indices) where entry (i, j) is
`1 - iou(tracks[track_indices[i]], detections[detection_indices[j]])`.

"""
if track_indices is None:
track_indices = np.arange(len(tracks))
if detection_indices is None:
detection_indices = np.arange(len(detections))

cost_matrix = np.zeros((len(track_indices), len(detection_indices)))
for row, track_idx in enumerate(track_indices):
if tracks[track_idx].time_since_update > 1:
cost_matrix[row, :] = linear_assignment.INFTY_COST
continue

bbox = tracks[track_idx].to_tlwh()
candidates = np.asarray([detections[i].tlwh for i in detection_indices])
cost_matrix[row, :] = 1. - iou(bbox, candidates)
return cost_matrix
Loading