dotrack haved modified!

This commit is contained in:
王庆刚
2024-05-29 20:31:28 +08:00
parent dff029de20
commit d1ea304491
19 changed files with 379 additions and 149 deletions

Binary file not shown.

View File

@ -177,7 +177,7 @@ def run(
save_dir = Path(project) / Path(source).stem
if save_dir.exists():
print(Path(source).stem)
# return
return
save_dir = increment_path(Path(project) / name, exist_ok=exist_ok) # increment run
(save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True) # make dir
@ -517,9 +517,10 @@ def main_loop(opt):
optdict = vars(opt)
# p = r"D:\datasets\ym\永辉测试数据_比对"
# p = r"D:\datasets\ym\广告板遮挡测试\8"
p = r"D:\datasets\ym\videos\标记视频"
p = r"D:\datasets\ym\广告板遮挡测试\8"
# p = r"D:\datasets\ym\videos\标记视频"
# p = r"D:\datasets\ym\实验室测试"
# p = r"D:\datasets\ym\永辉双摄视频\新建文件夹"
k = 0
if os.path.isdir(p):
@ -531,7 +532,7 @@ def main_loop(opt):
# r"D:\datasets\ym\广告板遮挡测试\8\2500441577966_20240508-175946_front_addGood_70f75407b7ae_155_17788571404.mp4"
# ]
files = [r"D:\datasets\ym\videos\标记视频\test_20240402-173935_6920152400975_back_174037372.mp4"]
# files = [r"D:\datasets\ym\videos\标记视频\test_20240402-173935_6920152400975_back_174037372.mp4"]
for file in files:
optdict["source"] = file
run(**optdict)

View File

@ -8,7 +8,7 @@ import numpy as np
import cv2
from pathlib import Path
from scipy.spatial.distance import cdist
from utils.mergetrack import track_equal_track
from utils.mergetrack import track_equal_track, readDict
curpath = Path(__file__).resolve().parents[0]
curpath = Path(curpath)
@ -79,16 +79,18 @@ class ShoppingCart:
class Track:
'''抽象基类,不能实例化对象'''
def __init__(self, boxes, imgshape=(1024, 1280)):
def __init__(self, boxes, features, imgshape=(1024, 1280)):
'''
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"
# 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"
self.boxes = boxes
self.features = features
self.tid = int(boxes[0, 4])
self.cls = int(boxes[0, 6])
self.frnum = boxes.shape[0]
@ -100,6 +102,9 @@ class Track:
self.start_fid = int(np.min(boxes[:, 7]))
self.end_fid = int(np.max(boxes[:, 7]))
self.Hands = []
self.HandsIou = []
'''5个关键点中心点、左上点、右上点、左下点、右下点 )坐标'''
@ -212,7 +217,7 @@ class Track:
self.trajmin = trajmin
self.trajmax = trajmax
self.feature = [trajlen_min, trajlen_max,
self.TrajFeat = [trajlen_min, trajlen_max,
trajdist_min, trajdist_max,
trajlen_rate, trajdist_rate]
@ -268,6 +273,53 @@ class Track:
return ranges, rangex
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 extract_hand_features(self):
assert self.cls == 0, "The class of traj must be HAND!"
@ -296,10 +348,12 @@ class doTracks:
def __init__(self, bboxes, TracksDict):
'''fundamental property'''
self.bboxes = bboxes
self.TracksDict = TracksDict
# self.TracksDict = TracksDict
self.frameID = np.unique(bboxes[:, 7].astype(int))
self.trackID = np.unique(bboxes[:, 4].astype(int))
self.lboxes = self.array2list()
self.lfeats = self.getfeats(TracksDict)
'''对 self.tracks 中的元素进行分类,将 track 归入相应列表中'''
self.Hands = []
@ -332,6 +386,19 @@ class doTracks:
return lboxes
def getfeats(self, TracksDict):
lboxes = self.lboxes
lfeats = []
for boxes in lboxes:
afeat = readDict(boxes, TracksDict)
lfeats.append(afeat)
return lfeats
'''
def classify(self):
@ -364,11 +431,6 @@ class doTracks:
'''
def similarity(self):
nt = len(self.tracks)
similar_dict = {}
@ -428,7 +490,7 @@ class doTracks:
blist = [b for b in alist]
alist = []
for btrack in blist:
if track_equal_track(atrack, btrack, self.TracksDict):
if track_equal_track(atrack, btrack):
cur_list.append(btrack)
else:
alist.append(btrack)

View File

@ -16,7 +16,7 @@ class doBackTracks(doTracks):
super().__init__(bboxes, TracksDict)
self.tracks = [backTrack(b) for b in self.lboxes]
self.tracks = [backTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)]
# self.similar_dict = self.similarity()
@ -68,6 +68,9 @@ class doBackTracks(doTracks):
tracks = self.sub_tracks(tracks, kid_tracks)
out_trcak = [t for t in tracks if t.isWholeOutCart]
tracks = self.sub_tracks(tracks, out_trcak)
static_tracks = [t for t in tracks if t.frnum>1 and t.is_static()]
self.Static.extend(static_tracks)
@ -75,10 +78,9 @@ class doBackTracks(doTracks):
tracks = self.sub_tracks(tracks, static_tracks)
'''购物框边界外具有运动状态的干扰目标'''
out_trcak = [t for t in tracks if t.is_OutTrack()]
tracks = self.sub_tracks(tracks, out_trcak)
# '''购物框边界外具有运动状态的干扰目标'''
# out_trcak = [t for t in tracks if t.is_OutTrack()]
# tracks = self.sub_tracks(tracks, out_trcak)
'''轨迹循环归并'''
@ -86,9 +88,74 @@ class doBackTracks(doTracks):
merged_tracks = self.merge_tracks_loop(tracks)
tracks = [t for t in merged_tracks if t.frnum > 1]
self.merged_tracks = merged_tracks
static_tracks = [t for t in tracks if t.frnum>1 and t.is_static()]
self.Static.extend(static_tracks)
tracks = self.sub_tracks(tracks, static_tracks)
for gtrack in tracks:
# print(f"Goods ID:{gtrack.tid}")
for htrack in hand_tracks:
hand_ious = self.associate_with_hand(htrack, gtrack)
if len(hand_ious):
gtrack.Hands.append(htrack)
gtrack.HandsIou.append(hand_ious)
self.Residual = tracks
def associate_with_hand(self, htrack, gtrack):
'''
迁移至基类:
手部 Track、商品 Track 建立关联的依据:
a. 运动帧的帧索引有交集
b. 帧索引交集部分iou均大于0
'''
assert htrack.cls==0 and gtrack.cls!=0 and gtrack.cls!=9, 'Track cls is Error!'
hand_ious = []
hboxes = np.empty(shape=(0, 9), dtype = np.float)
gboxes = np.empty(shape=(0, 9), dtype = np.float)
# start, end 为索引值,需要 start:(end+1)
for start, end in htrack.moving_index:
hboxes = np.concatenate((hboxes, htrack.boxes[start:end+1, :]), axis=0)
for start, end in gtrack.moving_index:
gboxes = np.concatenate((gboxes, gtrack.boxes[start:end+1, :]), axis=0)
hfids, gfids = hboxes[:, 7], gboxes[:, 7]
fids = set(hfids).intersection(set(gfids))
if len(fids)==0:
return hand_ious
# print(f"Goods ID: {gtrack.tid}, Hand ID: {htrack.tid}")
for f in fids:
h = np.where(hfids==f)[0][0]
g = np.where(gfids==f)[0][0]
x11, y11, x12, y12 = hboxes[h, 0:4]
x21, y21, x22, y22 = gboxes[g, 0:4]
x1, y1 = max((x11, x21)), max((y11, y21))
x2, y2 = min((x12, x22)), min((y12, y22))
union = (x2 - x1).clip(0) * (y2 - y1).clip(0)
area1 = (x12 - x11) * (y12 - y11)
area2 = (x22 - x21) * (y22 - y21)
iou = union / (area1 + area2 - union + 1e-6)
if iou>0:
hand_ious.append((f, iou))
return hand_ious
def merge_tracks(self, Residual):
"""
@ -100,19 +167,27 @@ class doBackTracks(doTracks):
for tracklist in mergedTracks:
if len(tracklist) > 1:
boxes = np.empty((0, 9), dtype=np.float32)
feats = np.empty((0, 256), dtype=np.float32)
for i, track in enumerate(tracklist):
if i==0: ntid, ncls=track.boxes[0, 4], track.boxes[0, 6]
iboxes = track.boxes.copy()
ifeats = track.features.copy()
# iboxes[:, 4], iboxes[:, 6] = ntid, ncls
iboxes[:, 4], iboxes[:, 6] = ntid, ncls
boxes = np.concatenate((boxes, iboxes), axis=0)
feats = np.concatenate((feats, ifeats), axis=0)
oldtracks.append(track)
fid_indices = np.argsort(boxes[:, 7])
boxes_fid = boxes[fid_indices]
newtracks.append(backTrack(boxes_fid))
boxes_fid = boxes[fid_indices]
feats_fid = feats[fid_indices]
newtracks.append(backTrack(boxes_fid, feats_fid))
elif len(tracklist) == 1:
oldtracks.append(tracklist[0])
newtracks.append(tracklist[0])
@ -138,19 +213,6 @@ class doBackTracks(doTracks):
return kidstate
def is_associate_with_hand(self):
"""
分析商品和手之间的关联性
"""
pass
def isuptrack(self, track):
Flag = False

View File

@ -13,7 +13,9 @@ class doFrontTracks(doTracks):
def __init__(self, bboxes, TracksDict):
super().__init__(bboxes, TracksDict)
self.tracks = [frontTrack(b) for b in self.lboxes]
# self.tracks = [frontTrack(b) for b in self.lboxes]
self.tracks = [frontTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)]
def classify(self):
'''功能:对 tracks 中元素分类 '''
@ -33,6 +35,8 @@ class doFrontTracks(doTracks):
kid_tracks = [t for t in tracks if t.cls==9]
tracks = self.sub_tracks(tracks, kid_tracks)
out_trcak = [t for t in tracks if t.isWholeOutCart]
tracks = self.sub_tracks(tracks, out_trcak)
'''静态 tracks'''
static_tracks = [t for t in tracks if t.frnum>1 and t.is_static()]
@ -49,8 +53,11 @@ class doFrontTracks(doTracks):
for gtrack in tracks:
# print(f"Goods ID:{gtrack.tid}")
for htrack in hand_tracks:
if self.is_associate_with_hand(htrack, gtrack):
gtrack.hands.append(htrack)
hand_ious = self.associate_with_hand(htrack, gtrack)
if len(hand_ious):
gtrack.Hands.append(htrack)
gtrack.HandsIou.append(hand_ious)
freemoved_tracks = [t for t in tracks if t.is_free_move()]
@ -59,14 +66,17 @@ class doFrontTracks(doTracks):
self.Residual = tracks
def is_associate_with_hand(self, htrack, gtrack):
'''手部 Track、商品 Track 建立关联的依据:
def associate_with_hand(self, htrack, gtrack):
'''
迁移至基类:
手部 Track、商品 Track 建立关联的依据:
a. 运动帧的帧索引有交集
b. 帧索引交集部分iou均大于0
'''
assert htrack.cls==0 and gtrack.cls!=0 and gtrack.cls!=9, 'Track cls is Error!'
hand_ious = []
hboxes = np.empty(shape=(0, 9), dtype = np.float)
gboxes = np.empty(shape=(0, 9), dtype = np.float)
@ -80,7 +90,7 @@ class doFrontTracks(doTracks):
fids = set(hfids).intersection(set(gfids))
if len(fids)==0:
return False
return hand_ious
# print(f"Goods ID: {gtrack.tid}, Hand ID: {htrack.tid}")
@ -102,9 +112,9 @@ class doFrontTracks(doTracks):
iou = union / (area1 + area2 - union + 1e-6)
if iou>0:
ious.append(iou)
hand_ious.append((f, iou))
return len(ious)
return hand_ious
@ -137,17 +147,24 @@ class doFrontTracks(doTracks):
for tracklist in mergedTracks:
if len(tracklist) > 1:
boxes = np.empty((0, 9), dtype=np.float32)
feats = np.empty((0, 256), dtype=np.float32)
for i, track in enumerate(tracklist):
if i==0: ntid, ncls=track.boxes[0, 4], track.boxes[0, 6]
iboxes = track.boxes.copy()
iboxes[:, 4], iboxes[:, 6] = ntid, ncls
ifeats = track.features.copy()
# iboxes[:, 4], iboxes[:, 6] = ntid, ncls
boxes = np.concatenate((boxes, iboxes), axis=0)
feats = np.concatenate((feats, ifeats), axis=0)
oldtracks.append(track)
fid_indices = np.argsort(boxes[:, 7])
boxes_fid = boxes[fid_indices]
feats_fid = feats[fid_indices]
newtracks.append(frontTrack(boxes_fid))
newtracks.append(frontTrack(boxes_fid, feats_fid))
elif len(tracklist) == 1:
oldtracks.append(tracklist[0])
newtracks.append(tracklist[0])

