# -*- 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 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] errpairs.append((seqdir, events[idxmax], events[index])) err_similarity.append(max(similarity)) return errpairs, corrpairs, err_similarity, correct_similarity # def contrast_analysis(del_barcode_file, basepath, savepath, saveimgs=False): def get_relative_paths(del_barcode_file, basepath, savepath, saveimgs=False): ''' del_barcode_file: deletedBarcode.txt 格式的 1:n 数据结果文件 returnGoods.txt格式数据文件不需要调用该函数,one2n_old() 函数返回的 errpairs 中元素为三元元组(取出,放入, 错误匹配) ''' relative_paths = [] '''1. 读取 deletedBarcode 文件 ''' all_list = read_deletedBarcode_file(del_barcode_file) '''2. 算法性能评估,并输出 (取出,删除, 错误匹配) 对 ''' errpairs, corrpairs, _, _ = one2n_old(all_list) '''3. 构造事件组合(取出,放入并删除, 错误匹配) 对应路径 ''' for errpair in errpairs: GetoutPath, InputPath, ErrorPath = get_contrast_paths(errpair, basepath) relative_paths.append((GetoutPath, InputPath, ErrorPath)) '''3. 获取 (取出,放入并删除, 错误匹配) 对应路径,保存相应轨迹图像''' if saveimgs: save_tracking_imgpairs(errpair, basepath, savepath) return relative_paths def one2n_test(): fpath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\other' fpath = r'\\192.168.1.28\share\测试_202406\1030\images' savepath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\illustration' if not os.path.exists(savepath): os.mkdir(savepath) 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 FileFormat = {} BarLists, blists = {}, [] for pth in filepaths: file = str(Path(pth).stem) if file.find('deletedBarcode')>=0: FileFormat[file] = 'deletedBarcode' blist = read_deletedBarcode_file(pth) elif file.find('returnGoods')>=0: FileFormat[file] = 'returnGoods' blist = read_returnGoods_file(pth) else: return BarLists.update({file: blist}) blists.extend(blist) BarLists.update({file: blist}) BarLists.update({"Total": blists}) for file, blist in BarLists.items(): if FileFormat[file] == 'deletedBarcode': _, _, err_similarity, correct_similarity = one2n_old(blist) elif FileFormat[file] == 'returnGoods': _, _, err_similarity, correct_similarity = one2n_new(blist) else: _, _, err_similarity, correct_similarity = one2n_old(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() def test_getreltpath(): ''' 适用于:deletedBarcode.txt,不适用于:returnGoods.txt ''' del_barcode_file = r'\\192.168.1.28\share\测试_202406\709\deletedBarcode.txt' basepath = r'\\192.168.1.28\share\测试_202406\709' # del_barcode_file = r'\\192.168.1.28\share\测试_202406\1030\images\returnGoods.txt' # basepath = r'\\192.168.1.28\share\测试_202406\1030\images' savepath = r'D:\contrast\dataset\result' saveimgs = True try: relative_path = get_relative_paths(del_barcode_file, basepath, savepath, saveimgs) except Exception as e: print(f'Error Type: {e}') if __name__ == '__main__': one2n_test() # test_getreltpath()