# -*- coding: utf-8 -*- """ Created on Mon Mar 4 18:36:31 2024 @author: ym """ import numpy as np import cv2 from tracking.utils.mergetrack import track_equal_track from scipy.spatial.distance import cdist from pathlib import Path curpath = Path(__file__).resolve().parents[0] curpath = Path(curpath) parpath = curpath.parent from .dotracks import doTracks, ShoppingCart from .track_back import backTrack class doBackTracks(doTracks): def __init__(self, bboxes, TracksDict): super().__init__(bboxes, TracksDict) self.tracks = [backTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)] # self.similar_dict = self.similarity() # self.shopcart = ShoppingCart(bboxes) self.incart = self.getincart() def getincart(self): img1 = cv2.imread(str(parpath/'shopcart/cart_tempt/incart.png'), cv2.IMREAD_GRAYSCALE) img2 = cv2.imread(str(parpath/'shopcart/cart_tempt/cartedge.png'), cv2.IMREAD_GRAYSCALE) ret, binary1 = cv2.threshold(img1, 250, 255, cv2.THRESH_BINARY) ret, binary2 = cv2.threshold(img2, 250, 255, cv2.THRESH_BINARY) binary = cv2.bitwise_or(binary1, binary2) return binary def classify(self): '''功能:对 tracks 中元素分类 ''' 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) 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) '''剔除静止目标后的 tracks''' tracks = self.sub_tracks(tracks, static_tracks) tracks_free = [t for t in tracks if t.frnum>1 and t.is_freemove()] self.FreeMove.extend(tracks_free) tracks = self.sub_tracks(tracks, tracks_free) # '''购物框边界外具有运动状态的干扰目标''' # out_trcak = [t for t in tracks if t.is_OutTrack()] # tracks = self.sub_tracks(tracks, out_trcak) '''轨迹循环归并''' # merged_tracks = self.merge_tracks(tracks) merged_tracks = self.merge_tracks_loop(tracks) [self.associate_with_hand(htrack, gtrack) for htrack in hand_tracks for gtrack in 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: # 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) # htrack.Goods.append((gtrack, hand_ious)) # for htrack in hand_tracks: # self.merge_based_hands(htrack) self.Residual = tracks # def merge_based_hands(self, htrack): # gtracks = htrack.Goods # if len(gtracks) >= 2: # atrack, afious = gtracks[0] # btrack, bfious = gtracks[1] 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 = sorted(set(hfids).intersection(set(gfids))) if len(fids)==0: return None # print(f"Goods ID: {gtrack.tid}, Hand ID: {htrack.tid}") for f in fids: h = np.where(hboxes[:,7] == f)[0][0] g = np.where(gboxes[:,7] == 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.01: gtrack.Hands.append((htrack.tid, f, iou)) return gtrack.Hands def merge_tracks(self, Residual): """ 对不同id,但可能是同一商品的目标进行归并 和 dotrack_front.py中函数相同,可以合并,可以合并至基类 """ mergedTracks = self.base_merge_tracks(Residual) oldtracks, newtracks = [], [] 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 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(backTrack(boxes_fid, feats_fid)) elif len(tracklist) == 1: oldtracks.append(tracklist[0]) newtracks.append(tracklist[0]) redu = self.sub_tracks(Residual, oldtracks) merged = self.join_tracks(redu, newtracks) return merged def kid_state(self, track): left_dist = track.cornpoints[:, 2] right_dist = 1024 - track.cornpoints[:, 4] if np.sum(left_dist<30)/track.frnum>0.8 and np.sum(right_dist>512)/track.frnum>0.7: kidstate = "left" elif np.sum(left_dist>512)/track.frnum>0.7 and np.sum(right_dist<30)/track.frnum>0.8: kidstate = "right" else: kidstate = "incart" return kidstate def isuptrack(self, track): Flag = False return Flag def isdowntrack(self, track): Flag = False return Flag def isfreetrack(self, track): Flag = False return Flag