五个功能模块 1. Yolo + Tracker + Resnet, 其中 Resnet 的实现在./contrast中 track_reid.py 2. 轨迹分析模块,目录为:./tracking (1) 基于模块(Yolo + Tracker + Resnet)的输出 tracking_test.py (2) 基于测试过程数据(track.data, tracking_output.data)的输出 module_analysis.py 3. 比对分析模块,目录为:./contrast 2个场景:1:1,1:n 1:1场景: (1) 利用现场保存数据进行比对 OneToOneCompare.txt(现场保存数据) one2one_onsite.py (2) 利用本地算法进行特征提取 one2one_contrast.py 1:n场景: (1) 直接利用 deletedBarcode.txt 中数据 one2n_contrast.py (2) 构造取出、放入事件,设计不同的特征, feat_select.py 4. 整体流程仿真 pipeline.py 需要指定是个变量: (1) evtdir: 保存各个事件的文件夹 (2) SourceType: "image", "video", yolo+resent+tracker模块输入数据类型 (3) savepath: 结果数据保存位置 (4) weights: YoloV5 模型权重 savepath (1) Yolos_Tracking eventname文件夹,保存yolo+resent+tracker模块输出,包括: (1) images 或 {videoname} (2) subimgs (3) trajectory (4) front_y2.png (5) trajectory.png (2) ShoppingDict_pkfile 保存 ShoppingDict 字典的 pickle 文件,可用于构造 ShoppingEvent 对象。 (3) contrast 保存1:1、1:SN、1:n数据 (4) error_events.txt 事件字典结构: ShoppingDict = {"eventPath": eventpath, "eventName": evtname, "barcode": barcode, "eventType": '', # "input", "output", "other" "frontCamera": {}, "backCamera": {}, "one2n": [] } 相机字典: CameraEvent = {"cameraType": '', # "front", "back" "videoPath": '', "imagePaths": [], "yoloResnetTracker": [], "tracking": [], } yoloResnetTracker,列表,元素 "frameDict" 为有关帧数据的字典结构 frameDict = {"path": path, "fid": int(frameId), "bboxes": det, "tboxes": tracks, "imgs": imgdict, "feats": featdict} 5. 全实时时间切分仿真分析 time_devide.py 需分 2 步运行模块: (1) runyolo() 该模块调用 imgs_inference.py 中模块 run_yolo, 该模块重新定义了类 LoadImages, 对图像进行了旋转。 后续工作: 1). 将run_yolo模块与track_redi.yolo_resnet_tracker模块合并 2). 图像文件名标准化 (2) show_seri() 该模块调用 event_time_specify.py 中模块 devide_motion_state 具体实现: ./tracking tracking_test.py have_tracked(): 轨迹分析测试。遍历track_reid.py输出的文件夹trackdict下的所有.pkl文件。 time_test.py 统计Pipeline整体流程中各模块耗时 module_analysis.py 该模块中需要借助 try...except... 捕获data文件中的异常 main(): 遍历文件夹下的每一个子文件夹,对子文件夹执行tracking_simulate() 函数; main_loop(): (1) 根据 deletedBarcode.txt 生成事件对,并利用事件对生成存储地址 (2) 调用 tracking_simulate() 函数 tracking_simulate(eventpath, savepath): (1) 根据event_names获取事件名enent_name (2) 遍历并执行 eventpath 文件夹下的 0_track.data、1_track.data 文件,并调用do_tracking() 执行 (3) 将前后摄、本地与现场,工8幅子图合并为1幅大图。 上下子图分别显示的是前后摄,每一行4个子图,分别为: (a) tracker输出原始轨迹; (b) 本地tracking输出; (c) 现场算法轨迹选择前轨迹; (d) 现场算法轨迹选择后的轨迹 do_tracking(fpath, savedir, event_name) inputs: fpath: 0/1_track.data文件,并核验是否存在 0/1_tracking_output.data,若不存在该文件,直接返回 None, None savedir: 在该文件夹下会建立3个子文件夹及一个png轨迹图 ./savedir/event_name_images, 画boxes后的图像序列 ./savedir/event_name_subimgs, 轨迹分析后的目标子图,无 _x 为PC机结果,有 _x 为平板单摄像头轨迹选择后的输出 ./savedir/trajectory, 存储每一个轨迹图 ./savedir/event_name_tracking_select.png 或 enent_name_tracking.png 或 enent_name_select.png outputs: img_tracking:本机tracker、tracking 输出的结果比较图 abimg: 部署算法的tracking、轨迹选择分析比较图 ./utils/read_data.py 0/1_track.data 文件保存:yolo、Resnet、tracker、tracking模块的输出 函数: extract_data(datapath) 异常排除: (1) assert len(boxes)==len(feats),确保每一帧内boxes数和feats数相等 (2) assert(len(bboxes)==len(ffeats)), 确保关于bboxes的帧数和关于ffeats的帧数相等 (3) assert(len(trackerboxes)==len(trackerfeats)),确保tracker输出的boxes可以对应到相应的feats上 这里未对 len(box)!=9、len(feat)!=256, 的情况做出约束 输出: bboxes ffeats trackerboxes tracker_feat_dict[f"frame_{fid}"]["feats"]{{bid}: (256,) } trackingboxes tracking_feat_dict[f"track_{tid}"]["feats"]{f"{fid}_{bid}": tracker_feat_dict[f"frame_{fid}"]["feats"][bid]}) 0/1_tracking_output.data 文件保存用于比对的boxes、features 函数: read_tracking_output(filepath) 异常排除: (1) assert len(feats)==len(boxes) (2) box.size==9、feat.size=256 ./deprecated/contrast_one2one.py 1:1 比对评估。have Deprecated! ./enentmatch.py 1:n 模拟测试,have Deprecated! ./contrast seqfeat_compare.py similarity_compare_sequence(root_dir) inputs: root_dir:文件夹,包含"subimgs"字段,对该文件夹中的相邻图像进行相似度比较 silimarity_compare() 功能:对imgpaths文件夹中的图像进行相似度比较 select_subimgs.py 为吴华琦实现的样本选择程序 event_test.py calc_simil(event, stdfeat) 事件与标准库的对比策略,该函数在one2one_contrast.py中调用 calsiml(feat1, feat2, topkp=75, cluth=0.15): 功能:计算2个样本集的相似度 (1)(feat1, feat2),对于单样本,选择 topkp 的相似度,并求均值,得到单样本对另一个特征集的相似度; (2)simi_max:样本集 feat1 对样本集 feat2 的相似度,是一个向量 (3)对 simi_max 进行聚类,阈值为 cluth,选取值最大的聚类中心,作为2个样本集相似度的度量 前后摄轨迹选择: 情况1:前后摄轨迹(与标准集的)相似度的差 > 阈值,表明前后摄中有一个轨迹与标准集相差较远,丢弃相应轨迹,保留具有较大相似度的轨迹 情况2:前后摄轨迹(与标准集的)相似度的差 >=阈值,表明前后摄轨迹与标准集均相似,求轨迹相似度均值 input_getout_compare.py creatd_deletedBarcode_front(filepath) (1) 基于 deletedBarcode.txt, 构造取出事件和相应的放入事件,构成列表并更新这些列表。 MatchList = [(getout_event, InputList), ...] (2) 设计不同的特征选择方式,计算 getout 事件和各 input 事件的相似度,并保存于文件: deletedBarcodeTest.txt precision_compare(filepath, savepath) 读取 deletedBarcode.txt 和 deletedBarcodeTest.txt 中的数据,进行相似度比较 stdfeat_analys(): feat_analysis(featpath): 标准特征集中样本类内、类间相似度分布 feat_infer.py 简单的subimg特征提取 genfeats.py get_std_barcodeDict(bcdpath, savepath) 功能: 生成并保存只有一个key值的字典 {barcode: [imgpath1, imgpath1, ...]} stdfeat_infer(imgPath, featPath, bcdSet=None) 功能: 对 imgPath 中图像进行特征提取,生成只有一个key值的字典。 {barcode: features},features.shape=(nsample, 256),并保存至 featPath 中 onsite_contrast_pr.py one2one_pr() 现场试验输出数据的性能评估,输出1:1, 1:SN, 1:n的PR曲线和相似度直方图分布。 test_compare() 适用于202410前数据保存版本的,需调用 OneToOneCompare.txt one2one_contrast.py 已修改,未更新。 共6个地址: (1) stdSamplePath: 用于生成比对标准特征集的原始图像地址 (2) stdBarcodePath: 比对标准特征集原始图像地址的pickle文件存储,{barcode: [imgpath1, imgpath1, ...]} (3) stdFeaturePath: 比对标准特征集特征存储地址 (4) eventFeatPath: 用于1:1比对的购物事件特征存储地址、对应子图存储地址 (5) subimgPath: 1:1比对购物事件轨迹、标准barcode所对应的 subimgs 存储地址 (6) resultPath: 1:1比对结果存储地址 (1), (2), (3): 保存标准特征集向量,只需运行一次 (4): 保存测试的事件字典,只需运行一次 test_one2one() 1:1比对 (1) 初始化事件和标准特征集, 只需运行一次 init_std_evt_dict() (2) 事件barcode集和标准库barcode求交集 build_std_evt_dict() (3) 1:1性能评估 one2one_simi() (4) 计算PR曲线 one2one_pr() test_one2SN() 1:SN比对 (1) 初始化事件和标准特征集, 只需运行一次 init_std_evt_dict() (2) 事件barcode集和标准库barcode求交集 build_std_evt__dict() (3) 1:SN性能评估 one2SN_pr() init_std_evt_dict() 生成标准特征集与事件对象并存储,并存储相关数据,只需运行一次 (1) Barcode图像进行特征推理并保存 gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet) (2) 基于data文件或pipeline输出的pickle文件生成 ShoppingEvent 对象 gen_eventdict(eventDatePath, saveimg) build_std_evt_dict() 基于事件barcode集和标准库barcode交集构造用于评估性能的事件集合。 simi_calc() 计算事件和标准特征集的相似度 data_precision_compare() 不同数据精度下的性能比较 int8_to_ft16() ft16_to_uint8() one2n_contrast.py 执行1:n共需要3步,分别对应3个函数: (1) 生成事件字典并保存至 eventDataPath, 只需运行一次 (2) 读取事件字典 (3) 1:n 比对事件评估 (1) gen_eventdict(sourcePath) (2) read_eventdict() inputs: eventDataPath: 类 ShoppingEvent 对象存储地址,该对象由函数 gen_eventdict() 生成。 output: evtDicts (3) one2n_pr() inputs: evtDicts output: fpevents:FP事件地址 (4) simi_calc() 计算两个事件的相似度 one2n_contrast_old.py (disused) test_one2n() 1:n 现场测试性能评估,输出 PR 曲线 兼容 2 种 txt 文件格式:returnGoods.txt, deletedBarcode.txt, 分别对应不同的文件读取函数: - read_deletedBarcode_file() - read_returnGoods_file() one2n_return(all_list) 输入:从returnGoods.txt读取的数据 输出: corrpairs:(取出事件, 正确匹配的放入事件) errpairs:(取出事件, 放入事件, 错误匹配的放入事件) corr_similarity: (正确匹配时的相似度) err_similarity: (错误匹配时的相似度) one2n_deleted(all_list) 输入: 从deletedBarcode.txt读取的数据 输出: corrpairs:(取出事件, 取出的barcode) errpairs:(取出事件, 取出的barcode, 错误匹配的barcode) corr_similarity: (正确匹配时的相似度) err_similarity: (错误匹配时的相似度) save_tracking_imgpairs(pairs, savepath) 输入: pairs:匹配时间对,len(2)=2 or 3, 对应正确匹配与错误匹配 savepath:结果保存地址,其中图像文件的命名为:取出事件 + 放入事件 + 错误匹配时间 子函数 get_event_path(), 扫码放入的对齐名 对于 returnGoods.txt, 放入事件的事件名和对应的文件夹名不一致,需要对齐 test_rpath_deleted() 功能: 针对 eletedBarcode.txt 格式的 1:n 数据结果文件 获得 1:n 情况下正确或匹配事件对(取出事件、放入事件、错误匹配事件) 匹配事件分析, 实现函数:save_tracking_imgpairs() 重要参数: del_barcode_file: basepath: 对应事件路径 savepath: 存储路径, 是函数 save_tracking_imgpairs() 的输入 saveimgs: Ture, False, 是否保存错误匹配的事件对 get_contrast_paths() 针对 eletedBarcode.txt 格式的 1:n 数据结果文件,返回三元时间元组(getoutpath, inputpath, errorpath) test_rpath_return() 针对 returnGoods.txt 格式 1:n 数据文件,不需要调用函数get_contrast_paths() 获得 1:n 情况下正确或匹配事件对(取出事件、放入事件、错误匹配事件) 匹配事件分析, 实现函数:save_tracking_imgpairs() time_devide.py runyolo() 执行 imgs_inference.py 中的 run_yolo()模块,该模块重新定义了类 LoadImages, 对图像进行了旋转。 show_seri()