View File

@ -14,29 +14,32 @@ from .dotracks import MoveState, Track
class backTrack(Track):
# boxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# 0, 1, 2, 3, 4, 5, 6, 7, 8
def __init__(self, boxes, imgshape=(1024, 1280)):
def __init__(self, boxes, features, imgshape=(1024, 1280)):
super().__init__(boxes, imgshape)
super().__init__(boxes, features, imgshape)
'''该函数依赖项: self.cornpoints'''
self.isCornpoint = self.isimgborder()
'''该函数依赖项: self.cornpoints
MarginState: list, seven elements, 表示轨迹中boxes出现在图像的
[左上,右上,左中,右中,左下,右下底部]
'''
self.isCornpoint, self.MarginState = self.isimgborder()
'''该函数依赖项: self.isCornpoint不能在父类中初始化'''
self.trajfeature()
'''静止点帧索引'''
self.static_index = self.compute_static_fids()
# self.static_index = self.compute_static_fids()
'''运动点帧索引(运动帧两端的静止帧索引)'''
self.moving_index = self.compute_dynamic_fids()
# self.moving_index = self.compute_dynamic_fids()
# self.static_index, self.moving_index = self.compute_static_dynamic_fids()
self.static_index, self.moving_index = self.compute_static_dynamic_fids()
'''该函数依赖项: self.cornpoints定义 4 个商品位置变量:
self.Cent_isIncart, self.LB_isIncart, self.RB_isIncart
self.posState = self.Cent_isIncart+self.LB_isIncart+self.RB_isIncart'''
self.PositionState()
self.PositionState(camerType="back")
'''self.feature_ious = (incart_iou, outcart_iou, cartboarder_iou, maxbox_iou, minbox_iou)
self.incartrates = incartrates'''
@ -51,46 +54,78 @@ class backTrack(Track):
x1, y1 = self.cornpoints[:,2], self.cornpoints[:,3],
x2, y2 = self.cornpoints[:,8], self.cornpoints[:,9]
cont1 = sum(abs(x1)<BoundPixel) / self.frnum > BoundThresh
cont2 = sum(abs(y1)<BoundPixel) / self.frnum > BoundThresh
cont3 = sum(abs(x2-self.imgshape[0])<BoundPixel) / self.frnum > BoundThresh
cont4 = sum(abs(y2-self.imgshape[1])<BoundPixel) / self.frnum > BoundThresh
condt1 = sum(abs(x1)<BoundPixel) / self.frnum > BoundThresh
condt2 = sum(abs(y1)<BoundPixel) / self.frnum > BoundThresh
condt3 = sum(abs(x2-self.imgshape[0])<BoundPixel) / self.frnum > BoundThresh
condt4 = sum(abs(y2-self.imgshape[1])<BoundPixel) / self.frnum > BoundThresh
cont = cont1 or cont2 or cont3 or cont4
condt = condt1 or condt2 or condt3 or condt4
isCornpoint = False
if cont:
if condt:
isCornpoint = True
return isCornpoint
condtA = condt1 and condt2
condtB = condt3 and condt2
condtC = condt1 and not condt2 and not condt4
condtD = condt3 and not condt2 and not condt4
condtE = condt1 and condt4
condtF = condt3 and condt4
condtG = condt4 and not condt1 and not condt3
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)
else:
incart = cv2.imread("./shopcart/cart_tempt/incart_ftmp.png", cv2.IMREAD_GRAYSCALE)
# =============================================================================
# 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
# =============================================================================
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)])
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
@ -251,8 +286,24 @@ class backTrack(Track):
def compute_static_dynamic_fids(self):
idx2 = self.trajlens.index(min(self.trajlens))
trajmin = self.trajectory[idx2]
if self.MarginState[0] or self.MarginState[2]:
idx1 = 4
elif self.MarginState[1] or self.MarginState[3]:
idx1 = 3
elif self.MarginState[4]:
idx1 = 2
elif self.MarginState[5]:
idx1 = 1
elif self.MarginState[6]:
if self.trajlens[1] < self.trajlens[2]:
idx1 = 1
else:
idx1 = 2
else:
idx1 = self.trajlens.index(min(self.trajlens))
# idx1 = self.trajlens.index(min(self.trajlens))
trajmin = self.trajectory[idx1]
static, dynamic = self.pt_state_fids(trajmin)
@ -280,46 +331,59 @@ class backTrack(Track):
# return static_dynamic_fids
# =============================================================================
def is_static(self):
'''静态情况 1: 目标关键点最小相对运动轨迹 < 0.2, 指标值偏大
feature = [trajlen_min, trajlen_max,
TrajFeat = [trajlen_min, trajlen_max,
trajdist_min, trajdist_max,
trajlen_rate, trajdist_rate]
'''
# print(f"TrackID: {self.tid}")
boxes = self.boxes
condt1 = self.feature[5] < 0.2 or self.feature[3] < 120
'''静态情况 1: '''
condt1 = self.TrajFeat[5] < 0.2 or self.TrajFeat[3] < 120
'''静态情况 2: 目标初始状态为静止,适当放宽关键点最小相对运动轨迹 < 0.5'''
condt2 = self.static_index.size > 0 \
and self.static_index[0, 0] <= 2 \
and self.feature[5] < 0.5
and self.static_index[0, 1] >= 5 \
and self.TrajFeat[5] < 0.5 \
and self.TrajFeat[1] < 240 \
and self.isWholeInCart
# and self.posState >= 2
# and self.TrajFeat[0] < 240 \
'''静态情况 3: 目标初始状态和最终状态均为静止'''
condt3 = self.static_index.shape[0] >= 2 \
and self.static_index[0, 0] <= 2 \
and self.static_index[0, 1] >= 5 \
and self.static_index[-1, 1] >= self.frnum-3 \
and self.TrajFeat[1] < 240 \
and self.isWholeInCart
# and self.posState >= 2
# and self.TrajFeat[0] < 240 \
condt = condt1 or condt2 or condt3
condt4 = self.static_index.shape[0] >= 2 \
and self.static_index[0, 0] <= 2 \
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.feature[5] < 0.2
# or t.feature[3] < 120
# 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.feature[5] < 0.5]
# 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

