diff --git a/contrast/event_test.py b/contrast/event_test.py index b148825..1c150f8 100644 --- a/contrast/event_test.py +++ b/contrast/event_test.py @@ -7,7 +7,7 @@ Created on Mon Dec 16 18:56:18 2024 import os import cv2 -from utils.event import ShoppingEvent +from utils.event import ShoppingEvent, save_data def main(): evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images" @@ -29,39 +29,14 @@ def main(): events = list(set(events)) '''定义当前事件存储地址及生成相应文件件''' - resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result" + resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result\single_event" for evtpath in events: - evtname = os.path.basename(evtpath) event = ShoppingEvent(evtpath) + save_data(event, resultPath) - img_cat = event.draw_tracks() - trajpath = os.path.join(resultPath, "trajectory") - if not os.path.exists(trajpath): - os.makedirs(trajpath) - traj_imgpath = os.path.join(trajpath, evtname+".png") - cv2.imwrite(traj_imgpath, img_cat) + print(event.evtname) - - ## 保存序列图像和轨迹子图 - subimgpath = os.path.join(resultPath, f"{evtname}", "subimg") - imgspath = os.path.join(resultPath, f"{evtname}", "imgs") - if not os.path.exists(subimgpath): - os.makedirs(subimgpath) - if not os.path.exists(imgspath): - os.makedirs(imgspath) - - - subimgpairs = event.save_event_subimg(subimgpath) - for subimgName, subimg in subimgpairs: - spath = os.path.join(subimgpath, subimgName) - cv2.imwrite(spath, subimg) - imgpairs = event.plot_save_image(imgspath) - for imgname, img in imgpairs: - spath = os.path.join(imgspath, imgname) - cv2.imwrite(spath, img) - - print(f"{evtname}") diff --git a/contrast/one2n_contrast.py b/contrast/one2n_contrast.py index 7ad3cb3..5c32ea2 100644 --- a/contrast/one2n_contrast.py +++ b/contrast/one2n_contrast.py @@ -1,498 +1,249 @@ # -*- coding: utf-8 -*- """ -Created on Sat Jul ** 14:07:25 2024 - - 现场测试精度、召回率分析程序,是 feat_select.py 的简化版, - 但支持循环计算,并输出总的pr曲线 +Created on Wed Dec 18 11:49:01 2024 @author: ym """ - - - -import os.path -import shutil - +import os +import pickle import numpy as np -import matplotlib.pyplot as plt -import cv2 from pathlib import Path -import sys -sys.path.append(r"D:\DetectTracking") -from tracking.utils.plotting import Annotator, colors -from tracking.utils.read_data import extract_data, read_deletedBarcode_file, read_tracking_output, read_returnGoods_file -from tracking.utils.plotting import draw_tracking_boxes, get_subimgs -from contrast.utils.tools import showHist, show_recall_prec, compute_recall_precision +import matplotlib.pyplot as plt +from scipy.spatial.distance import cdist +from utils.event import ShoppingEvent -# ============================================================================= -# def read_tracking_output(filepath): -# boxes = [] -# feats = [] -# with open(filepath, 'r', encoding='utf-8') as file: -# for line in file: -# line = line.strip() # 去除行尾的换行符和可能的空白字符 -# -# if not line: -# continue -# -# if line.endswith(','): -# line = line[:-1] -# -# data = np.array([float(x) for x in line.split(",")]) -# if data.size == 9: -# boxes.append(data) -# if data.size == 256: -# feats.append(data) -# -# return np.array(boxes), np.array(feats) -# ============================================================================= - -def read_tracking_imgs(imgspath): +def gen_eventdict(sourcePath, stype="data"): + '''stype: str, + 'source': 由 videos 或 images 生成的 pickle 文件 + 'data': 从 data 文件中读取的现场运行数据 ''' - input: - imgspath:该路径中的图像为Yolo算法的输入图像,640x512 - output: - imgs_0:后摄图像,根据 frameId 进行了排序 - imgs_1:前摄图像,根据 frameId 进行了排序 - ''' - imgs_0, frmIDs_0, imgs_1, frmIDs_1 = [], [], [], [] - - for filename in os.listdir(imgspath): - file, ext = os.path.splitext(filename) - flist = file.split('_') - if len(flist)==4 and ext==".jpg": - camID, frmID = flist[0], int(flist[-1]) - imgpath = os.path.join(imgspath, filename) - img = cv2.imread(imgpath) + + k, errEvents = 0, [] + for source_path in sourcePath: + evtpath, bname = os.path.split(source_path) + + # bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479" + source_path = os.path.join(evtpath, bname) + + pickpath = os.path.join(eventDataPath, f"{bname}.pickle") + if os.path.isfile(pickpath): continue + + try: + event = ShoppingEvent(source_path, stype) + # save_data(event, resultPath) - if camID=='0': - imgs_0.append(img) - frmIDs_0.append(frmID) - if camID=='1': - imgs_1.append(img) - frmIDs_1.append(frmID) - - if len(frmIDs_0): - indice = np.argsort(np.array(frmIDs_0)) - imgs_0 = [imgs_0[i] for i in indice ] - if len(frmIDs_1): - indice = np.argsort(np.array(frmIDs_1)) - imgs_1 = [imgs_1[i] for i in indice ] - - return imgs_0, imgs_1 - + with open(pickpath, 'wb') as f: + pickle.dump(event, f) + print(bname) + except Exception as e: + errEvents.append(source_path) + print(e) + # k += 1 + # if k==1: + # break + + errfile = os.path.join(resultPath, 'error_events.txt') + with open(errfile, 'w', encoding='utf-8') as f: + for line in errEvents: + f.write(line + '\n') -# ============================================================================= -# def draw_tracking_boxes(imgs, tracks): -# '''tracks: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index] -# 0 1 2 3 4 5 6 7 8 -# 关键:imgs中的次序和 track 中的 fid 对应 -# ''' -# subimgs = [] -# for *xyxy, tid, conf, cls, fid, bid in tracks: -# label = f'id:{int(tid)}_{int(cls)}_{conf:.2f}' -# -# annotator = Annotator(imgs[int(fid-1)].copy()) -# if cls==0: -# color = colors(int(cls), True) -# elif tid>0 and cls!=0: -# color = colors(int(tid), True) -# else: -# color = colors(19, True) # 19为调色板的最后一个元素 -# -# pt2 = [p/2 for p in xyxy] -# annotator.box_label(pt2, label, color=color) -# img0 = annotator.result() -# -# subimgs.append(img0) -# -# return subimgs -# ============================================================================= +def read_eventdict(eventDataPath): + evtDict = {} + for filename in os.listdir(eventDataPath): + evtname, ext = os.path.splitext(filename) + if ext != ".pickle": continue -def get_contrast_paths(pair, basepath): - assert(len(pair)==2 or len(pair)==3), "pair: seqdir, delete, barcodes" - - getout_fold = pair[0] # 取出操作对应的文件夹 - relvt_barcode = pair[1] # 取出操作对应放入操作的 Barcode - if len(pair)==3: - error_match = pair[2] # 取出操作错误匹配的 Barcode - else: - error_match = '' - - - getoutpath, inputpath, errorpath = '', '', '' - - day, hms = getout_fold.strip('_').split('-') - - input_folds, times = [], [] - errmatch_folds, errmatch_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]==relvt_barcode and int(hms1) simimax - for k in idx: - if similarity[k] > simimax: - idxmax = k - simimax = similarity[k] - if idxmax>-1: - input_event = events[idxmax] + o2n_evt = [evt for name, evt in evtDicts.items() if name.find(nname[:15])==0] + if len(o2n_evt)==1: + o2nevt = o2n_evt[0] else: - input_event = '' + continue + if typee == "11": + boxes1 = event.front_trackingboxes + boxes2 = o2nevt.front_trackingboxes + + feat1 = event.front_trackingfeats + feat2 = o2nevt.front_trackingfeats + if typee == "10": + boxes1 = event.front_trackingboxes + boxes2 = o2nevt.back_trackingboxes + + feat1 = event.front_trackingfeats + feat2 = o2nevt.back_trackingfeats + if typee == "00": + boxes1 = event.back_trackingboxes + boxes2 = o2nevt.back_trackingboxes + + feat1 = event.back_trackingfeats + feat2 = o2nevt.back_trackingfeats + if typee == "01": + boxes1 = event.back_trackingboxes + boxes2 = o2nevt.front_trackingboxes + + feat1 = event.back_trackingfeats + feat2 = o2nevt.front_trackingfeats + + matrix = 1 - cdist(feat1[0], feat2[0], 'cosine') + simi_mean = np.mean(matrix) + simi_max = np.max(matrix) - errpairs.append((seqdir, input_event, events[index])) - err_similarity.append(max(similarity)) - - return corrpairs, errpairs, corr_similarity, err_similarity - - -def test_rpath_deleted(): - '''deletedBarcode.txt 格式的 1:n 数据结果文件, returnGoods.txt格式数据文件不需要调用该函数''' - - del_bfile = r'\\192.168.1.28\share\测试_202406\709\deletedBarcode.txt' - basepath = r'\\192.168.1.28\share\测试_202406\709' - savepath = r'D:\DetectTracking\contrast\result' - saveimgs = True - - - - relative_paths = [] - - '''1. 读取 deletedBarcode 文件 ''' - all_list = read_deletedBarcode_file(del_bfile) - - '''2. 算法性能评估,并输出 (取出,删除, 错误匹配) 对 ''' - corrpairs, errpairs, _, _ = one2n_deleted(all_list) - - '''3. 构造事件组合(取出,放入并删除, 错误匹配) 对应路径 ''' - for errpair in errpairs: - GetoutPath, InputPath, ErrorPath = get_contrast_paths(errpair, basepath) + evt_names.append(nname) + evt_barcodes.append(barcode) + evt_similars.append(simi_mean) + evt_types.append(typee) - pairs = (GetoutPath, InputPath, ErrorPath) - relative_paths.append(pairs) - print(InputPath) - '''3. 获取 (取出,放入并删除, 错误匹配) 对应路径,保存相应轨迹图像''' - if saveimgs: - save_tracking_imgpairs(pairs, savepath) - -def test_rpath_return(): - return_bfile = r'\\192.168.1.28\share\测试_202406\1101\images\returnGoods.txt' - basepath = r'\\192.168.1.28\share\测试_202406\1101\images' - savepath = r'D:\DetectTracking\contrast\result' + if len(evt_names)==len(evt_barcodes) and len(evt_barcodes)==len(evt_similars) \ + and len(evt_similars)==len(evt_types) and len(evt_names)>0: + + maxsim = evt_similars[evt_similars.index(max(evt_similars))] + for i in range(len(evt_names)): + bcd, simi = evt_barcodes[i], evt_similars[i] + + if bcd==event.barcode and simi==maxsim: + tpsimi.append(simi) + tpevents.append(evtname) + elif bcd==event.barcode and simi!=maxsim: + fnsimi.append(simi) + fnevents.append(evtname) + elif bcd!=event.barcode and simi!=maxsim: + tnsimi.append(simi) + tnevents.append(evtname) + elif bcd!=event.barcode and simi==maxsim and event.barcode in evt_barcodes: + fpsimi.append(simi) + fpevents.append(evtname) + else: + errorFile_one2n.append(evtname) + + + + ''' 1:n 数据存储,需根据相似度排序''' + PPrecise, PRecall = [], [] + NPrecise, NRecall = [], [] - all_list = read_returnGoods_file(return_bfile) - corrpairs, errpairs, _, _ = one2n_return(all_list) - for corrpair in corrpairs: - GetoutPath = os.path.join(basepath, corrpair[0]) - InputPath = os.path.join(basepath, corrpair[1]) + Thresh = np.linspace(-0.2, 1, 100) + for th in Thresh: + '''============================= 1:n 计算''' + TP = sum(np.array(tpsimi) >= th) + FP = sum(np.array(fpsimi) >= th) + FN = sum(np.array(fnsimi) < th) + TN = sum(np.array(tnsimi) < th) - pairs = (GetoutPath, InputPath) - save_tracking_imgpairs(pairs, savepath) - - for errpair in errpairs: - GetoutPath = os.path.join(basepath, errpair[0]) - InputPath = os.path.join(basepath, errpair[1]) - ErrorPath = os.path.join(basepath, errpair[2]) + PPrecise.append(TP/(TP+FP+1e-6)) + PRecall.append(TP/(len(tpsimi)+len(fnsimi)+1e-6)) + NPrecise.append(TN/(TN+FN+1e-6)) + NRecall.append(TN/(len(tnsimi)+len(fpsimi)+1e-6)) - pairs = (GetoutPath, InputPath, ErrorPath) - save_tracking_imgpairs(pairs, savepath) - - -def test_one2n(): - ''' - 1:n 性能测试 - 兼容 2 种 txt 文件格式:returnGoods.txt, deletedBarcode.txt - fpath: 文件路径、或文件夹,其中包含多个 txt 文件 - savepath: pr曲线保存路径 - ''' - # fpath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\other' # deletedBarcode.txt - fpath = r'\\192.168.1.28\share\测试_202406\1108_展厅模型v800测试' # returnGoods.txt - savepath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\illustration' - - if os.path.isdir(fpath): - filepaths = [os.path.join(fpath, f) for f in os.listdir(fpath) - if f.find('.txt')>0 - and (f.find('deletedBarcode')>=0 or f.find('returnGoods')>=0)] - elif os.path.isfile(fpath): - filepaths = [fpath] - else: - return + + '''4. ============================= 1:n 曲线,''' + fig, ax = plt.subplots() + ax.plot(Thresh, PPrecise, 'r', label='Precise_Pos: TP/TPFP') + ax.plot(Thresh, PRecall, 'b', label='Recall_Pos: TP/TPFN') + ax.plot(Thresh, NPrecise, 'g', label='Precise_Neg: TN/TNFP') + ax.plot(Thresh, NRecall, 'c', label='Recall_Neg: TN/TNFN') + ax.set_xlim([0, 1]) + ax.set_ylim([0, 1]) + ax.grid(True) + ax.set_title('1:n Precise & Recall') + ax.set_xlabel(f"Event Num: {len(tpsimi)+len(fnsimi)}") + ax.legend() + plt.show() + ## ============================= 1:n 直方图''' + fig, axes = plt.subplots(2, 2) + axes[0, 0].hist(tpsimi, bins=60, edgecolor='black') + axes[0, 0].set_xlim([-0.2, 1]) + axes[0, 0].set_title('TP') + axes[0, 1].hist(fpsimi, bins=60, edgecolor='black') + axes[0, 1].set_xlim([-0.2, 1]) + axes[0, 1].set_title('FP') + axes[1, 0].hist(tnsimi, bins=60, edgecolor='black') + axes[1, 0].set_xlim([-0.2, 1]) + axes[1, 0].set_title('TN') + axes[1, 1].hist(fnsimi, bins=60, edgecolor='black') + axes[1, 1].set_xlim([-0.2, 1]) + axes[1, 1].set_title('FN') + plt.show() + + return fpevents + +def main(): - if not os.path.exists(savepath): - os.mkdir(savepath) - - BarLists, blists = {}, [] - for pth in filepaths: - file = str(Path(pth).stem) - if file.find('deletedBarcode')>=0: - blist = read_deletedBarcode_file(pth) - if file.find('returnGoods')>=0: - blist = read_returnGoods_file(pth) - - BarLists.update({file: blist}) - blists.extend(blist) + '''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 ''' + # gen_eventdict(sourcePath) - if len(blists): BarLists.update({"Total": blists}) - for file, blist in BarLists.items(): - if all(b['filetype']=="deletedBarcode" for b in blist): - _, _, correct_similarity, err_similarity = one2n_deleted(blist) - if all(b['filetype']=="returnGoods" for b in blists): - _, _, correct_similarity, err_similarity = one2n_return(blist) - - recall, prec, ths = compute_recall_precision(err_similarity, correct_similarity) - - plt1 = show_recall_prec(recall, prec, ths) - # plt1.show() - plt1.xlabel(f'threshold, Num: {len(blist)}') - plt1.savefig(os.path.join(savepath, file+'_pr.png')) - # plt1.close() - - plt2 = showHist(err_similarity, correct_similarity) - plt2.show() - plt2.savefig(os.path.join(savepath, file+'_hist.png')) - # plt.close() - - + '''2. 读取时间字典 ''' + evtDicts = read_eventdict(eventDataPath) + + + '''3. 1:n 比对事件评估 ''' + fpevents = one2n_pr(evtDicts) + fpErrFile = str(Path(resultPath).joinpath("one2n_Error.txt")) + with open(fpErrFile, "w") as file: + for item in fpevents: + file.write(item + "\n") + + + + + + + + if __name__ == '__main__': - # test_one2n() - test_rpath_return() # returnGoods.txt - # test_rpath_deleted() # deleteBarcode.txt + + eventSourcePath = [r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images"] + resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result" + + eventDataPath = os.path.join(resultPath, "evtobjs") + similPath = os.path.join(resultPath, "simidata") + if not os.path.exists(eventDataPath): + os.makedirs(eventDataPath) + if not os.path.exists(similPath): + os.makedirs(similPath) + + main() - # try: - # test_rpath_return() - # test_rpath_deleted() - # except Exception as e: - # print(e) + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/contrast/one2n_contrast_old.py b/contrast/one2n_contrast_old.py new file mode 100644 index 0000000..7ad3cb3 --- /dev/null +++ b/contrast/one2n_contrast_old.py @@ -0,0 +1,498 @@ +# -*- coding: utf-8 -*- +""" +Created on Sat Jul ** 14:07:25 2024 + + 现场测试精度、召回率分析程序,是 feat_select.py 的简化版, + 但支持循环计算,并输出总的pr曲线 + +@author: ym +""" + + + +import os.path +import shutil + +import numpy as np +import matplotlib.pyplot as plt +import cv2 +from pathlib import Path +import sys +sys.path.append(r"D:\DetectTracking") +from tracking.utils.plotting import Annotator, colors +from tracking.utils.read_data import extract_data, read_deletedBarcode_file, read_tracking_output, read_returnGoods_file +from tracking.utils.plotting import draw_tracking_boxes, get_subimgs +from contrast.utils.tools import showHist, show_recall_prec, compute_recall_precision + + +# ============================================================================= +# def read_tracking_output(filepath): +# boxes = [] +# feats = [] +# with open(filepath, 'r', encoding='utf-8') as file: +# for line in file: +# line = line.strip() # 去除行尾的换行符和可能的空白字符 +# +# if not line: +# continue +# +# if line.endswith(','): +# line = line[:-1] +# +# data = np.array([float(x) for x in line.split(",")]) +# if data.size == 9: +# boxes.append(data) +# if data.size == 256: +# feats.append(data) +# +# return np.array(boxes), np.array(feats) +# ============================================================================= + +def read_tracking_imgs(imgspath): + ''' + input: + imgspath:该路径中的图像为Yolo算法的输入图像,640x512 + output: + imgs_0:后摄图像,根据 frameId 进行了排序 + imgs_1:前摄图像,根据 frameId 进行了排序 + ''' + imgs_0, frmIDs_0, imgs_1, frmIDs_1 = [], [], [], [] + + for filename in os.listdir(imgspath): + file, ext = os.path.splitext(filename) + flist = file.split('_') + if len(flist)==4 and ext==".jpg": + camID, frmID = flist[0], int(flist[-1]) + imgpath = os.path.join(imgspath, filename) + img = cv2.imread(imgpath) + + if camID=='0': + imgs_0.append(img) + frmIDs_0.append(frmID) + if camID=='1': + imgs_1.append(img) + frmIDs_1.append(frmID) + + if len(frmIDs_0): + indice = np.argsort(np.array(frmIDs_0)) + imgs_0 = [imgs_0[i] for i in indice ] + if len(frmIDs_1): + indice = np.argsort(np.array(frmIDs_1)) + imgs_1 = [imgs_1[i] for i in indice ] + + return imgs_0, imgs_1 + + +# ============================================================================= +# def draw_tracking_boxes(imgs, tracks): +# '''tracks: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index] +# 0 1 2 3 4 5 6 7 8 +# 关键:imgs中的次序和 track 中的 fid 对应 +# ''' +# subimgs = [] +# for *xyxy, tid, conf, cls, fid, bid in tracks: +# label = f'id:{int(tid)}_{int(cls)}_{conf:.2f}' +# +# annotator = Annotator(imgs[int(fid-1)].copy()) +# if cls==0: +# color = colors(int(cls), True) +# elif tid>0 and cls!=0: +# color = colors(int(tid), True) +# else: +# color = colors(19, True) # 19为调色板的最后一个元素 +# +# pt2 = [p/2 for p in xyxy] +# annotator.box_label(pt2, label, color=color) +# img0 = annotator.result() +# +# subimgs.append(img0) +# +# return subimgs +# ============================================================================= + +def get_contrast_paths(pair, basepath): + assert(len(pair)==2 or len(pair)==3), "pair: seqdir, delete, barcodes" + + getout_fold = pair[0] # 取出操作对应的文件夹 + relvt_barcode = pair[1] # 取出操作对应放入操作的 Barcode + if len(pair)==3: + error_match = pair[2] # 取出操作错误匹配的 Barcode + else: + error_match = '' + + + getoutpath, inputpath, errorpath = '', '', '' + + day, hms = getout_fold.strip('_').split('-') + + input_folds, times = [], [] + errmatch_folds, errmatch_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]==relvt_barcode and int(hms1) simimax + for k in idx: + if similarity[k] > simimax: + idxmax = k + simimax = similarity[k] + if idxmax>-1: + input_event = events[idxmax] + else: + input_event = '' + + errpairs.append((seqdir, input_event, events[index])) + err_similarity.append(max(similarity)) + + return corrpairs, errpairs, corr_similarity, err_similarity + + +def test_rpath_deleted(): + '''deletedBarcode.txt 格式的 1:n 数据结果文件, returnGoods.txt格式数据文件不需要调用该函数''' + + del_bfile = r'\\192.168.1.28\share\测试_202406\709\deletedBarcode.txt' + basepath = r'\\192.168.1.28\share\测试_202406\709' + savepath = r'D:\DetectTracking\contrast\result' + saveimgs = True + + + + relative_paths = [] + + '''1. 读取 deletedBarcode 文件 ''' + all_list = read_deletedBarcode_file(del_bfile) + + '''2. 算法性能评估,并输出 (取出,删除, 错误匹配) 对 ''' + corrpairs, errpairs, _, _ = one2n_deleted(all_list) + + '''3. 构造事件组合(取出,放入并删除, 错误匹配) 对应路径 ''' + for errpair in errpairs: + GetoutPath, InputPath, ErrorPath = get_contrast_paths(errpair, basepath) + + pairs = (GetoutPath, InputPath, ErrorPath) + relative_paths.append(pairs) + + print(InputPath) + '''3. 获取 (取出,放入并删除, 错误匹配) 对应路径,保存相应轨迹图像''' + if saveimgs: + save_tracking_imgpairs(pairs, savepath) + +def test_rpath_return(): + return_bfile = r'\\192.168.1.28\share\测试_202406\1101\images\returnGoods.txt' + basepath = r'\\192.168.1.28\share\测试_202406\1101\images' + savepath = r'D:\DetectTracking\contrast\result' + + all_list = read_returnGoods_file(return_bfile) + corrpairs, errpairs, _, _ = one2n_return(all_list) + for corrpair in corrpairs: + GetoutPath = os.path.join(basepath, corrpair[0]) + InputPath = os.path.join(basepath, corrpair[1]) + + pairs = (GetoutPath, InputPath) + save_tracking_imgpairs(pairs, savepath) + + for errpair in errpairs: + GetoutPath = os.path.join(basepath, errpair[0]) + InputPath = os.path.join(basepath, errpair[1]) + ErrorPath = os.path.join(basepath, errpair[2]) + + pairs = (GetoutPath, InputPath, ErrorPath) + save_tracking_imgpairs(pairs, savepath) + + +def test_one2n(): + ''' + 1:n 性能测试 + 兼容 2 种 txt 文件格式:returnGoods.txt, deletedBarcode.txt + fpath: 文件路径、或文件夹,其中包含多个 txt 文件 + savepath: pr曲线保存路径 + ''' + # fpath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\other' # deletedBarcode.txt + fpath = r'\\192.168.1.28\share\测试_202406\1108_展厅模型v800测试' # returnGoods.txt + savepath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\illustration' + + if os.path.isdir(fpath): + filepaths = [os.path.join(fpath, f) for f in os.listdir(fpath) + if f.find('.txt')>0 + and (f.find('deletedBarcode')>=0 or f.find('returnGoods')>=0)] + elif os.path.isfile(fpath): + filepaths = [fpath] + else: + return + + if not os.path.exists(savepath): + os.mkdir(savepath) + + BarLists, blists = {}, [] + for pth in filepaths: + file = str(Path(pth).stem) + if file.find('deletedBarcode')>=0: + blist = read_deletedBarcode_file(pth) + if file.find('returnGoods')>=0: + blist = read_returnGoods_file(pth) + + BarLists.update({file: blist}) + blists.extend(blist) + + if len(blists): BarLists.update({"Total": blists}) + for file, blist in BarLists.items(): + if all(b['filetype']=="deletedBarcode" for b in blist): + _, _, correct_similarity, err_similarity = one2n_deleted(blist) + if all(b['filetype']=="returnGoods" for b in blists): + _, _, correct_similarity, err_similarity = one2n_return(blist) + + recall, prec, ths = compute_recall_precision(err_similarity, correct_similarity) + + plt1 = show_recall_prec(recall, prec, ths) + # plt1.show() + plt1.xlabel(f'threshold, Num: {len(blist)}') + plt1.savefig(os.path.join(savepath, file+'_pr.png')) + # plt1.close() + + plt2 = showHist(err_similarity, correct_similarity) + plt2.show() + plt2.savefig(os.path.join(savepath, file+'_hist.png')) + # plt.close() + + + +if __name__ == '__main__': + # test_one2n() + test_rpath_return() # returnGoods.txt + # test_rpath_deleted() # deleteBarcode.txt + + + # try: + # test_rpath_return() + # test_rpath_deleted() + # except Exception as e: + # print(e) + + diff --git a/contrast/one2one_contrast.py b/contrast/one2one_contrast.py index f6b8177..78349b1 100644 --- a/contrast/one2one_contrast.py +++ b/contrast/one2one_contrast.py @@ -52,7 +52,7 @@ from tracking.utils.read_data import extract_data, read_tracking_output, read_si from tracking.utils.plotting import Annotator, colors from feat_extract.config import config as conf from feat_extract.inference import FeatsInterface -from utils.event import ShoppingEvent +from utils.event import ShoppingEvent, save_data from genfeats import gen_bcd_features @@ -84,86 +84,6 @@ def ft16_to_uint8(arr_ft16): return arr_uint8, arr_ft16_ -# ============================================================================= -# def plot_save_image(event, savepath): -# cameras = ('front', 'back') -# for camera in cameras: -# if camera == 'front': -# boxes = event.front_trackerboxes -# imgpaths = event.front_imgpaths -# else: -# boxes = event.back_trackerboxes -# imgpaths = event.back_imgpaths -# -# def array2list(bboxes): -# '''[x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]''' -# frame_ids = bboxes[:, 7].astype(int) -# fID = np.unique(bboxes[:, 7].astype(int)) -# fboxes = [] -# for f_id in fID: -# idx = np.where(frame_ids==f_id)[0] -# box = bboxes[idx, :] -# fboxes.append((f_id, box)) -# return fboxes -# -# fboxes = array2list(boxes) -# -# for fid, fbox in fboxes: -# imgpath = imgpaths[int(fid-1)] -# -# image = cv2.imread(imgpath) -# -# annotator = Annotator(image.copy(), line_width=2) -# for i, *xyxy, tid, score, cls, fid, bid in enumerate(fbox): -# label = f'{int(id), int(cls)}' -# if tid >=0 and cls==0: -# color = colors(int(cls), True) -# elif tid >=0 and cls!=0: -# color = colors(int(id), True) -# else: -# color = colors(19, True) # 19为调色板的最后一个元素 -# annotator.box_label(xyxy, label, color=color) -# -# im0 = annotator.result() -# spath = os.path.join(savepath, Path(imgpath).name) -# cv2.imwrite(spath, im0) -# -# -# def save_event_subimg(event, savepath): -# ''' -# 功能: 保存一次购物事件的轨迹子图 -# 9 items: barcode, type, filepath, back_imgpaths, front_imgpaths, -# back_boxes, front_boxes, back_feats, front_feats, -# feats_compose, feats_select -# 子图保存次序:先前摄、后后摄,以 k 为编号,和 "feats_compose" 中次序相同 -# ''' -# cameras = ('front', 'back') -# for camera in cameras: -# if camera == 'front': -# boxes = event.front_boxes -# imgpaths = event.front_imgpaths -# else: -# boxes = event.back_boxes -# imgpaths = event.back_imgpaths -# -# for i, box in enumerate(boxes): -# x1, y1, x2, y2, tid, score, cls, fid, bid = box -# -# imgpath = imgpaths[int(fid-1)] -# image = cv2.imread(imgpath) -# -# subimg = image[int(y1/2):int(y2/2), int(x1/2):int(x2/2), :] -# -# camerType, timeTamp, _, frameID = os.path.basename(imgpath).split('.')[0].split('_') -# subimgName = f"cam{camerType}_{i}_tid{int(tid)}_fid({int(fid)}, {frameID}).png" -# spath = os.path.join(savepath, subimgName) -# -# cv2.imwrite(spath, subimg) -# # basename = os.path.basename(event['filepath']) -# print(f"Image saved: {os.path.basename(event.eventpath)}") -# ============================================================================= - - def data_precision_compare(stdfeat, evtfeat, evtMessage, save=True): evt, stdbcd, label = evtMessage rltdata, rltdata_ft16, rltdata_ft16_ = [], [], [] @@ -289,43 +209,7 @@ def one2one_simi(): with open(evtpath, 'rb') as f: evtdata = pickle.load(f) evtDict[evtname] = evtdata - - - '''======4.1 事件轨迹子图保存 ======================''' - error_event = [] - for evtname, event in evtDict.items(): - pairpath = os.path.join(subimgPath, f"{evtname}") - if not os.path.exists(pairpath): - os.makedirs(pairpath) - try: - subimgpairs = event.save_event_subimg(pairpath) - for subimgName, subimg in subimgpairs: - spath = os.path.join(pairpath, subimgName) - cv2.imwrite(spath, subimg) - - except Exception as e: - error_event.append(evtname) - - img_path = os.path.join(imagePath, f"{evtname}") - if not os.path.exists(img_path): - os.makedirs(img_path) - try: - imgpairs = event.plot_save_image(img_path) - for imgname, img in imgpairs: - spath = os.path.join(img_path, imgname) - cv2.imwrite(spath, img) - except Exception as e: - error_event.append(evtname) - - - - - errfile = os.path.join(subimgPath, f'error_event.txt') - with open(errfile, 'w', encoding='utf-8') as f: - for line in error_event: - f.write(line + '\n') - '''======4.2 barcode 标准图像保存 ==================''' # for stdbcd in barcodes: @@ -440,16 +324,13 @@ def compute_precise_recall(rltdata): rltpath = os.path.join(similPath, 'pr.png') plt.savefig(rltpath) # svg, png, pdf - def gen_eventdict(sourcePath, saveimg=True): - eventList = [] - errEvents = [] - k = 0 + k, errEvents = 0, [] for source_path in sourcePath: evtpath, bname = os.path.split(source_path) - bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479" + # bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479" source_path = os.path.join(evtpath, bname) pickpath = os.path.join(eventDataPath, f"{bname}.pickle") @@ -457,7 +338,8 @@ def gen_eventdict(sourcePath, saveimg=True): try: event = ShoppingEvent(source_path, stype="data") - eventList.append(event) + # save_data(event, resultPath) + with open(pickpath, 'wb') as f: pickle.dump(event, f) print(bname) @@ -465,11 +347,12 @@ def gen_eventdict(sourcePath, saveimg=True): errEvents.append(source_path) print(e) - k += 1 - if k==1: - break + # k += 1 + # if k==1: + # break + - errfile = os.path.join(eventDataPath, f'error_events.txt') + errfile = os.path.join(resultPath, 'error_events.txt') with open(errfile, 'w', encoding='utf-8') as f: for line in errEvents: f.write(line + '\n') @@ -477,6 +360,8 @@ def gen_eventdict(sourcePath, saveimg=True): def test_one2one(): + + '''==== 0. 生成事件列表和对应的 Barcodes列表 ===========''' bcdList, event_spath = [], [] for evtpath in eventSourcePath: for evtname in os.listdir(evtpath): @@ -486,9 +371,9 @@ def test_one2one(): if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10: bcdList.append(evt[-1]) event_spath.append(os.path.join(evtpath, evtname)) - - bcdSet = set(bcdList) - '''==== 1. 生成标准特征集, 只需运行一次, 在 genfeats.py 中实现 ===========''' + + '''==== 1. 生成标准特征集, 只需运行一次, 在 genfeats.py 中实现 ===========''' + # bcdSet = set(bcdList) # gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet) print("stdFeats have generated and saved!") @@ -511,40 +396,25 @@ if __name__ == '__main__': (3) stdFeaturePath: 比对标准特征集特征存储地址 (4) eventSourcePath: 事件地址 (5) resultPath: 结果存储地址 - (6) eventDataPath: 用于1:1比对的购物事件特征存储地址、对应子图存储地址 - (7) subimgPath: 1:1比对购物事件轨迹、标准barcode所对应的 subimgs 存储地址 - (8) similPath: 1:1比对结果存储地址(事件级) + (6) eventDataPath: 用于1:1比对的购物事件存储地址,在resultPath下 + (7) similPath: 1:1比对结果存储地址(事件级),在resultPath下 ''' - # stdSamplePath = r"\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_500_1979_已清洗" - # stdBarcodePath = r"\\192.168.1.28\share\测试_202406\contrast\std_barcodes_2192" - # stdFeaturePath = r"\\192.168.1.28\share\测试_202406\contrast\std_features_ft32" - # eventDataPath = r"\\192.168.1.28\share\测试_202406\contrast\events" - # subimgPath = r'\\192.168.1.28\share\测试_202406\contrast\subimgs' - # similPath = r"D:\DetectTracking\contrast\result\pickle" - # eventSourcePath = [r'\\192.168.1.28\share\测试_202406\1101\images'] stdSamplePath = r"\\192.168.1.28\share\数据\已完成数据\展厅数据\v1.0\比对数据\整理\zhantingBase" stdBarcodePath = r"D:\exhibition\dataset\bcdpath" stdFeaturePath = r"D:\exhibition\dataset\feats" - resultPath = r"D:\exhibition\result\events" + # eventSourcePath = [r'D:\exhibition\images\20241202'] # eventSourcePath = [r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\展厅测试\1129_展厅模型v801测试组测试"] - eventSourcePath = [r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\展厅测试\1126_展厅模型v801测试"] + eventSourcePath = [r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images"] + resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result" - - '''定义当前事件存储地址及生成相应文件件''' - eventDataPath = os.path.join(resultPath, "1126", "evtobjs") - subimgPath = os.path.join(resultPath, "1126", "subimgs") - imagePath = os.path.join(resultPath, "1126", "image") - similPath = os.path.join(resultPath, "1126", "simidata") - + + eventDataPath = os.path.join(resultPath, "evtobjs") + similPath = os.path.join(resultPath, "simidata") if not os.path.exists(eventDataPath): os.makedirs(eventDataPath) - if not os.path.exists(subimgPath): - os.makedirs(subimgPath) - if not os.path.exists(imagePath): - os.makedirs(imagePath) if not os.path.exists(similPath): os.makedirs(similPath) diff --git a/contrast/one2one_onsite.py b/contrast/onsite_contrast_pr.py similarity index 99% rename from contrast/one2one_onsite.py rename to contrast/onsite_contrast_pr.py index 1456c9d..b26005f 100644 --- a/contrast/one2one_onsite.py +++ b/contrast/onsite_contrast_pr.py @@ -104,7 +104,7 @@ def test_compare(): plot_pr_curve(simiList) -def one2one_pr(paths): +def contrast_pr(paths): ''' 1:1 @@ -501,7 +501,7 @@ def one2one_pr(paths): if __name__ == "__main__": evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images" - one2one_pr(evtpaths) + contrast_pr(evtpaths) diff --git a/contrast/utils/__pycache__/event.cpython-39.pyc b/contrast/utils/__pycache__/event.cpython-39.pyc index 0cbfef1..3ee59c8 100644 Binary files a/contrast/utils/__pycache__/event.cpython-39.pyc and b/contrast/utils/__pycache__/event.cpython-39.pyc differ diff --git a/contrast/utils/event.py b/contrast/utils/event.py index 090cd0c..541a2ab 100644 --- a/contrast/utils/event.py +++ b/contrast/utils/event.py @@ -19,6 +19,37 @@ from tracking.utils.read_data import extract_data, read_tracking_output, read_si IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png'] VID_FORMAT = ['.mp4', '.avi'] +def save_data(event, resultPath=None): + '''事件轨迹子图保存''' + if resultPath is None: + resultPath = os.path.dirname(os.path.abspath(__file__)) + + + subimgpath = os.path.join(resultPath, f"{event.evtname}", "subimg") + imgspath = os.path.join(resultPath, f"{event.evtname}", "imgs") + if not os.path.exists(subimgpath): + os.makedirs(subimgpath) + if not os.path.exists(imgspath): + os.makedirs(imgspath) + ##(2) 保存轨迹中的子图 + subimgpairs = event.save_event_subimg(subimgpath) + for subimgName, subimg in subimgpairs: + spath = os.path.join(subimgpath, subimgName) + cv2.imwrite(spath, subimg) + + ##(3) 保存序列图像 + imgpairs = event.plot_save_image(imgspath) + for imgname, img in imgpairs: + spath = os.path.join(imgspath, imgname) + cv2.imwrite(spath, img) + ##(4) 保存轨迹散点图 + img_cat = event.draw_tracks() + trajpath = os.path.join(resultPath, "trajectory") + if not os.path.exists(trajpath): + os.makedirs(trajpath) + traj_imgpath = os.path.join(trajpath, event.evtname+".png") + cv2.imwrite(traj_imgpath, img_cat) + def array2list(bboxes): ''' @@ -44,7 +75,7 @@ def array2list(bboxes): class ShoppingEvent: def __init__(self, eventpath, stype="data"): - '''stype: str, 'pickle', 'data', ''' + '''stype: str, 'source', 'data', ''' self.eventpath = eventpath self.evtname = str(Path(eventpath).stem) @@ -60,6 +91,7 @@ class ShoppingEvent: '''=========== process.data ===============================''' self.one2one = None self.one2n = None + self.one2SN = None '''=========== 0/1_track.data =============================''' self.back_yolobboxes = [] @@ -85,8 +117,8 @@ class ShoppingEvent: if stype=="data": self.from_datafile(eventpath) - if stype=="pickle": - self.from_pklfile(eventpath) + if stype=="source": + self.from_source_pkl(eventpath) self.feats_select = [] self.feats_compose = np.empty((0, 256), dtype=np.float64) @@ -131,7 +163,7 @@ class ShoppingEvent: return kdata, outdata - def from_pklfile(self, eventpath): + def from_source_pkl(self, eventpath): with open(eventpath, 'rb') as f: ShoppingDict = pickle.load(f) @@ -222,7 +254,7 @@ class ShoppingEvent: SimiDict = read_similar(procpath) self.one2one = SimiDict['one2one'] self.one2n = SimiDict['one2n'] - + self.one2SN = SimiDict['one2SN'] '''=========== 0/1_track.data & 0/1_tracking_output.data =======''' for dataname in os.listdir(eventpath): @@ -411,14 +443,10 @@ class ShoppingEvent: -def main(): - - +def main(): # pklpath = r"D:\DetectTracking\evtresult\images2\ShoppingDict.pkl" - # evt = ShoppingEvent(pklpath, stype='pickle') - - - + # evt = ShoppingEvent(pklpath, stype='source') + evtpath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images\20241209-160248-08edd5f6-1806-45ad-babf-7a4dd11cea60_6973226721445" evt = ShoppingEvent(evtpath, stype='data') @@ -427,65 +455,7 @@ def main(): cv2.imwrite("a.png", img_cat) - -# ============================================================================= -# def main1(): -# evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images" -# text1 = "one2n_Error.txt" -# text2 = "one2SN_Error.txt" -# events = [] -# text = (text1, text2) -# for txt in text: -# txtfile = os.path.join(evtpaths, txt) -# with open(txtfile, "r") as f: -# lines = f.readlines() -# for i, line in enumerate(lines): -# line = line.strip() -# if line: -# fpath=os.path.join(evtpaths, line) -# events.append(fpath) -# -# -# events = list(set(events)) -# -# '''定义当前事件存储地址及生成相应文件件''' -# resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result" -# # eventDataPath = os.path.join(resultPath, "evtobjs") -# # subimgPath = os.path.join(resultPath, "subimgs") -# # imagePath = os.path.join(resultPath, "image") -# -# # if not os.path.exists(eventDataPath): -# # os.makedirs(eventDataPath) -# # if not os.path.exists(subimgPath): -# # os.makedirs(subimgPath) -# # if not os.path.exists(imagePath): -# # os.makedirs(imagePath) -# -# -# for evtpath in events: -# event = ShoppingEvent(evtpath) -# -# -# evtname = os.path.basename(evtpath) -# subimgpath = os.path.join(resultPath, f"{evtname}", "subimg") -# imgspath = os.path.join(resultPath, f"{evtname}", "imgs") -# if not os.path.exists(subimgpath): -# os.makedirs(subimgpath) -# if not os.path.exists(imgspath): -# os.makedirs(imgspath) -# -# subimgpairs = event.save_event_subimg(subimgpath) -# -# for subimgName, subimg in subimgpairs: -# spath = os.path.join(subimgpath, subimgName) -# cv2.imwrite(spath, subimg) -# -# imgpairs = event.plot_save_image(imgspath) -# for imgname, img in imgpairs: -# spath = os.path.join(imgspath, imgname) -# cv2.imwrite(spath, img) -# -# ============================================================================= + if __name__ == "__main__": diff --git a/说明文档.txt b/说明文档.txt index 37d2026..5e2cfcc 100644 --- a/说明文档.txt +++ b/说明文档.txt @@ -155,58 +155,15 @@ stdfeat_infer(imgPath, featPath, bcdSet=None) 功能: 对 imgPath 中图像进行特征提取,生成只有一个key值的字典。 {barcode: features},features.shape=(nsample, 256),并保存至 featPath 中 - - - one2n_contrast.py - 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: (错误匹配时的相似度) + + + onsite_contrast_pr.py + one2one_pr() + 现场试验输出数据的性能评估,输出1:1, 1:SN, 1:n的PR曲线和相似度直方图分布。 - 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() + test_compare() + 适用于202410前数据保存版本的,需调用 OneToOneCompare.txt one2one_contrast.py @@ -258,7 +215,20 @@ ft16_to_uint8() - + one2n_contrast.py + 执行1:n共需要3步: + '''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 ''' + # gen_eventdict(sourcePath) + + '''2. 读取时间字典 ''' + evtDicts = read_eventdict(eventDataPath) + + + '''3. 1:n 比对事件评估 ''' + + + + @@ -266,26 +236,67 @@ - one2one_onsite.py - 现场试验输出数据的 1:1 性能评估; - 适用于202410前数据保存版本的,需调用 OneToOneCompare.txt - - 标准特征向量生成 - std_sample_path:图像样本的存储地址 - std_barcode_path:对 std_sample_path 中文件列表进行遍历,形成{barcode: 图像样本地址}形式字典并进行存储 - std_feature_path:调用 inference_image(), 对每一个barcode,生成字典并进行存储 - - genfeats.py - genfeatures(imgpath, bcdpath, featpath) - 功能:生成标准特征向量的字典, 并保存为: barcode.pickle - keys: barcode, imgpaths, feats_ft32, feats_ft16, feats_uint8 - 参数: - (1) imgpath:图像样本的存储地址 - (2) bcdpath:对 imgpath 中文件列表进行遍历,形成{barcode: 图像样本地址}形式字典并进行存储 - (3) featpath:调用 inference_image(), 对每一个barcode,生成字典并进行存储 + 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()