dotrack haved modified!
This commit is contained in:
BIN
runs/detect/加购_88/detect - 快捷方式.lnk
Normal file
BIN
runs/detect/加购_88/detect - 快捷方式.lnk
Normal file
Binary file not shown.
@ -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)
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
|
@ -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: 商品在购物车内,但运动方向无序'''
|
||||
|
@ -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")
|
||||
|
Binary file not shown.
@ -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
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user