View File

@ -12,11 +12,9 @@ from .dotracks import MoveState, Track
class frontTrack(Track):
# boxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# 0, 1, 2, 3, 4, 5, 6, 7, 8
def __init__(self, boxes, imgshape=(1024, 1280)):
super().__init__(boxes, imgshape)
self.hands = []
def __init__(self, boxes, features, imgshape=(1024, 1280)):
super().__init__(boxes, features, imgshape)
'''5个关键点中心点、左上点、右上点、左下点、右下点 )轨迹特征'''
# self.compute_cornpts_feats()
@ -40,6 +38,7 @@ class frontTrack(Track):
'''该函数依赖项: self.isCornpoint不能在父类中初始化'''
self.trajfeature()
self.PositionState(camerType="front")
'''手部状态分析'''
self.HAND_STATIC_THRESH = 100
@ -245,7 +244,7 @@ class frontTrack(Track):
'''情况2中心点向上 '''
## 商品中心点向上移动但没有关联的Hand轨迹也不是左右边界点
condt_b = condt0 and len(self.hands)==0 and y0[-1] < y0[0] and (not self.is_edge_cornpoint())
condt_b = condt0 and len(self.Hands)==0 and y0[-1] < y0[0] and (not self.is_edge_cornpoint())
'''情况3: 商品在购物车内,但运动方向无序'''

