diff --git a/tracking/__pycache__/contrast_analysis.cpython-39.pyc b/tracking/__pycache__/contrast_analysis.cpython-39.pyc index 8e5b16f..b5f51c6 100644 Binary files a/tracking/__pycache__/contrast_analysis.cpython-39.pyc and b/tracking/__pycache__/contrast_analysis.cpython-39.pyc differ diff --git a/tracking/contrast_analysis.py b/tracking/contrast_analysis.py index 058c6fd..c8e620c 100644 --- a/tracking/contrast_analysis.py +++ b/tracking/contrast_analysis.py @@ -397,7 +397,7 @@ def contrast_loop(fpath): plt1 = show_recall_prec(recall, prec, ths) # plt1.show() - plt.xlabel(f'threshold, Num: {len(blist)}') + plt1.xlabel(f'threshold, Num: {len(blist)}') plt1.savefig(os.path.join(savepath, file+'_pr.png')) # plt1.close() @@ -408,13 +408,12 @@ def contrast_loop(fpath): -def main1(): - fpath = r'D:\contrast\dataset\1_to_n\0719' - fpath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\good' +def main(): + fpath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\other' contrast_loop(fpath) -def main(): +def main1(): del_barcode_file = 'D:/contrast/dataset/compairsonResult/deletedBarcode_20240709_pm.txt' basepath = r'D:\contrast\dataset\1_to_n\709' savepath = r'D:\contrast\dataset\result' @@ -431,9 +430,9 @@ def resolve_vidoes(): video2imgs(videopath, savepath) if __name__ == '__main__': - # main() - main1() + main() + # main1() # resolve_vidoes() diff --git a/tracking/dotrack/__pycache__/dotracks.cpython-39.pyc b/tracking/dotrack/__pycache__/dotracks.cpython-39.pyc index 671fcc3..d34df3e 100644 Binary files a/tracking/dotrack/__pycache__/dotracks.cpython-39.pyc and b/tracking/dotrack/__pycache__/dotracks.cpython-39.pyc differ diff --git a/tracking/dotrack/__pycache__/dotracks_back.cpython-39.pyc b/tracking/dotrack/__pycache__/dotracks_back.cpython-39.pyc index 2c89354..d60ba11 100644 Binary files a/tracking/dotrack/__pycache__/dotracks_back.cpython-39.pyc and b/tracking/dotrack/__pycache__/dotracks_back.cpython-39.pyc differ diff --git a/tracking/dotrack/__pycache__/dotracks_front.cpython-39.pyc b/tracking/dotrack/__pycache__/dotracks_front.cpython-39.pyc index cc3a8f9..ddd487d 100644 Binary files a/tracking/dotrack/__pycache__/dotracks_front.cpython-39.pyc and b/tracking/dotrack/__pycache__/dotracks_front.cpython-39.pyc differ diff --git a/tracking/dotrack/dotracks.py b/tracking/dotrack/dotracks.py index 72305b8..df10ceb 100644 --- a/tracking/dotrack/dotracks.py +++ b/tracking/dotrack/dotracks.py @@ -79,7 +79,7 @@ class ShoppingCart: class Track: '''抽象基类,不能实例化对象''' - def __init__(self, boxes, features, imgshape=(1024, 1280)): + def __init__(self, boxes, features=None, 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 diff --git a/tracking/dotrack/dotracks_back.py b/tracking/dotrack/dotracks_back.py index 459bdf9..bf17b07 100644 --- a/tracking/dotrack/dotracks_back.py +++ b/tracking/dotrack/dotracks_back.py @@ -55,10 +55,14 @@ class doBackTracks(doTracks): # tracks = self.sub_tracks(tracks, out_trcak) - [self.associate_with_hand(htrack, gtrack) for htrack in hand_tracks for gtrack in tracks] + '''轨迹循环归并''' # 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 diff --git a/tracking/dotrack/dotracks_front.py b/tracking/dotrack/dotracks_front.py index 6eedf3c..a4c7f54 100644 --- a/tracking/dotrack/dotracks_front.py +++ b/tracking/dotrack/dotracks_front.py @@ -45,10 +45,12 @@ class doFrontTracks(doTracks): '''剔除静止目标后的 tracks''' tracks = self.sub_tracks(tracks, static_tracks) - [self.associate_with_hand(htrack, gtrack) for htrack in hand_tracks for gtrack in tracks] + # [self.associate_with_hand(htrack, gtrack) for htrack in hand_tracks for gtrack in tracks] '''轨迹循环归并''' merged_tracks = self.merge_tracks_loop(tracks) + [self.associate_with_hand(htrack, gtrack) for htrack in hand_tracks for gtrack in merged_tracks] + tracks = [t for t in merged_tracks if t.frnum > 1] # for gtrack in tracks: diff --git a/tracking/dotrack/track_select.py b/tracking/dotrack/track_select.py new file mode 100644 index 0000000..d27fd1a --- /dev/null +++ b/tracking/dotrack/track_select.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jul 29 10:28:21 2024 + 未来需将这一部分和轨迹分析代码集成 + +@author: ym +""" +import numpy as np +import cv2 +from scipy.spatial.distance import cdist + +class TProp: + def __init__(self, boxes): + + self.boxes = boxes + + + + + +class TProp: + '''抽象基类,不能实例化对象''' + def __init__(self, boxes): + ''' + 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" + + self.boxes = boxes + + '''5个关键点(中心点、左上点、右上点、左下点、右下点 )坐标''' + self.compute_cornpoints() + + '''5个关键点轨迹特征,可以在子类中实现,降低顺序处理时的计算量 + (中心点、左上点、右上点、左下点、右下点 )轨迹特征''' + self.compute_cornpts_feats() + + self.distmax = max(self.trajdist) + + + def compute_cornpoints(self): + ''' + cornpoints 共10项,分别是个点的坐标值(x, y) + (center, top_left, top_right, bottom_left, bottom_right) + ''' + boxes = self.boxes + cornpoints = np.zeros((self.frnum, 10)) + cornpoints[:,0] = (boxes[:, 0] + boxes[:, 2]) / 2 + cornpoints[:,1] = (boxes[:, 1] + boxes[:, 3]) / 2 + cornpoints[:,2], cornpoints[:,3] = boxes[:, 0], boxes[:, 1] + cornpoints[:,4], cornpoints[:,5] = boxes[:, 2], boxes[:, 1] + cornpoints[:,6], cornpoints[:,7] = boxes[:, 0], boxes[:, 3] + cornpoints[:,8], cornpoints[:,9] = boxes[:, 2], boxes[:, 3] + + self.cornpoints = cornpoints + def compute_cornpts_feats(self): + ''' + ''' + trajectory = [] + trajlens = [] + trajdist = [] + trajrects = [] + for k in range(5): + # diff_xy2 = np.power(np.diff(self.cornpoints[:, 2*k:2*(k+1)], axis = 0), 2) + # trajlen = np.sum(np.sqrt(np.sum(diff_xy2, axis = 1))) + + X = self.cornpoints[:, 2*k:2*(k+1)] + + traj = np.linalg.norm(np.diff(X, axis=0), axis=1) + trajectory.append(traj) + + trajlen = np.sum(traj) + trajlens.append(trajlen) + + ptdist = np.max(cdist(X, X)) + trajdist.append(ptdist) + + '''最小外接矩形: + rect[0]: 中心(x, y) + rect[1]: (w, h) + rect[0]: 旋转角度 (-90°, 0] + ''' + rect = cv2.minAreaRect(X.astype(np.int64)) + trajrects.append(rect) + + self.trajectory = trajectory + self.trajlens = trajlens + self.trajdist = trajdist + self.trajrects = trajrects \ No newline at end of file diff --git a/tracking/feat_select.py b/tracking/feat_select.py new file mode 100644 index 0000000..8430c79 --- /dev/null +++ b/tracking/feat_select.py @@ -0,0 +1,418 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Jul 27 14:07:25 2024 + +@author: ym +""" +import os.path +import numpy as np +from scipy.spatial.distance import cdist +import matplotlib.pyplot as plt +import sys +sys.path.append(r"D:\DetectTracking") +from tracking.utils.read_data import extract_data, read_deletedBarcode_file, read_tracking_output +from tracking.dotrack.dotracks import Track + +from tracking.contrast_analysis import performance_evaluate, compute_recall_precision, show_recall_prec + +def compute_similar(feat1, feat2): + + if len(feat1)==0 or len(feat2)==0: + return 0 + + similar = 1 - np.maximum(0.0, cdist(feat1, feat2, metric = 'cosine')) + smean = np.mean(similar) + + return smean + + + + + + +def update_event(datapath): + '''一次购物事件,包含 8 个keys''' + event = {} + # event['front_tracking_boxes'] = [] + # event['front_tracking_feats'] = {} + # event['back_tracking_boxes'] = [] + # event['back_tracking_feats'] = {} + + event['back_sole_boxes'] = np.empty((0, 9), dtype=np.float64) + event['front_sole_boxes'] = np.empty((0, 9), dtype=np.float64) + + event['back_sole_feats'] = np.empty((0, 256), dtype=np.float64) + event['front_sole_feats'] = np.empty((0, 256), dtype=np.float64) + + event['feats_compose'] = np.empty((0, 256), dtype=np.float64) + event['feats_select'] = np.empty((0, 256), dtype=np.float64) + + '''读取当前事件的 data 文件''' + for filename in os.listdir(datapath): + # filename = '1_track.data' + fpath = os.path.join(datapath, filename) + CamerType = filename.split('_')[0] + # if os.path.isfile(fpath) and filename.find("track.data")>0: + # bboxes, ffeats, trackerboxes, tracker_feat_dict, tracking_boxes, tracking_feat_dict = extract_data(fpath) + + # if CamerType == '0': + # event['back_tracking_boxes'] = tracking_boxes + # event['back_tracking_feats'] = tracking_feat_dict + # elif CamerType == '1': + # event['front_tracking_boxes'] = tracking_boxes + # event['front_tracking_feats'] = tracking_feat_dict + + + + if os.path.isfile(fpath) and filename.find("tracking_output.data")>0: + tracking_output_boxes, tracking_output_feats = read_tracking_output(fpath) + if CamerType == '0': + event['back_sole_boxes'] = tracking_output_boxes + event['back_sole_feats'] = tracking_output_feats + elif CamerType == '1': + event['front_sole_boxes'] = tracking_output_boxes + event['front_sole_feats'] = tracking_output_feats + + + '''事件的特征表征方式选择''' + + fs_feats = event['front_sole_feats'] + bs_feats = event['back_sole_feats'] + + '''1. 如果前后摄均没有轨迹选择输出,返回''' + condt1 = len(fs_feats) + len(bs_feats) == 0 + if condt1: + return event + + + '''2. 构造综合特征''' + feats_compose = np.empty((0, 256), dtype=np.float64) + if len(fs_feats): + feats_compose = np.concatenate((feats_compose, fs_feats), axis=0) + if len(bs_feats): + feats_compose = np.concatenate((feats_compose, bs_feats), axis=0) + event['feats_compose'] = feats_compose + + '''3. 构造前摄特征''' + if len(fs_feats): + event['feats_select'] = fs_feats + return event + + + '''4. 从前摄输出轨迹中选取特定轨迹对应的特征''' + ftrboxes = event['front_tracking_boxes'] + ftrfeats = event['front_tracking_feats'] + + condt2 = len(ftrboxes) + len(ftrfeats) == 0 + condt3 = len(ftrfeats) != len(ftrboxes) + if condt2 or condt3: + return event + + bprops = [] + for boxes in ftrboxes: + track = Track(boxes) + bprops.append(max(track.trajdist)) + + index = bprops.index(max(bprops)) + box_select = ftrboxes[index] + tid = int(box_select[0, 4]) + + feat_select = ftrfeats[f"track_{tid}"] + feats_select = np.empty((0, 256), dtype=np.float64) + for fid_bid, feat in feat_select['feats'].items(): + feats_select = np.concatenate((feats_select, feat[None, :]), axis=0) + event['feats_select'] = feats_select + + return event + + +def creatd_deletedBarcode_front(filepath): + # filepath = r'\\192.168.1.28\share\测试_202406\0723\0723_1\deletedBarcode.txt' + + basepath, _ = os.path.split(filepath) + + MatchList = [] + + bcdlist = read_deletedBarcode_file(filepath) + + k = 0 + for s_list in bcdlist: + getout_fold = s_list['SeqDir'].strip() + day, hms = getout_fold.strip('_').split('-') + + ''' 生成取出事件字典 ''' + getout_event = {} + getout_event['barcode'] = s_list['Deleted'].strip() + getout_event['path'] = os.path.join(basepath, getout_fold) + + getout_event['feats_compose'] = np.empty((0, 256), dtype=np.float64) + getout_event['feats_select'] = np.empty((0, 256), dtype=np.float64) + + + InputList = [] + barcodes = [s.strip() for s in s_list['barcode']] + similarity = [float(s.strip()) for s in s_list['similarity']] + for i, barcode in enumerate(barcodes): + + ''' 生成放入事件字典 ''' + input_event = {} + + input_folds, times = [], [] + for pathname in os.listdir(basepath): + if pathname.endswith('_'): continue + if os.path.isfile(os.path.join(basepath, pathname)):continue + + infold = pathname.split('_') + if len(infold)!=2: continue + + day1, hms1 = infold[0].split('-') + + if day1==day and infold[1]==barcode and int(hms1)0: enent_name = '' @@ -368,35 +382,56 @@ def main_loop(): enent_name = prefix[i] + name break spath = os.path.join(savepath, enent_name) - do_tracking(fpath, spath) - - k +=1 - if k==1: - break - + + # abimg = do_tracking(fpath, spath) + # imgs.append(abimg) + try: + abimg = do_tracking(fpath, spath) + imgs.append(abimg) + if len(imgs) == 2: + Img = np.concatenate((imgs[0], imgs[1]), axis = 0) + + H, W = Img.shape[:2] + cv2.line(Img, (0, int(H/2)), (int(W), int(H/2)), (128, 255, 128), 2) + else: + Img = imgs[0] + + imgpath = os.path.join(savepath, enent_name + '_alg.png') + cv2.imwrite(imgpath, Img) + + except Exception as e: + print(f'Error! {fpath}, {e}') + + + + # k +=1 + # if k==1: + # break + def main(): ''' - fpath: data文件,包括 Pipeline 各模块输出 + fpath: data文件地址,该 data 文件包括 Pipeline 各模块输出 save_dir:需包含二级目录,其中一级目录为轨迹图像; 二级目录为与data文件对应的序列图像存储地址。 ''' - fpath = r'\\192.168.1.28\share\测试_202406\0719\719_4\20240719-164209_\0_track.data' - save_dir = r'D:\contrast\dataset\result\20240719-164209_6971284204320_6902890247777\getout' + fpath = r'\\192.168.1.28\share\测试_202406\0723\0723_1\20240723-101506_6906839615771\1_track.data' + save_dir = r'D:\contrast\dataset\result\20240723-101506_\images' do_tracking(fpath, save_dir) if __name__ == "__main__": - try: - # main() - main_loop() - - except Exception as e: - print(f'Error: {e}') + + main_loop() + # main() + # try: + # main_loop() + # except Exception as e: + # print(f'Error: {e}') diff --git a/tracking/utils/__pycache__/plotting.cpython-39.pyc b/tracking/utils/__pycache__/plotting.cpython-39.pyc index 2a0d87b..751d408 100644 Binary files a/tracking/utils/__pycache__/plotting.cpython-39.pyc and b/tracking/utils/__pycache__/plotting.cpython-39.pyc differ diff --git a/tracking/utils/__pycache__/read_data.cpython-39.pyc b/tracking/utils/__pycache__/read_data.cpython-39.pyc index fc7e663..2c54c25 100644 Binary files a/tracking/utils/__pycache__/read_data.cpython-39.pyc and b/tracking/utils/__pycache__/read_data.cpython-39.pyc differ diff --git a/tracking/utils/plotting.py b/tracking/utils/plotting.py index b0b528b..c5d50f0 100644 --- a/tracking/utils/plotting.py +++ b/tracking/utils/plotting.py @@ -286,7 +286,8 @@ def boxing_img(det, img, line_width=3): return imgx def draw_tracking_boxes(imgs, tracks, scale=2): - '''tracks: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index] + '''需要确保 imgs 覆盖tracks中的帧ID数 + tracks: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index] 0 1 2 3 4 5 6 7 8 关键: (1) imgs中的次序和 track 中的 fid 对应 @@ -311,12 +312,13 @@ def draw_tracking_boxes(imgs, tracks, scale=2): bboxes = array2list(tracks) - if len(bboxes)!=len(imgs): - return [] + # if len(bboxes)!=len(imgs): + # return False, imgs subimgs = [] for i, boxes in enumerate(bboxes): - annotator = Annotator(imgs[i].copy()) + fid = int(boxes[0, 7]) + annotator = Annotator(imgs[fid-1].copy()) for *xyxy, tid, conf, cls, fid, bid in boxes: label = f'id:{int(tid)}_{int(cls)}_{conf:.2f}' @@ -331,7 +333,7 @@ def draw_tracking_boxes(imgs, tracks, scale=2): annotator.box_label(pt2, label, color=color) img = annotator.result() - subimgs.append(img) + subimgs.append((fid-1, img)) return subimgs diff --git a/tracking/utils/read_data.py b/tracking/utils/read_data.py index a46510e..6877fd3 100644 --- a/tracking/utils/read_data.py +++ b/tracking/utils/read_data.py @@ -110,14 +110,17 @@ def extract_data(datapath): if len(boxes): trackingboxes.append(np.array(boxes)) - + tracking_feat_dict = {} - for i, boxes in enumerate(trackingboxes): - for box in boxes: - tid, fid, bid = int(box[4]), int(box[7]), int(box[8]) - if f"track_{tid}" not in tracking_feat_dict: - tracking_feat_dict[f"track_{tid}"]= {"feats": {}} - tracking_feat_dict[f"track_{tid}"]["feats"].update({f"{fid}_{bid}": tracker_feat_dict[f"frame_{fid}"]["feats"][bid]}) + try: + for i, boxes in enumerate(trackingboxes): + for box in boxes: + tid, fid, bid = int(box[4]), int(box[7]), int(box[8]) + if f"track_{tid}" not in tracking_feat_dict: + tracking_feat_dict[f"track_{tid}"]= {"feats": {}} + tracking_feat_dict[f"track_{tid}"]["feats"].update({f"{fid}_{bid}": tracker_feat_dict[f"frame_{fid}"]["feats"][bid]}) + except Exception as e: + print(f'Path: {datapath}, Error: {e}') return bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict