SUM010's picture
Upload 2120 files
7b7527a
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
This code is based on https://github.com/LCFractal/AIC21-MTMC/tree/main/reid/reid-matching/tools
Note: The following codes are strongly related to camera parameters of the AIC21 test-set S06,
so they can only be used in S06, and can not be used for other MTMCT datasets.
"""
import numpy as np
try:
from sklearn.cluster import AgglomerativeClustering
except:
print(
'Warning: Unable to use MTMCT in PP-Tracking, please install sklearn, for example: `pip install sklearn`'
)
pass
from .utils import get_dire, get_match, get_cid_tid, combin_feature, combin_cluster
from .utils import normalize, intracam_ignore, visual_rerank
__all__ = [
'st_filter',
'get_labels_with_camera',
]
CAM_DIST = [[0, 40, 55, 100, 120, 145], [40, 0, 15, 60, 80, 105],
[55, 15, 0, 40, 65, 90], [100, 60, 40, 0, 20, 45],
[120, 80, 65, 20, 0, 25], [145, 105, 90, 45, 25, 0]]
def st_filter(st_mask, cid_tids, cid_tid_dict):
count = len(cid_tids)
for i in range(count):
i_tracklet = cid_tid_dict[cid_tids[i]]
i_cid = i_tracklet['cam']
i_dire = get_dire(i_tracklet['zone_list'], i_cid)
i_iot = i_tracklet['io_time']
for j in range(count):
j_tracklet = cid_tid_dict[cid_tids[j]]
j_cid = j_tracklet['cam']
j_dire = get_dire(j_tracklet['zone_list'], j_cid)
j_iot = j_tracklet['io_time']
match_dire = True
cam_dist = CAM_DIST[i_cid - 41][j_cid - 41]
# if time overlopped
if i_iot[0] - cam_dist < j_iot[0] and j_iot[0] < i_iot[
1] + cam_dist:
match_dire = False
if i_iot[0] - cam_dist < j_iot[1] and j_iot[1] < i_iot[
1] + cam_dist:
match_dire = False
# not match after go out
if i_dire[1] in [1, 2]: # i out
if i_iot[0] < j_iot[1] + cam_dist:
match_dire = False
if i_dire[1] in [1, 2]:
if i_dire[0] in [3] and i_cid > j_cid:
match_dire = False
if i_dire[0] in [4] and i_cid < j_cid:
match_dire = False
if i_cid in [41] and i_dire[1] in [4]:
if i_iot[0] < j_iot[1] + cam_dist:
match_dire = False
if i_iot[1] > 199:
match_dire = False
if i_cid in [46] and i_dire[1] in [3]:
if i_iot[0] < j_iot[1] + cam_dist:
match_dire = False
# match after come into
if i_dire[0] in [1, 2]:
if i_iot[1] > j_iot[0] - cam_dist:
match_dire = False
if i_dire[0] in [1, 2]:
if i_dire[1] in [3] and i_cid > j_cid:
match_dire = False
if i_dire[1] in [4] and i_cid < j_cid:
match_dire = False
is_ignore = False
if ((i_dire[0] == i_dire[1] and i_dire[0] in [3, 4]) or
(j_dire[0] == j_dire[1] and j_dire[0] in [3, 4])):
is_ignore = True
if not is_ignore:
# direction conflict
if (i_dire[0] in [3] and j_dire[0] in [4]) or (
i_dire[1] in [3] and j_dire[1] in [4]):
match_dire = False
# filter before going next scene
if i_dire[1] in [3] and i_cid < j_cid:
if i_iot[1] > j_iot[1] - cam_dist:
match_dire = False
if i_dire[1] in [4] and i_cid > j_cid:
if i_iot[1] > j_iot[1] - cam_dist:
match_dire = False
if i_dire[0] in [3] and i_cid < j_cid:
if i_iot[0] < j_iot[0] + cam_dist:
match_dire = False
if i_dire[0] in [4] and i_cid > j_cid:
if i_iot[0] < j_iot[0] + cam_dist:
match_dire = False
## 3-30
## 4-1
if i_dire[0] in [3] and i_cid > j_cid:
if i_iot[1] > j_iot[0] - cam_dist:
match_dire = False
if i_dire[0] in [4] and i_cid < j_cid:
if i_iot[1] > j_iot[0] - cam_dist:
match_dire = False
# filter before going next scene
## 4-7
if i_dire[1] in [3] and i_cid > j_cid:
if i_iot[0] < j_iot[1] + cam_dist:
match_dire = False
if i_dire[1] in [4] and i_cid < j_cid:
if i_iot[0] < j_iot[1] + cam_dist:
match_dire = False
else:
if i_iot[1] > 199:
if i_dire[0] in [3] and i_cid < j_cid:
if i_iot[0] < j_iot[0] + cam_dist:
match_dire = False
if i_dire[0] in [4] and i_cid > j_cid:
if i_iot[0] < j_iot[0] + cam_dist:
match_dire = False
if i_dire[0] in [3] and i_cid > j_cid:
match_dire = False
if i_dire[0] in [4] and i_cid < j_cid:
match_dire = False
if i_iot[0] < 1:
if i_dire[1] in [3] and i_cid > j_cid:
match_dire = False
if i_dire[1] in [4] and i_cid < j_cid:
match_dire = False
if not match_dire:
st_mask[i, j] = 0.0
st_mask[j, i] = 0.0
return st_mask
def subcam_list(cid_tid_dict, cid_tids):
sub_3_4 = dict()
sub_4_3 = dict()
for cid_tid in cid_tids:
cid, tid = cid_tid
tracklet = cid_tid_dict[cid_tid]
zs, ze = get_dire(tracklet['zone_list'], cid)
if zs in [3] and cid not in [46]: # 4 to 3
if not cid + 1 in sub_4_3:
sub_4_3[cid + 1] = []
sub_4_3[cid + 1].append(cid_tid)
if ze in [4] and cid not in [41]: # 4 to 3
if not cid in sub_4_3:
sub_4_3[cid] = []
sub_4_3[cid].append(cid_tid)
if zs in [4] and cid not in [41]: # 3 to 4
if not cid - 1 in sub_3_4:
sub_3_4[cid - 1] = []
sub_3_4[cid - 1].append(cid_tid)
if ze in [3] and cid not in [46]: # 3 to 4
if not cid in sub_3_4:
sub_3_4[cid] = []
sub_3_4[cid].append(cid_tid)
sub_cid_tids = dict()
for i in sub_3_4:
sub_cid_tids[(i, i + 1)] = sub_3_4[i]
for i in sub_4_3:
sub_cid_tids[(i, i - 1)] = sub_4_3[i]
return sub_cid_tids
def subcam_list2(cid_tid_dict, cid_tids):
sub_dict = dict()
for cid_tid in cid_tids:
cid, tid = cid_tid
if cid not in [41]:
if not cid in sub_dict:
sub_dict[cid] = []
sub_dict[cid].append(cid_tid)
if cid not in [46]:
if not cid + 1 in sub_dict:
sub_dict[cid + 1] = []
sub_dict[cid + 1].append(cid_tid)
return sub_dict
def get_sim_matrix(cid_tid_dict,
cid_tids,
use_ff=True,
use_rerank=True,
use_st_filter=False):
# Note: camera releated get_sim_matrix function,
# which is different from the one in utils.py.
count = len(cid_tids)
q_arr = np.array(
[cid_tid_dict[cid_tids[i]]['mean_feat'] for i in range(count)])
g_arr = np.array(
[cid_tid_dict[cid_tids[i]]['mean_feat'] for i in range(count)])
q_arr = normalize(q_arr, axis=1)
g_arr = normalize(g_arr, axis=1)
st_mask = np.ones((count, count), dtype=np.float32)
st_mask = intracam_ignore(st_mask, cid_tids)
# different from utils.py
if use_st_filter:
st_mask = st_filter(st_mask, cid_tids, cid_tid_dict)
visual_sim_matrix = visual_rerank(
q_arr, g_arr, cid_tids, use_ff=use_ff, use_rerank=use_rerank)
visual_sim_matrix = visual_sim_matrix.astype('float32')
np.set_printoptions(precision=3)
sim_matrix = visual_sim_matrix * st_mask
np.fill_diagonal(sim_matrix, 0)
return sim_matrix
def get_labels_with_camera(cid_tid_dict,
cid_tids,
use_ff=True,
use_rerank=True,
use_st_filter=False):
# 1st cluster
sub_cid_tids = subcam_list(cid_tid_dict, cid_tids)
sub_labels = dict()
dis_thrs = [0.7, 0.5, 0.5, 0.5, 0.5, 0.7, 0.5, 0.5, 0.5, 0.5]
for i, sub_c_to_c in enumerate(sub_cid_tids):
sim_matrix = get_sim_matrix(
cid_tid_dict,
sub_cid_tids[sub_c_to_c],
use_ff=use_ff,
use_rerank=use_rerank,
use_st_filter=use_st_filter)
cluster_labels = AgglomerativeClustering(
n_clusters=None,
distance_threshold=1 - dis_thrs[i],
affinity='precomputed',
linkage='complete').fit_predict(1 - sim_matrix)
labels = get_match(cluster_labels)
cluster_cid_tids = get_cid_tid(labels, sub_cid_tids[sub_c_to_c])
sub_labels[sub_c_to_c] = cluster_cid_tids
labels, sub_cluster = combin_cluster(sub_labels, cid_tids)
# 2nd cluster
cid_tid_dict_new = combin_feature(cid_tid_dict, sub_cluster)
sub_cid_tids = subcam_list2(cid_tid_dict_new, cid_tids)
sub_labels = dict()
for i, sub_c_to_c in enumerate(sub_cid_tids):
sim_matrix = get_sim_matrix(
cid_tid_dict_new,
sub_cid_tids[sub_c_to_c],
use_ff=use_ff,
use_rerank=use_rerank,
use_st_filter=use_st_filter)
cluster_labels = AgglomerativeClustering(
n_clusters=None,
distance_threshold=1 - 0.1,
affinity='precomputed',
linkage='complete').fit_predict(1 - sim_matrix)
labels = get_match(cluster_labels)
cluster_cid_tids = get_cid_tid(labels, sub_cid_tids[sub_c_to_c])
sub_labels[sub_c_to_c] = cluster_cid_tids
labels, sub_cluster = combin_cluster(sub_labels, cid_tids)
return labels