View File

@ -21,7 +21,7 @@ from pathlib import Path
# ================= using for import ultralytics
import sys
sys.path.append(r"D:\yolov5track")
sys.path.append(r"D:\DetectTracking")
from utils.gen import Profile
from dotrack.dotracks_back import doBackTracks
@ -68,7 +68,7 @@ def detect_start_end(bboxes, features_dict, filename):
return start, end
def save_subimgs(vts, file):
def save_subimgs(vts, file, TracksDict):
imgdir = Path(f'./result/imgs/{file}')
if not imgdir.exists():
imgdir.mkdir(parents=True, exist_ok=True)
@ -78,19 +78,21 @@ def save_subimgs(vts, file):
for ii in range(len(boxes)):
tid, fid, bid = int(boxes[ii, 4]), int(boxes[ii, 7]), int(boxes[ii, 8])
img = vts.TracksDict[f"frame_{fid}"]["imgs"][bid]
img = TracksDict[f"frame_{fid}"]["imgs"][bid]
# feat = TracksDict[f"frame_{fid}"]["feats"][bid]
# box = TracksDict[f"frame_{fid}"]["boxes"][bid]
cv2.imwrite(str(imgdir) + f"/{tid}_{fid}_{bid}.png", img)
def have_tracked():
trackdict = r'./data/trackdicts'
trackdict = r'./data/trackdicts_1'
alltracks = []
k = 0
gt = Profile()
for filename in os.listdir(trackdict):
filename = 'test_20240402-173935_6920152400975_back_174037372.pkl'
# filename = 'test_20240402-173935_6920152400975_back_174037372.pkl'
filename = '加购_91.pkl'
file, ext = os.path.splitext(filename)
filepath = os.path.join(trackdict, filename)
TracksDict = np.load(filepath, allow_pickle=True)
@ -101,7 +103,7 @@ def have_tracked():
vts = doFrontTracks(bboxes, TracksDict)
vts.classify()
save_subimgs(vts, file)
save_subimgs(vts, file, TracksDict)
plt = plot_frameID_y2(vts)
@ -114,7 +116,7 @@ def have_tracked():
vts.classify()
alltracks.append(vts)
save_subimgs(vts, file)
save_subimgs(vts, file, TracksDict)
edgeline = cv2.imread("./shopcart/cart_tempt/edgeline.png")
draw_all_trajectories(vts, edgeline, save_dir, filename)
print(file+f" need time: {gt.dt:.2f}s")

