119 lines
3.6 KiB
Python
119 lines
3.6 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""
|
||
Created on Wed Sep 20 14:28:20 2023
|
||
|
||
@author: ym
|
||
"""
|
||
import numpy as np
|
||
from scipy.spatial.distance import cdist
|
||
|
||
|
||
def boxes_add_fid(tboxes):
|
||
'''
|
||
将 bboxes 对应的帧索引添加到 boxes 最后一列
|
||
Return:
|
||
bboxes: [x1, y1, x2, y2, track_id, score, cls, frame_index]
|
||
'''
|
||
|
||
bboxes = np.empty((0, 8), dtype = np.float32)
|
||
for tbox, f in tboxes:
|
||
data = tbox.numpy()
|
||
|
||
frame = f * np.ones([data.shape[0], 1])
|
||
bbox = np.concatenate([data, frame], axis=1)
|
||
bboxes = np.concatenate([bboxes, bbox], axis=0)
|
||
|
||
return bboxes
|
||
|
||
|
||
|
||
def array2list(bboxes):
|
||
'''
|
||
将 bboxes 变换为 track 列表
|
||
bboxes: [x1, y1, x2, y2, track_id, score, cls, frame_index]
|
||
Return:
|
||
lboxes:列表,列表中元素具有同一 track_id,xywh 格式
|
||
[x, y, w, h, track_id, score, cls, frame_index]
|
||
'''
|
||
track_ids = set(bboxes[:, 4])
|
||
lboxes = []
|
||
for t_id in track_ids:
|
||
idx = np.where(bboxes[:, 4] == t_id)[0]
|
||
box = bboxes[idx, :]
|
||
|
||
x = (box[:, 0] + box[:, 2]) / 2
|
||
y = (box[:, 1] + box[:, 3]) / 2
|
||
|
||
# box: [x, y, w, h, track_id, score, cls, frame_index]
|
||
box[:, 2] = box[:, 2] - box[:, 0]
|
||
box[:, 3] = box[:, 3] - box[:, 1]
|
||
box[:, 0] = x
|
||
box[:, 1] = y
|
||
|
||
lboxes.append(box)
|
||
|
||
return lboxes
|
||
|
||
|
||
def max_dist_track(tboxes):
|
||
|
||
'''
|
||
计算 tboxes 中最大dist的 track
|
||
Return:
|
||
'''
|
||
|
||
max_track_dist, max_dist = 0, 0
|
||
for track in tboxes:
|
||
box = track[:, :4].astype(int)
|
||
|
||
dist = cdist(box[:, :2], box[:, :2])
|
||
|
||
dm = np.max(dist)
|
||
if dm > max_dist:
|
||
max_dist = dm
|
||
max_track = track.copy()
|
||
max_track_dist = dist.copy()
|
||
|
||
|
||
# 同一 track_id 中目标中心移动最大距离的索引(ix1, ix2)
|
||
indx, indy = np.where(dist == dm)
|
||
ix1, ix2 = indx[0], indy[0]
|
||
# 确保 ix1 < ix2,索引 ix1 是开始时的视频
|
||
if ix1 > ix2: ix1, ix2 = ix2, ix1
|
||
|
||
# =============================================================================
|
||
# # =============================================================================
|
||
# # 逻辑分析
|
||
# # =============================================================================
|
||
# Scanzone = ((0, int(Height/4)), (int(2*Weight/3), Weight))
|
||
# if max_track.shape[0] > 10:
|
||
#
|
||
# # max_track 视频序列的第一帧索引 idx1
|
||
# frame_1 = int(min(max_track[:, 7]))
|
||
# idx1 = np.where(max_track[:, 7] == frame_1)[0][0]
|
||
#
|
||
# # max_track 视频序列的最后一帧索引 idx2
|
||
# frame_2 = int(max(max_track[:, 7]))
|
||
# idx2 = np.where(max_track[:, 7] == frame_2)[0][0]
|
||
#
|
||
# # max_track 视频序列的第一帧目标位置中心 (x1, y1)
|
||
# x1, y1 = max_track[idx1, :2]
|
||
#
|
||
# # max_track 视频序列的第最后一帧目标位置中心 (x2, y2)
|
||
# x2, y2 = max_track[idx2, :2]
|
||
#
|
||
#
|
||
# # track序列第一帧和最后一帧的距离,该距离和 mx_dist 不是一个概念
|
||
# dist_1_2 = max_track_dist[idx1, idx2]
|
||
#
|
||
# if max_dist < 3 * Height/10:
|
||
# State = Uncertain
|
||
#
|
||
# elif y1 > y2:
|
||
# State = TakeOut
|
||
#
|
||
# elif y1 < y2:
|
||
# State = PutIn
|
||
# =============================================================================
|
||
return max_track, max_dist
|