modify dotrack module

This commit is contained in:
王庆刚
2024-06-03 15:25:39 +08:00
parent d1ea304491
commit f90ef72cbf
19 changed files with 502 additions and 420 deletions

View File

@ -84,7 +84,6 @@ class Track:
boxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
0 1 2 3 4 5 6 7 8
'''
# 不满足以下条件时会如何?
# assert len(set(boxes[:, 4].astype(int))) == 1, "For a Track, track_id more than 1"
# assert len(set(boxes[:, 6].astype(int))) == 1, "For a Track, class number more than 1"
@ -110,7 +109,8 @@ class Track:
'''5个关键点中心点、左上点、右上点、左下点、右下点 )坐标'''
self.compute_cornpoints()
'''5个关键点轨迹特征可以在子类中实现降低顺序处理时的计算量'''
'''5个关键点轨迹特征可以在子类中实现降低顺序处理时的计算量
(中心点、左上点、右上点、左下点、右下点 )轨迹特征'''
self.compute_cornpts_feats()
@ -341,8 +341,6 @@ class Track:
return
class doTracks:
def __init__(self, bboxes, TracksDict):
@ -394,42 +392,7 @@ class doTracks:
lfeats.append(afeat)
return lfeats
'''
def classify(self):
tracks = self.tracks
# 提取手的frame_id并和动目标的frame_id 进行关联
hand_tracks = [t for t in tracks if t.cls==0]
self.Hands.extend(hand_tracks)
tracks = self.sub_tracks(tracks, hand_tracks)
# 提取小孩的track并计算状态left, right, incart
kid_tracks = [t for t in tracks if t.cls==9]
kid_states = [self.kid_state(t) for t in kid_tracks]
self.Kids = [x for x in zip(kid_tracks, kid_states)]
tracks = self.sub_tracks(tracks, kid_tracks)
static_tracks = [t for t in tracks if t.frnum>1 and t.is_static()]
self.Static.extend(static_tracks)
# 剔除静止目标后的 tracks
tracks = self.sub_tracks(tracks, static_tracks)
return tracks
'''
def similarity(self):
nt = len(self.tracks)

View File

@ -23,34 +23,6 @@ class doBackTracks(doTracks):
self.shopcart = ShoppingCart(bboxes)
# =============================================================================
# def array2list(self):
# ''' 0, 1, 2, 3, 4, 5, 6, 7, 8
# bboxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# lboxes[x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# '''
#
# track_ids = set(self.bboxes[:, 4])
# lboxes = []
# for t_id in track_ids:
# idx = np.where(self.bboxes[:, 4] == t_id)[0]
# box = self.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 classify(self):
'''功能:对 tracks 中元素分类 '''

View File

@ -122,25 +122,6 @@ class doFrontTracks(doTracks):
"""
对不同id但可能是同一商品的目标进行归并
"""
# =============================================================================
# mergedTracks = []
# alist = [t for t in Residual]
# while alist:
# atrack = alist[0]
# cur_list = []
# cur_list.append(atrack)
# alist.pop(0)
#
# blist = [b for b in alist]
# alist = []
# for btrack in blist:
# if track_equal_track(atrack, btrack, self.TracksDict):
# cur_list.append(btrack)
# else:
# alist.append(btrack)
#
# mergedTracks.append(cur_list)
# =============================================================================
mergedTracks = self.base_merge_tracks(Residual)
oldtracks, newtracks = [], []
@ -175,27 +156,3 @@ class doFrontTracks(doTracks):
return merged
# =============================================================================
# def array2list(self):
# '''
# 将 bboxes 变换为 track 列表
# bboxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# Return
# lboxes列表列表中元素具有同一 track_idx1y1x2y2 格式
# [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# '''
# track_ids = set(self.bboxes[:, 4])
# lboxes = []
# for t_id in track_ids:
# # print(f"The ID is: {t_id}")
# idx = np.where(self.bboxes[:, 4] == t_id)[0]
# box = self.bboxes[idx, :]
#
# lboxes.append(box)
#
# return lboxes
# =============================================================================