View File

@ -161,7 +161,7 @@ class BOTSORT(BYTETracker):
'''1. reid 相似度阈值,低于该值的两 boxes 图像不可能是同一对象,需要确定一个合理的可信阈值
2. iou 的约束为若约束,故 iou_dists 应设置为较大的值
'''
emb_dists_mask = (emb_dists > 0.85)
emb_dists_mask = (emb_dists > 0.65)
iou_dists[emb_dists_mask] = 1
emb_dists[iou_dists_mask] = 1

View File

@ -87,20 +87,29 @@ def draw_all_trajectories(vts, edgeline, save_dir, filename):
# edgeline2 = edgeline1.copy()
# edgeline = np.concatenate((edgeline1, edgeline2), exis = 1)
# =============================================================================
# '''1. tracks 5点轨迹'''
# trackpth = save_dir.parent /Path("trajectory")/ Path(f"{file}")
# if not trackpth.exists():
# trackpth.mkdir(parents=True, exist_ok=True)
# for track in vts.tracks:
# # if track.cls != 0:
# img = edgeline.copy()
# img = draw5points(track, img)
#
# pth = trackpth.joinpath(f"{track.tid}.png")
# cv2.imwrite(str(pth), img)
#
# =============================================================================
'''1. tracks 5点轨迹'''
trackpth = save_dir.parent /Path("trajectory")/ Path(f"{file}")
if not trackpth.exists():
trackpth.mkdir(parents=True, exist_ok=True)
for track in vts.tracks:
# if track.cls != 0:
img = edgeline.copy()
img = draw5points(track, img)
pth = trackpth.joinpath(f"{track.tid}.png")
cv2.imwrite(str(pth), img)
for track in vts.merged_tracks:
# if track.cls != 0:
img = edgeline.copy()
img = draw5points(track, img)
pth = trackpth.joinpath(f"{track.tid}_.png")
cv2.imwrite(str(pth), img)
'''2. all tracks 中心轨迹'''
img1, img2 = edgeline.copy(), edgeline.copy()
@ -139,7 +148,7 @@ def draw_all_trajectories(vts, edgeline, save_dir, filename):
def drawFeatures(allvts, save_dir):
# [trajlen_min, trajdist_max, trajlen_rate, trajist_rate]]
feats = [track.feature for vts in allvts for track in vts.tracks]
feats = [track.TrajFeat for vts in allvts for track in vts.tracks]
feats = np.array(feats)
fig, ax = plt.subplots()
ax.scatter(feats[:,3], feats[:, 1], s=10)
@ -269,7 +278,7 @@ def draw5points(track, img):
trajstd = 0
trajlen_min, trajlen_max, trajdist_min, trajdist_max, trajlen_rate, trajdist_rate = track.feature
trajlen_min, trajlen_max, trajdist_min, trajdist_max, trajlen_rate, trajdist_rate = track.TrajFeat
for i in range(boxes.shape[0]):
cv2.circle(img, (int(cornpoints[i, 0]), int(cornpoints[i, 1])), 6, (255, 255, 255), 2)

