88
99from cython_bbox import bbox_overlaps as bbox_ious
1010import kalman_filter
11+ import math
1112
1213def merge_matches (m1 , m2 , shape ):
1314 O ,P ,Q = shape
@@ -165,3 +166,111 @@ def fuse_motion(kf, cost_matrix, tracks, detections, only_position=False, lambda
165166 cost_matrix [row , gating_distance > gating_threshold ] = np .inf
166167 cost_matrix [row ] = lambda_ * cost_matrix [row ] + (1 - lambda_ )* gating_distance
167168 return cost_matrix
169+
170+
171+ """
172+ funcs to cal similarity, copied from UAVMOT
173+ """
174+ def local_relation_fuse_motion (cost_matrix ,
175+ tracks ,
176+ detections ,
177+ only_position = False ,
178+ lambda_ = 0.98 ):
179+ """
180+ :param kf:
181+ :param cost_matrix:
182+ :param tracks:
183+ :param detections:
184+ :param only_position:
185+ :param lambda_:
186+ :return:
187+ """
188+
189+ # print(cost_matrix.shape)
190+ if cost_matrix .size == 0 :
191+ return cost_matrix
192+
193+ gating_dim = 2 if only_position else 4
194+ # gating_threshold = kalman_filter.chi2inv95[gating_dim]
195+ # measurements = np.asarray([det.tlwh2xyah() for det in detections])
196+ structure_distance = structure_similarity_distance (tracks ,
197+ detections )
198+ cost_matrix = lambda_ * cost_matrix + (1 - lambda_ ) * structure_distance
199+
200+ return cost_matrix
201+ def structure_similarity_distance (tracks , detections ):
202+ track_structure = structure_representation (tracks )
203+ detection_structure = structure_representation (detections ,mode = 'detection' )
204+
205+ # for debug
206+ # print(track_structure.shape, detection_structure.shape)
207+ # exit(0)
208+ cost_matrix = np .maximum (0.0 , cdist (track_structure , detection_structure , metric = "cosine" ))
209+
210+ return cost_matrix
211+ def angle (v1 , v2 ):
212+ # dx1 = v1[2] - v1[0]
213+ # dy1 = v1[3] - v1[1]
214+ # dx2 = v2[2] - v2[0]
215+ # dy2 = v2[3] - v2[1]
216+ dx1 = v1 [0 ]
217+ dy1 = v1 [1 ]
218+ dx2 = v2 [0 ]
219+ dy2 = v2 [1 ]
220+ angle1 = math .atan2 (dy1 , dx1 )
221+ angle1 = int (angle1 * 180 / math .pi )
222+ # print(angle1)
223+ angle2 = math .atan2 (dy2 , dx2 )
224+ angle2 = int (angle2 * 180 / math .pi )
225+ # print(angle2)
226+ if angle1 * angle2 >= 0 :
227+ included_angle = abs (angle1 - angle2 )
228+ else :
229+ included_angle = abs (angle1 ) + abs (angle2 )
230+ if included_angle > 180 :
231+ included_angle = 360 - included_angle
232+ return included_angle
233+
234+ def structure_representation (tracks ,mode = 'trcak' ):
235+ local_R = 400
236+ structure_matrix = []
237+ for i , track_A in enumerate (tracks ):
238+ length = []
239+ index = []
240+ for j , track_B in enumerate (tracks ):
241+ # print(track_A.mean[0:2])
242+ # pp: 中心点距离 shape: (1, )
243+ if mode == "detection" :
244+ pp = list (
245+ map (lambda x : np .linalg .norm (np .array (x [0 ] - x [1 ])), zip (track_A .get_xy (), track_B .get_xy ())))
246+ else :
247+ pp = list (map (lambda x : np .linalg .norm (np .array (x [0 ] - x [1 ])), zip (track_A .mean [0 :2 ],track_B .mean [0 :2 ])))
248+ lgt = np .linalg .norm (pp )
249+ if lgt < local_R and lgt > 0 :
250+ length .append (lgt )
251+ index .append (j )
252+
253+ if length == []:
254+ v = [0.0001 ,0.0001 ,0.0001 ]
255+
256+ else :
257+ max_length = max (length )
258+ min_length = min (length )
259+ if max_length == min_length :
260+ v = [max_length , min_length , 0.0001 ]
261+ else :
262+ max_index = index [length .index (max_length )]
263+ min_index = index [length .index (min_length )]
264+ if mode == "detection" :
265+ v1 = tracks [max_index ].get_xy () - track_A .get_xy ()
266+ v2 = tracks [min_index ].get_xy () - track_A .get_xy ()
267+ else :
268+ v1 = tracks [max_index ].mean [0 :2 ] - track_A .mean [0 :2 ]
269+ v2 = tracks [min_index ].mean [0 :2 ] - track_A .mean [0 :2 ]
270+
271+ include_angle = angle (v1 , v2 )
272+ v = [max_length , min_length , include_angle ]
273+
274+ structure_matrix .append (v )
275+
276+ return np .asarray (structure_matrix )
0 commit comments