20241218
This commit is contained in:
@ -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}")
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
||||
if camID=='0':
|
||||
imgs_0.append(img)
|
||||
frmIDs_0.append(frmID)
|
||||
if camID=='1':
|
||||
imgs_1.append(img)
|
||||
frmIDs_1.append(frmID)
|
||||
# bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479"
|
||||
source_path = os.path.join(evtpath, bname)
|
||||
|
||||
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 ]
|
||||
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
|
||||
if os.path.isfile(pickpath): continue
|
||||
|
||||
return imgs_0, imgs_1
|
||||
try:
|
||||
event = ShoppingEvent(source_path, stype)
|
||||
# save_data(event, resultPath)
|
||||
|
||||
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 read_eventdict(eventDataPath):
|
||||
evtDict = {}
|
||||
for filename in os.listdir(eventDataPath):
|
||||
evtname, ext = os.path.splitext(filename)
|
||||
if ext != ".pickle": continue
|
||||
|
||||
evtpath = os.path.join(eventDataPath, filename)
|
||||
with open(evtpath, 'rb') as f:
|
||||
evtdata = pickle.load(f)
|
||||
evtDict[evtname] = evtdata
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 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
|
||||
# =============================================================================
|
||||
return evtDict
|
||||
|
||||
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
|
||||
def one2n_pr(evtDicts):
|
||||
tpevents, fnevents, fpevents, tnevents = [], [], [], []
|
||||
tpsimi, fnsimi, tnsimi, fpsimi = [], [], [], []
|
||||
errorFile_one2n = []
|
||||
for evtname, event in evtDicts.items():
|
||||
evt_names, evt_barcodes, evt_similars, evt_types = [], [], [], []
|
||||
|
||||
for ndict in event.one2n:
|
||||
nname = ndict["event"]
|
||||
barcode = ndict["barcode"]
|
||||
similar = ndict["similar"]
|
||||
typee = ndict["type"].strip()
|
||||
|
||||
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:
|
||||
error_match = ''
|
||||
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)
|
||||
|
||||
evt_names.append(nname)
|
||||
evt_barcodes.append(barcode)
|
||||
evt_similars.append(simi_mean)
|
||||
evt_types.append(typee)
|
||||
|
||||
|
||||
getoutpath, inputpath, errorpath = '', '', ''
|
||||
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:
|
||||
|
||||
day, hms = getout_fold.strip('_').split('-')
|
||||
maxsim = evt_similars[evt_similars.index(max(evt_similars))]
|
||||
for i in range(len(evt_names)):
|
||||
bcd, simi = evt_barcodes[i], evt_similars[i]
|
||||
|
||||
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)<int(hms):
|
||||
input_folds.append(pathname)
|
||||
times.append(int(hms1))
|
||||
|
||||
if day1==day and len(error_match) and infold[1]==error_match and int(hms1)<int(hms):
|
||||
errmatch_folds.append(pathname)
|
||||
errmatch_times.append(int(hms1))
|
||||
|
||||
''' 根据时间排序,选择离取出操作最近时间的文件夹,
|
||||
作为取出操作应正确匹配的放入操作所对应的文件夹 '''
|
||||
if len(input_folds):
|
||||
indice = np.argsort(np.array(times))
|
||||
input_fold = input_folds[indice[-1]]
|
||||
|
||||
inputpath = os.path.join(basepath, input_fold)
|
||||
|
||||
|
||||
'''取出操作错误匹配的放入操作对应的文件夹'''
|
||||
if len(errmatch_folds):
|
||||
indice = np.argsort(np.array(errmatch_times))
|
||||
errmatch_fold = errmatch_folds[indice[-1]]
|
||||
|
||||
errorpath = os.path.join(basepath, errmatch_fold)
|
||||
|
||||
|
||||
|
||||
'''放入事件文件夹地址、取出事件文件夹地址'''
|
||||
getoutpath = os.path.join(basepath, getout_fold)
|
||||
|
||||
|
||||
return getoutpath, inputpath, errorpath
|
||||
|
||||
|
||||
def save_tracking_imgpairs(pairs, savepath):
|
||||
'''
|
||||
pairs: 匹配事件对
|
||||
savepath: 保存的目标文件夹
|
||||
'''
|
||||
def get_event_path(evtpath):
|
||||
basepath, eventname = os.path.split(evtpath)
|
||||
evt_path = ''
|
||||
for filename in os.listdir(basepath):
|
||||
if filename.find(eventname)==0:
|
||||
evt_path = os.path.join(basepath, filename)
|
||||
break
|
||||
return evt_path
|
||||
|
||||
getoutpath = get_event_path(pairs[0])
|
||||
inputpath = get_event_path(pairs[1])
|
||||
|
||||
if len(pairs) == 3:
|
||||
errorpath = get_event_path(pairs[2])
|
||||
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:
|
||||
errorpath = ''
|
||||
|
||||
''' 1. 读取放入、取出事件对应的 Yolo输入的前后摄图像,0:后摄,1:前摄
|
||||
2. 读取放入、取出事件对应的 tracking 输出:boxes, feats
|
||||
3. boxes绘制并保存图像序列
|
||||
4. 截取并保存轨迹子图
|
||||
'''
|
||||
if len(getoutpath):
|
||||
imgs_getout_0, imgs_getout_1 = read_tracking_imgs(getoutpath)
|
||||
|
||||
getout_data_0 = os.path.join(getoutpath, '0_tracking_output.data')
|
||||
getout_data_1 = os.path.join(getoutpath, '1_tracking_output.data')
|
||||
boxes_output_0, feats_output_0 = read_tracking_output(getout_data_0)
|
||||
boxes_output_1, feats_output_1 = read_tracking_output(getout_data_1)
|
||||
ImgsGetout_0 = draw_tracking_boxes(imgs_getout_0, boxes_output_0)
|
||||
ImgsGetout_1 = draw_tracking_boxes(imgs_getout_1, boxes_output_1)
|
||||
|
||||
SubimgsGetout_0 = get_subimgs(imgs_getout_0, boxes_output_0)
|
||||
SubimgsGetout_1 = get_subimgs(imgs_getout_1, boxes_output_1)
|
||||
|
||||
savedir = os.path.basename(getoutpath)
|
||||
|
||||
if len(inputpath):
|
||||
imgs_input_0, imgs_input_1 = read_tracking_imgs(inputpath)
|
||||
|
||||
input_data_0 = os.path.join(inputpath, '0_tracking_output.data')
|
||||
input_data_1 = os.path.join(inputpath, '1_tracking_output.data')
|
||||
boxes_input_0, feats_input_0 = read_tracking_output(input_data_0)
|
||||
boxes_input_1, feats_input_1 = read_tracking_output(input_data_1)
|
||||
ImgsInput_0 = draw_tracking_boxes(imgs_input_0, boxes_input_0)
|
||||
ImgsInput_1 = draw_tracking_boxes(imgs_input_1, boxes_input_1)
|
||||
|
||||
SubimgsInput_0 = get_subimgs(imgs_input_0, boxes_input_0)
|
||||
SubimgsInput_1 = get_subimgs(imgs_input_1, boxes_input_1)
|
||||
|
||||
savedir = savedir + '+' + os.path.basename(inputpath)
|
||||
|
||||
if len(errorpath):
|
||||
imgs_error_0, imgs_error_1 = read_tracking_imgs(errorpath)
|
||||
|
||||
error_data_0 = os.path.join(errorpath, '0_tracking_output.data')
|
||||
error_data_1 = os.path.join(errorpath, '1_tracking_output.data')
|
||||
boxes_error_0, feats_error_0 = read_tracking_output(error_data_0)
|
||||
boxes_error_1, feats_error_1 = read_tracking_output(error_data_1)
|
||||
ImgsError_0 = draw_tracking_boxes(imgs_error_0, boxes_error_0)
|
||||
ImgsError_1 = draw_tracking_boxes(imgs_error_1, boxes_error_1)
|
||||
|
||||
SubimgsError_0 = get_subimgs(imgs_error_0, boxes_error_0)
|
||||
SubimgsError_1 = get_subimgs(imgs_error_0, boxes_error_0)
|
||||
|
||||
savedir = savedir + '+' + os.path.basename(errorpath)
|
||||
|
||||
''' savepath\pairs\savedir\eventpairs\保存画框后的图像序列 '''
|
||||
entpairs = os.path.join(savepath, 'pairs', savedir, 'eventpairs')
|
||||
if not os.path.exists(entpairs):
|
||||
os.makedirs(entpairs)
|
||||
for fid, img in ImgsInput_0:
|
||||
imgpath = os.path.join(entpairs, f'input_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsInput_1:
|
||||
imgpath = os.path.join(entpairs, f'input_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsGetout_0:
|
||||
imgpath = os.path.join(entpairs, f'getout_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsGetout_1:
|
||||
imgpath = os.path.join(entpairs, f'getout_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
if 'ImgsError_0' in vars() and 'ImgsError_1' in vars():
|
||||
for fid, img in ImgsError_0:
|
||||
imgpath = os.path.join(entpairs, f'errMatch_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsError_1:
|
||||
imgpath = os.path.join(entpairs, f'errMatch_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
|
||||
''' savepath\pairs\savedir\subimgpairs\保存轨迹子图 '''
|
||||
subimgpairs = os.path.join(savepath, 'pairs', savedir, 'subimgpairs')
|
||||
if not os.path.exists(subimgpairs):
|
||||
os.makedirs(subimgpairs)
|
||||
for fid, bid, img in SubimgsGetout_0:
|
||||
imgpath = os.path.join(subimgpairs, f'getout_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsGetout_1:
|
||||
imgpath = os.path.join(subimgpairs, f'getout_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsInput_0:
|
||||
imgpath = os.path.join(subimgpairs, f'input_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsInput_1:
|
||||
imgpath = os.path.join(subimgpairs, f'input_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
if 'SubimgsError_0' in vars() and 'SubimgsError_1' in vars():
|
||||
for fid, bid, img in SubimgsError_0:
|
||||
imgpath = os.path.join(subimgpairs, f'errMatch_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsError_1:
|
||||
imgpath = os.path.join(subimgpairs, f'errMatch_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
|
||||
|
||||
def one2n_deleted(all_list):
|
||||
corrpairs, errpairs, correct_similarity, err_similarity = [], [], [], []
|
||||
for s_list in all_list:
|
||||
seqdir = s_list['SeqDir'].strip()
|
||||
delete = s_list['Deleted'].strip()
|
||||
barcodes = [s.strip() for s in s_list['barcode']]
|
||||
|
||||
|
||||
similarity_comp, similarity_front = [], []
|
||||
for simil in s_list['similarity']:
|
||||
ss = [float(s.strip()) for s in simil.split(',')]
|
||||
|
||||
similarity_comp.append(ss[0])
|
||||
if len(ss)==3:
|
||||
similarity_front.append(ss[2])
|
||||
|
||||
if len(similarity_front):
|
||||
similarity = [s for s in similarity_front]
|
||||
else:
|
||||
similarity = [s for s in similarity_comp]
|
||||
|
||||
|
||||
index = similarity.index(max(similarity))
|
||||
matched_barcode = barcodes[index]
|
||||
if matched_barcode == delete:
|
||||
corrpairs.append((seqdir, delete))
|
||||
correct_similarity.append(max(similarity))
|
||||
else:
|
||||
errpairs.append((seqdir, delete, matched_barcode))
|
||||
err_similarity.append(max(similarity))
|
||||
|
||||
|
||||
return corrpairs, errpairs, correct_similarity, err_similarity
|
||||
errorFile_one2n.append(evtname)
|
||||
|
||||
|
||||
|
||||
def one2n_return(all_list):
|
||||
corrpairs, corr_similarity, errpairs, err_similarity = [], [], [], []
|
||||
''' 1:n 数据存储,需根据相似度排序'''
|
||||
PPrecise, PRecall = [], []
|
||||
NPrecise, NRecall = [], []
|
||||
|
||||
for s_list in all_list:
|
||||
seqdir = s_list['SeqDir'].strip()
|
||||
delete = s_list['Deleted'].strip()
|
||||
barcodes = [s.strip() for s in s_list['barcode']]
|
||||
events = [s.strip() for s in s_list['event']]
|
||||
types = [s.strip() for s in s_list['type']]
|
||||
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)
|
||||
|
||||
## =================== 读入相似度值
|
||||
similarity_comp, similarity_front = [], []
|
||||
for simil in s_list['similarity']:
|
||||
ss = [float(s.strip()) for s in simil.split(',')]
|
||||
|
||||
similarity_comp.append(ss[0])
|
||||
if len(ss)==3:
|
||||
similarity_front.append(ss[2])
|
||||
|
||||
if len(similarity_front):
|
||||
similarity = [s for s in similarity_front]
|
||||
else:
|
||||
similarity = [s for s in similarity_comp]
|
||||
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))
|
||||
|
||||
|
||||
index = similarity.index(max(similarity))
|
||||
matched_barcode = barcodes[index]
|
||||
if matched_barcode == delete:
|
||||
corrpairs.append((seqdir, events[index]))
|
||||
corr_similarity.append(max(similarity))
|
||||
else:
|
||||
idx = [i for i, name in enumerate(events) if name.split('_')[-1] == delete]
|
||||
idxmax, simimax = -1, -1
|
||||
# idxmax, simimax = k, similarity[k] for k in idx if similarity[k] > simimax
|
||||
for k in idx:
|
||||
if similarity[k] > simimax:
|
||||
idxmax = k
|
||||
simimax = similarity[k]
|
||||
if idxmax>-1:
|
||||
input_event = events[idxmax]
|
||||
else:
|
||||
input_event = ''
|
||||
'''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()
|
||||
|
||||
errpairs.append((seqdir, input_event, events[index]))
|
||||
err_similarity.append(max(similarity))
|
||||
return fpevents
|
||||
|
||||
return corrpairs, errpairs, corr_similarity, err_similarity
|
||||
def main():
|
||||
|
||||
'''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 '''
|
||||
# gen_eventdict(sourcePath)
|
||||
|
||||
'''2. 读取时间字典 '''
|
||||
evtDicts = read_eventdict(eventDataPath)
|
||||
|
||||
|
||||
def test_rpath_deleted():
|
||||
'''deletedBarcode.txt 格式的 1:n 数据结果文件, returnGoods.txt格式数据文件不需要调用该函数'''
|
||||
'''3. 1:n 比对事件评估 '''
|
||||
fpevents = one2n_pr(evtDicts)
|
||||
|
||||
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
|
||||
fpErrFile = str(Path(resultPath).joinpath("one2n_Error.txt"))
|
||||
with open(fpErrFile, "w") as file:
|
||||
for item in fpevents:
|
||||
file.write(item + "\n")
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
|
498
contrast/one2n_contrast_old.py
Normal file
498
contrast/one2n_contrast_old.py
Normal file
@ -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)<int(hms):
|
||||
input_folds.append(pathname)
|
||||
times.append(int(hms1))
|
||||
|
||||
if day1==day and len(error_match) and infold[1]==error_match and int(hms1)<int(hms):
|
||||
errmatch_folds.append(pathname)
|
||||
errmatch_times.append(int(hms1))
|
||||
|
||||
''' 根据时间排序,选择离取出操作最近时间的文件夹,
|
||||
作为取出操作应正确匹配的放入操作所对应的文件夹 '''
|
||||
if len(input_folds):
|
||||
indice = np.argsort(np.array(times))
|
||||
input_fold = input_folds[indice[-1]]
|
||||
|
||||
inputpath = os.path.join(basepath, input_fold)
|
||||
|
||||
|
||||
'''取出操作错误匹配的放入操作对应的文件夹'''
|
||||
if len(errmatch_folds):
|
||||
indice = np.argsort(np.array(errmatch_times))
|
||||
errmatch_fold = errmatch_folds[indice[-1]]
|
||||
|
||||
errorpath = os.path.join(basepath, errmatch_fold)
|
||||
|
||||
|
||||
|
||||
'''放入事件文件夹地址、取出事件文件夹地址'''
|
||||
getoutpath = os.path.join(basepath, getout_fold)
|
||||
|
||||
|
||||
return getoutpath, inputpath, errorpath
|
||||
|
||||
|
||||
def save_tracking_imgpairs(pairs, savepath):
|
||||
'''
|
||||
pairs: 匹配事件对
|
||||
savepath: 保存的目标文件夹
|
||||
'''
|
||||
def get_event_path(evtpath):
|
||||
basepath, eventname = os.path.split(evtpath)
|
||||
evt_path = ''
|
||||
for filename in os.listdir(basepath):
|
||||
if filename.find(eventname)==0:
|
||||
evt_path = os.path.join(basepath, filename)
|
||||
break
|
||||
return evt_path
|
||||
|
||||
getoutpath = get_event_path(pairs[0])
|
||||
inputpath = get_event_path(pairs[1])
|
||||
|
||||
if len(pairs) == 3:
|
||||
errorpath = get_event_path(pairs[2])
|
||||
else:
|
||||
errorpath = ''
|
||||
|
||||
''' 1. 读取放入、取出事件对应的 Yolo输入的前后摄图像,0:后摄,1:前摄
|
||||
2. 读取放入、取出事件对应的 tracking 输出:boxes, feats
|
||||
3. boxes绘制并保存图像序列
|
||||
4. 截取并保存轨迹子图
|
||||
'''
|
||||
if len(getoutpath):
|
||||
imgs_getout_0, imgs_getout_1 = read_tracking_imgs(getoutpath)
|
||||
|
||||
getout_data_0 = os.path.join(getoutpath, '0_tracking_output.data')
|
||||
getout_data_1 = os.path.join(getoutpath, '1_tracking_output.data')
|
||||
boxes_output_0, feats_output_0 = read_tracking_output(getout_data_0)
|
||||
boxes_output_1, feats_output_1 = read_tracking_output(getout_data_1)
|
||||
ImgsGetout_0 = draw_tracking_boxes(imgs_getout_0, boxes_output_0)
|
||||
ImgsGetout_1 = draw_tracking_boxes(imgs_getout_1, boxes_output_1)
|
||||
|
||||
SubimgsGetout_0 = get_subimgs(imgs_getout_0, boxes_output_0)
|
||||
SubimgsGetout_1 = get_subimgs(imgs_getout_1, boxes_output_1)
|
||||
|
||||
savedir = os.path.basename(getoutpath)
|
||||
|
||||
if len(inputpath):
|
||||
imgs_input_0, imgs_input_1 = read_tracking_imgs(inputpath)
|
||||
|
||||
input_data_0 = os.path.join(inputpath, '0_tracking_output.data')
|
||||
input_data_1 = os.path.join(inputpath, '1_tracking_output.data')
|
||||
boxes_input_0, feats_input_0 = read_tracking_output(input_data_0)
|
||||
boxes_input_1, feats_input_1 = read_tracking_output(input_data_1)
|
||||
ImgsInput_0 = draw_tracking_boxes(imgs_input_0, boxes_input_0)
|
||||
ImgsInput_1 = draw_tracking_boxes(imgs_input_1, boxes_input_1)
|
||||
|
||||
SubimgsInput_0 = get_subimgs(imgs_input_0, boxes_input_0)
|
||||
SubimgsInput_1 = get_subimgs(imgs_input_1, boxes_input_1)
|
||||
|
||||
savedir = savedir + '+' + os.path.basename(inputpath)
|
||||
|
||||
if len(errorpath):
|
||||
imgs_error_0, imgs_error_1 = read_tracking_imgs(errorpath)
|
||||
|
||||
error_data_0 = os.path.join(errorpath, '0_tracking_output.data')
|
||||
error_data_1 = os.path.join(errorpath, '1_tracking_output.data')
|
||||
boxes_error_0, feats_error_0 = read_tracking_output(error_data_0)
|
||||
boxes_error_1, feats_error_1 = read_tracking_output(error_data_1)
|
||||
ImgsError_0 = draw_tracking_boxes(imgs_error_0, boxes_error_0)
|
||||
ImgsError_1 = draw_tracking_boxes(imgs_error_1, boxes_error_1)
|
||||
|
||||
SubimgsError_0 = get_subimgs(imgs_error_0, boxes_error_0)
|
||||
SubimgsError_1 = get_subimgs(imgs_error_0, boxes_error_0)
|
||||
|
||||
savedir = savedir + '+' + os.path.basename(errorpath)
|
||||
|
||||
''' savepath\pairs\savedir\eventpairs\保存画框后的图像序列 '''
|
||||
entpairs = os.path.join(savepath, 'pairs', savedir, 'eventpairs')
|
||||
if not os.path.exists(entpairs):
|
||||
os.makedirs(entpairs)
|
||||
for fid, img in ImgsInput_0:
|
||||
imgpath = os.path.join(entpairs, f'input_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsInput_1:
|
||||
imgpath = os.path.join(entpairs, f'input_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsGetout_0:
|
||||
imgpath = os.path.join(entpairs, f'getout_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsGetout_1:
|
||||
imgpath = os.path.join(entpairs, f'getout_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
if 'ImgsError_0' in vars() and 'ImgsError_1' in vars():
|
||||
for fid, img in ImgsError_0:
|
||||
imgpath = os.path.join(entpairs, f'errMatch_0_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, img in ImgsError_1:
|
||||
imgpath = os.path.join(entpairs, f'errMatch_1_{fid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
|
||||
''' savepath\pairs\savedir\subimgpairs\保存轨迹子图 '''
|
||||
subimgpairs = os.path.join(savepath, 'pairs', savedir, 'subimgpairs')
|
||||
if not os.path.exists(subimgpairs):
|
||||
os.makedirs(subimgpairs)
|
||||
for fid, bid, img in SubimgsGetout_0:
|
||||
imgpath = os.path.join(subimgpairs, f'getout_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsGetout_1:
|
||||
imgpath = os.path.join(subimgpairs, f'getout_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsInput_0:
|
||||
imgpath = os.path.join(subimgpairs, f'input_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsInput_1:
|
||||
imgpath = os.path.join(subimgpairs, f'input_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
if 'SubimgsError_0' in vars() and 'SubimgsError_1' in vars():
|
||||
for fid, bid, img in SubimgsError_0:
|
||||
imgpath = os.path.join(subimgpairs, f'errMatch_0_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
for fid, bid, img in SubimgsError_1:
|
||||
imgpath = os.path.join(subimgpairs, f'errMatch_1_{fid}_{bid}.png')
|
||||
cv2.imwrite(imgpath, img)
|
||||
|
||||
|
||||
def one2n_deleted(all_list):
|
||||
corrpairs, errpairs, correct_similarity, err_similarity = [], [], [], []
|
||||
for s_list in all_list:
|
||||
seqdir = s_list['SeqDir'].strip()
|
||||
delete = s_list['Deleted'].strip()
|
||||
barcodes = [s.strip() for s in s_list['barcode']]
|
||||
|
||||
|
||||
similarity_comp, similarity_front = [], []
|
||||
for simil in s_list['similarity']:
|
||||
ss = [float(s.strip()) for s in simil.split(',')]
|
||||
|
||||
similarity_comp.append(ss[0])
|
||||
if len(ss)==3:
|
||||
similarity_front.append(ss[2])
|
||||
|
||||
if len(similarity_front):
|
||||
similarity = [s for s in similarity_front]
|
||||
else:
|
||||
similarity = [s for s in similarity_comp]
|
||||
|
||||
|
||||
index = similarity.index(max(similarity))
|
||||
matched_barcode = barcodes[index]
|
||||
if matched_barcode == delete:
|
||||
corrpairs.append((seqdir, delete))
|
||||
correct_similarity.append(max(similarity))
|
||||
else:
|
||||
errpairs.append((seqdir, delete, matched_barcode))
|
||||
err_similarity.append(max(similarity))
|
||||
|
||||
|
||||
return corrpairs, errpairs, correct_similarity, err_similarity
|
||||
|
||||
|
||||
|
||||
def one2n_return(all_list):
|
||||
corrpairs, corr_similarity, errpairs, err_similarity = [], [], [], []
|
||||
|
||||
for s_list in all_list:
|
||||
seqdir = s_list['SeqDir'].strip()
|
||||
delete = s_list['Deleted'].strip()
|
||||
barcodes = [s.strip() for s in s_list['barcode']]
|
||||
events = [s.strip() for s in s_list['event']]
|
||||
types = [s.strip() for s in s_list['type']]
|
||||
|
||||
## =================== 读入相似度值
|
||||
similarity_comp, similarity_front = [], []
|
||||
for simil in s_list['similarity']:
|
||||
ss = [float(s.strip()) for s in simil.split(',')]
|
||||
|
||||
similarity_comp.append(ss[0])
|
||||
if len(ss)==3:
|
||||
similarity_front.append(ss[2])
|
||||
|
||||
if len(similarity_front):
|
||||
similarity = [s for s in similarity_front]
|
||||
else:
|
||||
similarity = [s for s in similarity_comp]
|
||||
|
||||
|
||||
index = similarity.index(max(similarity))
|
||||
matched_barcode = barcodes[index]
|
||||
if matched_barcode == delete:
|
||||
corrpairs.append((seqdir, events[index]))
|
||||
corr_similarity.append(max(similarity))
|
||||
else:
|
||||
idx = [i for i, name in enumerate(events) if name.split('_')[-1] == delete]
|
||||
idxmax, simimax = -1, -1
|
||||
# idxmax, simimax = k, similarity[k] for k in idx if similarity[k] > 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)
|
||||
|
||||
|
@ -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_ = [], [], []
|
||||
@ -291,42 +211,6 @@ def one2one_simi():
|
||||
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:
|
||||
# stdImgpath = stdDict[stdbcd]["imgpaths"]
|
||||
@ -441,15 +325,12 @@ def compute_precise_recall(rltdata):
|
||||
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):
|
||||
@ -487,8 +372,8 @@ def test_one2one():
|
||||
bcdList.append(evt[-1])
|
||||
event_spath.append(os.path.join(evtpath, evtname))
|
||||
|
||||
bcdSet = set(bcdList)
|
||||
'''==== 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)
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -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):
|
||||
@ -412,12 +444,8 @@ class ShoppingEvent:
|
||||
|
||||
|
||||
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')
|
||||
@ -428,64 +456,6 @@ def main():
|
||||
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# 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__":
|
||||
|
139
说明文档.txt
139
说明文档.txt
@ -157,56 +157,13 @@
|
||||
{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,6 +215,16 @@
|
||||
|
||||
ft16_to_uint8()
|
||||
|
||||
one2n_contrast.py
|
||||
执行1:n共需要3步:
|
||||
'''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 '''
|
||||
# gen_eventdict(sourcePath)
|
||||
|
||||
'''2. 读取时间字典 '''
|
||||
evtDicts = read_eventdict(eventDataPath)
|
||||
|
||||
|
||||
'''3. 1:n 比对事件评估 '''
|
||||
|
||||
|
||||
|
||||
@ -266,25 +233,69 @@
|
||||
|
||||
|
||||
|
||||
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
|
||||
|
Reference in New Issue
Block a user