View File

@ -31,12 +31,19 @@ def readDict(boxes, TracksDict):
def track_equal_track(atrack, btrack, TracksDict):
def track_equal_track(atrack, btrack):
# boxes: [x, y, w, h, track_id, score, cls, frame_index, box_index]
# 0 1 2 3 4 5 6 7 8
aboxes = atrack.boxes
bboxes = btrack.boxes
afeat = atrack.features
bfeat = btrack.features
# afeat = readDict(aboxes, TracksDict)
# bfeat = readDict(bboxes, TracksDict)
''' 1. 判断轨迹在时序上是否有交集 '''
afids = aboxes[:, 7].astype(np.int_)
bfids = bboxes[:, 7].astype(np.int_)
@ -50,8 +57,6 @@ def track_equal_track(atrack, btrack, TracksDict):
return False
''' 2. 轨迹特征相似度判断'''
afeat = readDict(aboxes, TracksDict)
bfeat = readDict(bboxes, TracksDict)
feat = np.concatenate((afeat, bfeat), axis=0)
emb_simil = 1-np.maximum(0.0, cdist(feat, feat, 'cosine'))
@ -82,9 +87,15 @@ def track_equal_track(atrack, btrack, TracksDict):
idx_pair.append((a_idx, b_idx))
ious = []
embs = []
for a, b in idx_pair:
abox, bbox = aboxes[a, :], bboxes[b, :]
af, bf = afeat[a, :], bfeat[b, :]
emb_ab = 1-cdist(af[None, :], bf[None, :], 'cosine')
xa1, ya1 = abox[0] - abox[2]/2, abox[1] - abox[3]/2
xa2, ya2 = abox[0] + abox[2]/2, abox[1] + abox[3]/2
@ -101,13 +112,16 @@ def track_equal_track(atrack, btrack, TracksDict):
union = box1_area + box2_area - inter + 1e-6
ious.append(inter/union)
embs.append(emb_ab[0, 0])
cont = False if len(interfid) else True
# cont2 = emb_[0, 0]>0.75
# cont3 = all(iou>0.5 for iou in ious)
cont = False if len(interfid) else True # fid 无交集
cont1 = all(emb > 0.5 for emb in embs)
cont2 = all(iou > 0.5 for iou in ious)
# cont = cont and cont2 and cont3
cont = cont and cont1 and cont2
return cont