View File

@ -48,7 +48,6 @@ class backTrack(Track):
# self.PCA()
def isimgborder(self, BoundPixel=10, BoundThresh=0.3):
x1, y1 = self.cornpoints[:,2], self.cornpoints[:,3],
@ -74,69 +73,12 @@ class backTrack(Track):
MarginState = [condtA, condtB, condtC, condtD, condtE, condtF, condtG]
return isCornpoint, MarginState
# =============================================================================
# def PositionState(self, camerType="back"):
# '''
# 已迁移至基类
# camerType: back, 后置摄像头
# front, 前置摄像头
# '''
# if camerType=="front":
# incart = cv2.imread("./shopcart/cart_tempt/incart.png", cv2.IMREAD_GRAYSCALE)
# outcart = cv2.imread("./shopcart/cart_tempt/outcart.png", cv2.IMREAD_GRAYSCALE)
# else:
# incart = cv2.imread("./shopcart/cart_tempt/incart_ftmp.png", cv2.IMREAD_GRAYSCALE)
# outcart = cv2.imread("./shopcart/cart_tempt/outcart_ftmp.png", cv2.IMREAD_GRAYSCALE)
#
# xc, yc = self.cornpoints[:,0].clip(0,self.imgshape[0]-1).astype(np.int64), self.cornpoints[:,1].clip(0,self.imgshape[1]-1).astype(np.int64)
# x1, y1 = self.cornpoints[:,6].clip(0,self.imgshape[0]-1).astype(np.int64), self.cornpoints[:,7].clip(0,self.imgshape[1]-1).astype(np.int64)
# x2, y2 = self.cornpoints[:,8].clip(0,self.imgshape[0]-1).astype(np.int64), self.cornpoints[:,9].clip(0,self.imgshape[1]-1).astype(np.int64)
#
# # print(self.tid)
# Cent_inCartnum = np.count_nonzero(incart[(yc, xc)])
# LB_inCartnum = np.count_nonzero(incart[(y1, x1)])
# RB_inCartnum = np.count_nonzero(incart[(y2, x2)])
#
# Cent_outCartnum = np.count_nonzero(outcart[(yc, xc)])
# LB_outCartnum = np.count_nonzero(outcart[(y1, x1)])
# RB_outCartnum = np.count_nonzero(outcart[(y2, x2)])
#
# '''Track完全在车内左下角点、右下角点与 outcart 的交集为 0'''
# self.isWholeInCart = False
# if LB_outCartnum + RB_outCartnum == 0:
# self.isWholeInCart = True
#
# '''Track完全在车外左下角点、中心点与 incart 的交集为 0
# 右下角点、中心点与 incart 的交集为 0
# '''
# self.isWholeOutCart = False
# if Cent_inCartnum + LB_inCartnum == 0 or Cent_inCartnum + RB_inCartnum == 0:
# self.isWholeOutCart = True
#
#
# self.Cent_isIncart = False
# self.LB_isIncart = False
# self.RB_isIncart = False
# if Cent_inCartnum: self.Cent_isIncart = True
# if LB_inCartnum: self.LB_isIncart = True
# if RB_inCartnum: self.RB_isIncart = True
#
# self.posState = self.Cent_isIncart+self.LB_isIncart+self.RB_isIncart
# =============================================================================
def PCA(self):
self.pca = PCA()
X = self.cornpoints[:, 0:2]
self.pca.fit(X)
def compute_ious_feat(self):
@ -194,96 +136,8 @@ class backTrack(Track):
self.feature_ious = (incart_iou, outcart_iou, cartboarder_iou, maxbox_iou, minbox_iou)
self.incartrates = incartrates
def compute_static_fids(self, thresh1 = 12, thresh2 = 3):
'''
计算 track 的轨迹中相对处于静止状态的轨迹点的start_frame_id, end_frame_id
thresh1: 相邻两帧目标中心点是否静止的的阈值,以像素为单位,
thresh2: 连续捕捉到目标处于静止状态的帧数,当 thresh2 = 3时,至少连续 4个点,
产生3个相邻点差值均小于 thresh1 时,判定为连续静止.
处理过程中利用了插值技术因此start、end并非 self.boxes 中对应的帧索引
'''
BoundPixel = 8
x1, y1 = self.cornpoints[:,2], self.cornpoints[:,3],
x2, y2 = self.cornpoints[:,8], self.cornpoints[:,9]
cont1 = sum(abs(x1)<BoundPixel) > 3
# cont2 = sum(abs(y1)<BoundPixel) > 3
cont3 = sum(abs(x2-self.imgshape[0])<BoundPixel) > 3
# cont4 = sum(abs(y2-self.imgshape[1])<BoundPixel) > 3
cont = not(cont1 or cont3)
## ============== 下一步,启用中心点,选择具有最小运动幅度的角点作为参考点
static_index = []
if self.frnum>=2 and cont:
x1 = self.boxes[1:,7]
x2 = [i for i in range(int(min(x1)), int(max(x1)+1))]
dist_adjc = np.interp(x2, x1, self.trajmin)
# dist_adjc = self.trajmin
static_thresh = (dist_adjc < thresh1)[:, None].astype(np.uint8)
static_cnts, _ = cv2.findContours(static_thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
for cnt in static_cnts:
_, start, _, num = cv2.boundingRect(cnt)
end = start + num
if num < thresh2:
continue
static_index.append((start, end))
static_index = np.array(static_index)
if static_index.size:
indx = np.argsort(static_index[:, 0])
static_index = static_index[indx]
return static_index
def compute_dynamic_fids(self, thresh1 = 12, thresh2 = 3):
'''
计算 track 的轨迹中运动轨迹点的start_frame_id, end_frame_id
thresh1: 相邻两帧目标中心点是否运动的阈值,以像素为单位,
thresh2: 连续捕捉到目标连续运动的帧数
目标:
1. 计算轨迹方向
2. 计算和手部运动的关联性
'''
moving_index = []
if self.frnum>=2:
x1 = self.boxes[1:,7]
x2 = [i for i in range(int(min(x1)), int(max(x1)+1))]
dist_adjc = np.interp(x2, x1, self.trajmin)
moving_thresh = (dist_adjc >= thresh1)[:, None].astype(np.uint8)
moving_cnts, _ = cv2.findContours(moving_thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
for cnt in moving_cnts:
_, start, _, num = cv2.boundingRect(cnt)
if num < thresh2:
continue
end = start + num
moving_index.append((start, end))
# =============================================================================
# '''========= 输出帧id不太合适 ========='''
# moving_fids = []
# for i in range(len(moving_index)):
# i1, i2 = moving_index[i]
# fid1, fid2 = boxes[i1, 7], boxes[i2, 7]
# moving_fids.append([fid1, fid2])
# moving_fids = np.array(moving_fids)
# =============================================================================
moving_index = np.array(moving_index)
if moving_index.size:
indx = np.argsort(moving_index[:, 0])
moving_index = moving_index[indx]
return moving_index
def compute_static_dynamic_fids(self):
if self.MarginState[0] or self.MarginState[2]:
@ -319,17 +173,6 @@ class backTrack(Track):
return static, dynamic
# =============================================================================
# static_dynamic_fids = []
# for traj in self.trajectory:
# static, dynamic = self.pt_state_fids(traj)
# static_dynamic_fids.append((static, dynamic))
#
# return static_dynamic_fids
# =============================================================================
def is_static(self):
'''静态情况 1: 目标关键点最小相对运动轨迹 < 0.2, 指标值偏大
@ -354,7 +197,6 @@ class backTrack(Track):
# and self.posState >= 2
# and self.TrajFeat[0] < 240 \
'''静态情况 3: 目标初始状态和最终状态均为静止'''
condt3 = self.static_index.shape[0] >= 2 \
and self.static_index[0, 0] <= 2 \
@ -370,50 +212,23 @@ class backTrack(Track):
and self.static_index[0, 1] >= 6 \
and self.static_index[-1, 0] <= self.frnum-5 \
and self.static_index[-1, 1] >= self.frnum-2
condt = condt1 or condt2 or condt3 or condt4
return condt
# =============================================================================
# track1 = [t for t in tracks if t.TrajFeat[5] < 0.2
# or t.TrajFeat[3] < 120
# ]
#
# track2 = [t for t in tracks if t.static_index.size > 0
# and t.static_index[0, 0] <= 2
# and t.TrajFeat[5] < 0.5]
#
# track3 = [t for t in tracks if t.static_index.shape[0] >= 2
# and t.static_index[0, 0] <= 2
# and t.static_index[-1, 1] >= t.frnum-3]
#
# track12 = self.join_tracks(track1, track2)
#
# '''提取静止状态的 track'''
# static_tracks = self.join_tracks(track12, track3)
# self.Static.extend(static_tracks)
#
# =============================================================================
def is_OutTrack(self):
if self.posState <= 1:
isout = True
else:
isout = False
return isout
def compute_distance(self):
pass
def move_start_fid(self):
pass
def move_end_fid(self):
pass

View File

@ -15,17 +15,9 @@ class frontTrack(Track):
def __init__(self, boxes, features, imgshape=(1024, 1280)):
super().__init__(boxes, features, imgshape)
'''5个关键点中心点、左上点、右上点、左下点、右下点 )轨迹特征'''
# self.compute_cornpts_feats()
self.CART_HIGH_THRESH1 = imgshape[1]/2.98
# if self.tid==10:
# print(f"ID: {self.tid}")
'''y1、y2静止状态区间值是 boxes 中对 axis=0 的索引,不是帧索引'''
det_y1 = np.diff(boxes[:, 1], axis=0)
det_y2 = np.diff(boxes[:, 3], axis=0)
@ -78,69 +70,6 @@ class frontTrack(Track):
condt = all(self.boxes[:, 3] > self.imgshape[1]-20)
return condt
# def is_OutTrack(self):
# isout = False
# if self.posState <= 1:
# isout = True
# return isout
# =============================================================================
# def compute_static_fids(self, det_y, STATIC_THRESH = 8):
# '''
# 前摄时y一般选择为 box 的 y1 坐标,且需限定商品在购物车内。
# inputs
# y1D array
# parameters
# STATIC_THRESH轨迹处于静止状态的阈值。
# outputs
# 输出为差分值小于 STATIC_THRESH 的y中元素的start, end索引
# ranges = [(x1, y1),
# (x1, y1),
# ...]
# '''
# # print(f"The ID is: {self.tid}")
#
# # det_y = np.diff(y, axis=0)
# ranges, rangex = [], []
#
# static_indices = np.where(np.abs(det_y) < STATIC_THRESH)[0]
#
# if len(static_indices) == 0:
# rangex.append((0, len(det_y)))
# return ranges, rangex
#
# start_index = static_indices[0]
#
# for i in range(1, len(static_indices)):
# if static_indices[i] != static_indices[i-1] + 1:
# ranges.append((start_index, static_indices[i-1] + 1))
# start_index = static_indices[i]
# ranges.append((start_index, static_indices[-1] + 1))
#
# if len(ranges) == 0:
# rangex.append((0, len(det_y)))
# return ranges, rangex
#
# idx1, idx2 = ranges[0][0], ranges[-1][1]
#
# if idx1 != 0:
# rangex.append((0, idx1))
#
# # 轨迹的最后阶段是运动状态
# for k in range(1, len(ranges)):
# index1 = ranges[k-1][1]
# index2 = ranges[k][0]
# rangex.append((index1, index2))
#
# if idx2 != len(det_y):
# rangex.append((idx2, len(det_y)))
#
# return ranges, rangex
#
# =============================================================================
def is_static(self):
@ -202,14 +131,6 @@ class frontTrack(Track):
return condt
def is_upward(self):
'''判断商品是否取出,'''
print(f"The ID is: {self.tid}")