20250313
This commit is contained in:
Binary file not shown.
Binary file not shown.
@ -16,11 +16,6 @@ from feat_extract.inference import FeatsInterface #, inference_image
|
||||
|
||||
Encoder = FeatsInterface(conf)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
imgpaths = r"D:\全实时\202502\result\Yolos_Tracking\20250228-160049-188_6921168558018_6921168558018\a"
|
||||
featDict = {}
|
||||
|
@ -191,10 +191,19 @@ def stdfeat_infer(imgPath, featPath, bcdSet=None):
|
||||
return
|
||||
|
||||
|
||||
def gen_bcd_features(imgpath, bcdpath, featpath, bcdSet=None):
|
||||
def gen_bcd_features(imgpath, bcdpath, featpath, eventSourcePath):
|
||||
''' 生成标准特征集 '''
|
||||
'''1. 提取 imgpath 中样本地址,生成字典{barcode: [imgpath1, imgpath1, ...]}
|
||||
并存储于: bcdpath, 格式为 barcode.pickle'''
|
||||
|
||||
bcdList = []
|
||||
for evtname in os.listdir(eventSourcePath):
|
||||
bname, ext = os.path.splitext(evtname)
|
||||
evt = bname.split('_')
|
||||
if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10:
|
||||
bcdList.append(evt[-1])
|
||||
|
||||
bcdSet = set(bcdList)
|
||||
get_std_barcodeDict(imgpath, bcdpath, bcdSet)
|
||||
|
||||
'''2. 特征提取,并保存至文件夹 featpath 中,也根据 bcdSet 交集执行'''
|
||||
|
@ -14,49 +14,47 @@ from scipy.spatial.distance import cdist
|
||||
from utils.event import ShoppingEvent
|
||||
|
||||
|
||||
def init_eventdict(sourcePath, stype="data"):
|
||||
def init_eventDict(sourcePath, eventDataPath, stype="data"):
|
||||
'''stype: str,
|
||||
'source': 由 videos 或 images 生成的 pickle 文件
|
||||
'data': 从 data 文件中读取的现场运行数据
|
||||
"realtime": 全实时数据,从 data 文件中读取的现场运行数据
|
||||
'''
|
||||
|
||||
sourcePath:事件文件夹,事件类型包含2种:
|
||||
(1) pipeline生成的 pickle 文件
|
||||
(2) 直接采集的事件文件夹
|
||||
'''
|
||||
k, errEvents = 0, []
|
||||
for bname in os.listdir(sourcePath):
|
||||
# bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479"
|
||||
for evtname in os.listdir(sourcePath):
|
||||
bname, ext = os.path.splitext(evtname)
|
||||
source_path = os.path.join(sourcePath, evtname)
|
||||
|
||||
source_path = os.path.join(sourcePath, bname)
|
||||
if stype=="source" and not os.path.isfile(source_path): continue
|
||||
if stype=="source" and ext not in ['.pkl', '.pickle']: continue
|
||||
if stype=="data" and os.path.isfile(source_path): continue
|
||||
if stype=="realtime" and os.path.isfile(source_path): continue
|
||||
|
||||
if os.path.isdir(source_path):
|
||||
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
|
||||
else:
|
||||
pickpath = os.path.join(eventDataPath, bname)
|
||||
|
||||
if os.path.isfile(pickpath):
|
||||
continue
|
||||
evt = bname.split('_')
|
||||
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
|
||||
if not condt: continue
|
||||
|
||||
evt = os.path.splitext(os.path.split(pickpath)[-1])[0].split('_')
|
||||
cont = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
|
||||
if not cont:
|
||||
continue
|
||||
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
|
||||
if os.path.isfile(pickpath): continue
|
||||
|
||||
# event = ShoppingEvent(source_path, stype)
|
||||
try:
|
||||
event = ShoppingEvent(source_path, stype)
|
||||
with open(pickpath, 'wb') as f:
|
||||
pickle.dump(event, f)
|
||||
print(bname)
|
||||
print(evtname)
|
||||
except Exception as e:
|
||||
errEvents.append(source_path)
|
||||
print(f"Error: {bname}, {e}")
|
||||
print(f"Error: {evtname}, {e}")
|
||||
# k += 1
|
||||
# if k==1:
|
||||
# break
|
||||
|
||||
errfile = os.path.join(resultPath, 'error_events.txt')
|
||||
with open(errfile, 'a', encoding='utf-8') as f:
|
||||
|
||||
errfile = Path(eventDataPath).parent / 'error_events.txt'
|
||||
with open(str(errfile), 'a', encoding='utf-8') as f:
|
||||
for line in errEvents:
|
||||
f.write(line + '\n')
|
||||
|
||||
@ -185,7 +183,7 @@ def one2n_pr(evtDicts, pattern=1):
|
||||
elif bcd!=event.barcode and simi!=maxsim:
|
||||
tnsimi.append(simi)
|
||||
tnevents.append(evtname)
|
||||
elif bcd!=event.barcode and simi==maxsim:
|
||||
elif bcd!=event.barcode and simi==maxsim and event.barcode in evt_barcodes:
|
||||
fpsimi.append(simi)
|
||||
fpevents.append(evtname)
|
||||
else:
|
||||
@ -216,7 +214,11 @@ def one2n_pr(evtDicts, pattern=1):
|
||||
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_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
|
||||
ax.set_title('1:n Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(one2nFile)}")
|
||||
ax.legend()
|
||||
@ -241,7 +243,7 @@ def one2n_pr(evtDicts, pattern=1):
|
||||
|
||||
def main():
|
||||
'''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 '''
|
||||
init_eventdict(eventSourcePath, stype="realtime") # 'source', 'data', 'realtime'
|
||||
init_eventDict(eventSourcePath, eventDataPath, stype="realtime") # 'source', 'data', 'realtime'
|
||||
|
||||
# for pfile in os.listdir(eventDataPath):
|
||||
# evt = os.path.splitext(pfile)[0].split('_')
|
||||
@ -264,7 +266,7 @@ def main():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-2-27"
|
||||
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-3-4_2"
|
||||
resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\testing"
|
||||
|
||||
eventDataPath = os.path.join(resultPath, "evtobjs_wang")
|
||||
|
@ -58,6 +58,7 @@ from feat_extract.inference import FeatsInterface
|
||||
from utils.event import ShoppingEvent, save_data
|
||||
from genfeats import gen_bcd_features
|
||||
from event_test import calc_simil
|
||||
from one2n_contrast import init_eventDict
|
||||
|
||||
|
||||
|
||||
@ -271,8 +272,12 @@ def build_std_evt_dict():
|
||||
evtDict = {}
|
||||
for evtname, barcode in evtList:
|
||||
evtpath = os.path.join(eventDataPath, evtname+'.pickle')
|
||||
with open(evtpath, 'rb') as f:
|
||||
evtdata = pickle.load(f)
|
||||
try:
|
||||
with open(evtpath, 'rb') as f:
|
||||
evtdata = pickle.load(f)
|
||||
except Exception as e:
|
||||
print(evtname)
|
||||
|
||||
evtDict[evtname] = evtdata
|
||||
|
||||
return evtList, evtDict, stdDict
|
||||
@ -300,7 +305,8 @@ def one2SN_pr(evtList, evtDict, stdDict):
|
||||
event = evtDict[evtname]
|
||||
## 无轨迹判断
|
||||
if len(event.front_feats)+len(event.back_feats)==0:
|
||||
print(evtname)
|
||||
errorFile_one2SN.append(evtname)
|
||||
print(f"No trajectory: {evtname}")
|
||||
continue
|
||||
|
||||
barcodes, similars = [], []
|
||||
@ -351,10 +357,10 @@ def one2SN_pr(evtList, evtDict, stdDict):
|
||||
FNX = sum(np.array(fn_simi) < th)
|
||||
TNX = sum(np.array(tn_simi) < th)
|
||||
PPreciseX.append(TPX/(TPX+FPX+1e-6))
|
||||
PRecallX.append(TPX/(len(tp_simi)+len(fn_simi)+1e-6))
|
||||
PRecallX.append(TPX/(TPX+FNX+1e-6))
|
||||
|
||||
NPreciseX.append(TNX/(TNX+FNX+1e-6))
|
||||
NRecallX.append(TNX/(len(tn_simi)+len(fp_simi)+1e-6))
|
||||
NRecallX.append(TNX/(TNX+FPX+1e-6))
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(Thresh, PPreciseX, 'r', label='Precise_Pos: TP/TPFP')
|
||||
@ -363,9 +369,11 @@ def one2SN_pr(evtList, evtDict, stdDict):
|
||||
ax.plot(Thresh, NRecallX, 'c', label='Recall_Neg: TN/TNFN')
|
||||
ax.set_xlim([0, 1])
|
||||
ax.set_ylim([0, 1])
|
||||
ax.grid(True)
|
||||
ax.set_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
ax.set_title('1:SN Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(evtList)}")
|
||||
ax.set_xlabel(f"Event Num: {len(tp_events) + len(fn_events)}")
|
||||
ax.legend()
|
||||
plt.show()
|
||||
## ============================= 1:N 展厅 直方图'''
|
||||
@ -403,10 +411,14 @@ def one2one_simi(evtList, evtDict, stdDict):
|
||||
|
||||
'''======2 计算事件、标准特征集相似度 =================='''
|
||||
rltdata = []
|
||||
errorFile_one2one = []
|
||||
for i in range(len(mergePairs)):
|
||||
evtname, stdbcd, label = mergePairs[i]
|
||||
event = evtDict[evtname]
|
||||
if len(event.feats_compose)==0: continue
|
||||
if len(event.feats_compose)==0:
|
||||
errorFile_one2one.append(evtname)
|
||||
|
||||
continue
|
||||
|
||||
stdfeat = stdDict[stdbcd] # float32
|
||||
|
||||
@ -418,11 +430,16 @@ def one2one_simi(evtList, evtDict, stdDict):
|
||||
|
||||
'''================ float32、16、int8 精度比较与存储 ============='''
|
||||
# data_precision_compare(stdfeat, evtfeat, mergePairs[i], save=True)
|
||||
|
||||
return rltdata
|
||||
|
||||
errorFile_one2one = list(set(errorFile_one2one))
|
||||
|
||||
return rltdata, errorFile_one2one
|
||||
|
||||
|
||||
def one2one_pr(rltdata):
|
||||
def one2one_pr(evtList, evtDict, stdDict):
|
||||
|
||||
rltdata, errorFile_one2one = one2one_simi(evtList, evtDict, stdDict)
|
||||
|
||||
Same, Cross = [], []
|
||||
for label, stdbcd, evtname, simi_mean, simi_max, simi_mft in rltdata:
|
||||
if label == "same":
|
||||
@ -451,27 +468,41 @@ def one2one_pr(rltdata):
|
||||
Correct = []
|
||||
Thresh = np.linspace(-0.2, 1, 100)
|
||||
for th in Thresh:
|
||||
TP = np.sum(Same > th)
|
||||
FN = TPFN - TP
|
||||
TP = np.sum(Same >= th)
|
||||
FN = np.sum(Same < th)
|
||||
# FN = TPFN - TP
|
||||
|
||||
TN = np.sum(Cross < th)
|
||||
FP = TNFP - TN
|
||||
FP = np.sum(Cross >= th)
|
||||
# FP = TNFP - TN
|
||||
|
||||
Recall_Pos.append(TP/TPFN)
|
||||
Recall_Neg.append(TN/TNFP)
|
||||
|
||||
Precision_Pos.append(TP/(TP+FP+1e-6))
|
||||
Precision_Neg.append(TN/(TN+FN+1e-6))
|
||||
Recall_Pos.append(TP/(TP+FN+1e-6))
|
||||
Recall_Neg.append(TN/(TN+FP+1e-6))
|
||||
|
||||
# Recall_Pos.append(TP/TPFN)
|
||||
# Recall_Neg.append(TN/TNFP)
|
||||
|
||||
|
||||
Correct.append((TN+TP)/(TPFN+TNFP))
|
||||
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(Thresh, Correct, 'r', label='Correct: (TN+TP)/(TPFN+TNFP)')
|
||||
|
||||
ax.plot(Thresh, Precision_Pos, 'r', label='Precision_Pos: TP/(TP+FP)')
|
||||
ax.plot(Thresh, Recall_Pos, 'b', label='Recall_Pos: TP/TPFN')
|
||||
ax.plot(Thresh, Recall_Neg, 'g', label='Recall_Neg: TN/TNFP')
|
||||
ax.plot(Thresh, Precision_Pos, 'c', label='Precision_Pos: TP/(TP+FP)')
|
||||
ax.plot(Thresh, Correct, 'c', label='Correct: (TN+TP)/(TPFN+TNFP)')
|
||||
ax.plot(Thresh, Precision_Neg, 'm', label='Precision_Neg: TN/(TN+FN)')
|
||||
|
||||
ax.set_xlim([0, 1])
|
||||
ax.set_ylim([0, 1])
|
||||
ax.grid(True)
|
||||
|
||||
ax.set_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
|
||||
ax.set_title('PrecisePos & PreciseNeg')
|
||||
ax.set_xlabel(f"Same Num: {TPFN}, Cross Num: {TNFP}")
|
||||
ax.legend()
|
||||
@ -506,23 +537,17 @@ def gen_eventdict(sourcePath, saveimg=True):
|
||||
## 兼容事件的两种情况:文件夹 和 Yolo-Resnet-Tracker 的输出
|
||||
if os.path.isfile(source_path):
|
||||
bname, ext = os.path.splitext(bname)
|
||||
evt = bname.split("_")
|
||||
# evt = bname.split("_")
|
||||
|
||||
evt = bname.split('_')
|
||||
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
|
||||
if not condt: continue
|
||||
|
||||
# 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
|
||||
|
||||
# event = ShoppingEvent(source_path, stype=source_type)
|
||||
# with open(pickpath, 'wb') as f:
|
||||
# pickle.dump(event, f)
|
||||
|
||||
try:
|
||||
event = ShoppingEvent(source_path, stype=source_type)
|
||||
# save_data(event, resultPath)
|
||||
@ -538,16 +563,44 @@ def gen_eventdict(sourcePath, saveimg=True):
|
||||
# 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 init_std_evt_dict():
|
||||
'''==== 0. 生成事件列表和对应的 Barcodes列表 ==========='''
|
||||
bcdList, event_spath = [], []
|
||||
# def init_std_evt_dict():
|
||||
# '''==== 0. 生成事件列表和对应的 Barcodes列表 ==========='''
|
||||
# bcdList, event_spath = [], []
|
||||
# for evtname in os.listdir(eventSourcePath):
|
||||
# bname, ext = os.path.splitext(evtname)
|
||||
|
||||
# ## 处理事件的两种情况:文件夹 和 Yolo-Resnet-Tracker 的输出
|
||||
# fpath = os.path.join(eventSourcePath, evtname)
|
||||
# if os.path.isfile(fpath) and (ext==".pkl" or ext==".pickle"):
|
||||
# evt = bname.split('_')
|
||||
# elif os.path.isdir(fpath):
|
||||
# evt = evtname.split('_')
|
||||
# else:
|
||||
# continue
|
||||
|
||||
# if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10:
|
||||
# bcdList.append(evt[-1])
|
||||
# event_spath.append(fpath)
|
||||
|
||||
# '''==== 1. 生成标准特征集, 只需运行一次, 在 genfeats.py 中实现 ==========='''
|
||||
# bcdSet = set(bcdList)
|
||||
# gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet)
|
||||
# print("stdFeats have generated and saved!")
|
||||
|
||||
# '''==== 2. 生成事件字典, 只需运行一次 ==============='''
|
||||
# gen_eventdict(event_spath)
|
||||
# print("eventList have generated and saved!")
|
||||
|
||||
def get_evtList():
|
||||
|
||||
'''==== 0. 生成事件列表和对应的 Barcodes 集合 ==========='''
|
||||
bcdList, evtpaths = [], []
|
||||
for evtname in os.listdir(eventSourcePath):
|
||||
bname, ext = os.path.splitext(evtname)
|
||||
|
||||
@ -562,46 +615,73 @@ def init_std_evt_dict():
|
||||
|
||||
if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10:
|
||||
bcdList.append(evt[-1])
|
||||
event_spath.append(fpath)
|
||||
|
||||
'''==== 1. 生成标准特征集, 只需运行一次, 在 genfeats.py 中实现 ==========='''
|
||||
bcdSet = set(bcdList)
|
||||
gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet)
|
||||
print("stdFeats have generated and saved!")
|
||||
|
||||
'''==== 2. 生成事件字典, 只需运行一次 ==============='''
|
||||
gen_eventdict(event_spath)
|
||||
print("eventList have generated and saved!")
|
||||
evtpaths.append(fpath)
|
||||
|
||||
bcdSet = set(bcdList)
|
||||
|
||||
return evtpaths, bcdSet
|
||||
|
||||
|
||||
|
||||
def test_one2one():
|
||||
# def init_stdDict():
|
||||
# evtpaths, bcdSet = get_evtList()
|
||||
# gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet)
|
||||
# print("stdFeats have generated and saved!")
|
||||
|
||||
|
||||
# def init_evtDict():
|
||||
# '''==== 0. 生成事件列表和对应的 Barcodes列表 ==========='''
|
||||
# bcdList, event_spath = [], []
|
||||
# for evtname in os.listdir(eventSourcePath):
|
||||
# bname, ext = os.path.splitext(evtname)
|
||||
|
||||
# ## 处理事件的两种情况:文件夹 和 Yolo-Resnet-Tracker 的输出
|
||||
# fpath = os.path.join(eventSourcePath, evtname)
|
||||
# if os.path.isfile(fpath) and (ext==".pkl" or ext==".pickle"):
|
||||
# evt = bname.split('_')
|
||||
# elif os.path.isdir(fpath):
|
||||
# evt = evtname.split('_')
|
||||
# else:
|
||||
# continue
|
||||
|
||||
# if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10:
|
||||
# bcdList.append(evt[-1])
|
||||
# event_spath.append(fpath)
|
||||
|
||||
# '''==== 2. 生成事件字典, 只需运行一次 ==============='''
|
||||
# gen_eventdict(event_spath)
|
||||
# print("eventList have generated and saved!")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_one2one_one2SN():
|
||||
'''1:1性能评估'''
|
||||
|
||||
# 1. 只需运行一次,生成事件字典和相应的标准特征库字典
|
||||
# init_std_evt_dict()
|
||||
# evtpaths, bcdSet = get_evtList()
|
||||
|
||||
# 2. 基于事件barcode集和标准库barcode交集构造事件集合
|
||||
evtList, evtDict, stdDict = build_std_evt_dict()
|
||||
'''=== 1. 只需运行一次,生成事件对应的标准特征库字典,如已生成,无需运行 ===='''
|
||||
# gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, eventSourcePath)
|
||||
|
||||
rltdata = one2one_simi(evtList, evtDict, stdDict)
|
||||
'''==== 2. 生成事件字典, 只需运行一次 ===================='''
|
||||
|
||||
one2one_pr(rltdata)
|
||||
# date_ = ['2025-3-4_1', '2025-3-5_1', '2025-3-5_2']
|
||||
# for dt in date_:
|
||||
# evtpaths = os.path.join(eventSourcePath, dt)
|
||||
# init_eventDict(evtpaths, eventDataPath, source_type)
|
||||
|
||||
init_eventDict(eventSourcePath, eventDataPath, source_type)
|
||||
|
||||
|
||||
|
||||
def test_one2SN():
|
||||
'''1:SN性能评估'''
|
||||
|
||||
# 1. 只需运行一次,生成事件字典和相应的标准特征库字典
|
||||
# init_std_evt_dict()
|
||||
|
||||
# 2. 事件barcode集和标准库barcode求交集
|
||||
'''==== 2. 基于事件barcode集和标准库barcode交集构造事件集合 ========='''
|
||||
evtList, evtDict, stdDict = build_std_evt_dict()
|
||||
|
||||
one2SN_pr(evtList, evtDict, stdDict)
|
||||
|
||||
one2one_pr(evtList, evtDict, stdDict)
|
||||
|
||||
one2SN_pr(evtList, evtDict, stdDict)
|
||||
|
||||
if __name__ == '__main__':
|
||||
'''
|
||||
共7个地址:
|
||||
@ -627,32 +707,30 @@ if __name__ == '__main__':
|
||||
|
||||
stdSamplePath = r"\\192.168.1.28\share\数据\已完成数据\比对数据\barcode\all_totalBarocde\totalBarcode"
|
||||
stdBarcodePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\testing\bcdpath"
|
||||
stdFeaturePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\testing\stdfeats"
|
||||
stdFeaturePath = r"\\192.168.1.28\share\数据\已完成数据\比对数据\barcode\all_totalBarocde\features_json\v11_barcode_0304"
|
||||
|
||||
if not os.path.exists(stdBarcodePath):
|
||||
os.makedirs(stdBarcodePath)
|
||||
if not os.path.exists(stdFeaturePath):
|
||||
os.makedirs(stdFeaturePath)
|
||||
|
||||
'''source_type:
|
||||
"source": eventSourcePath 为 Yolo-Resnet-Tracker 输出的 pickle 文件
|
||||
"data": 基于事件切分的原 data 文件版本
|
||||
"realtime": 全实时生成的 data 文件
|
||||
'''
|
||||
source_type:
|
||||
"source": eventSourcePath 为 Yolo-Resnet-Tracker 输出的 pickle 文件
|
||||
"data": eventSourcePath 为 包含 data 文件的文件夹
|
||||
'''
|
||||
source_type = 'realtime' # 'source', 'data', 'realtime'
|
||||
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-2-21\比对\video"
|
||||
|
||||
source_type = 'realtime' # 'source', 'data', 'realtime'
|
||||
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\基准数据集\2025-3-4_1"
|
||||
resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\testing"
|
||||
eventDataPath = os.path.join(resultPath, "evtobjs_data")
|
||||
similPath = os.path.join(resultPath, "simidata_data")
|
||||
|
||||
eventDataPath = os.path.join(resultPath, "evtobjs_0304_1")
|
||||
similPath = os.path.join(resultPath, "simidata_0304_1")
|
||||
if not os.path.exists(eventDataPath):
|
||||
os.makedirs(eventDataPath)
|
||||
if not os.path.exists(similPath):
|
||||
os.makedirs(similPath)
|
||||
|
||||
test_one2one()
|
||||
|
||||
test_one2SN()
|
||||
test_one2one_one2SN()
|
||||
|
||||
|
||||
|
||||
|
@ -109,24 +109,31 @@ def test_compare():
|
||||
|
||||
plot_pr_curve(simiList)
|
||||
|
||||
def contrast_pr(paths):
|
||||
def contrast_pr(evtPaths):
|
||||
'''
|
||||
1:1
|
||||
'''
|
||||
paths = Path(paths)
|
||||
|
||||
'''
|
||||
evtpaths = []
|
||||
for p in paths.iterdir():
|
||||
# date_ = ['2025-3-4_1', '2025-3-5_1', '2025-3-5_2']
|
||||
# for dt in date_:
|
||||
# paths = Path(evtPaths) / dt
|
||||
abc = []
|
||||
for p in Path(evtPaths).iterdir():
|
||||
condt1 = p.is_dir()
|
||||
condt2 = len(p.name.split('_'))>=2
|
||||
condt3 = len(p.name.split('_')[-1])>8
|
||||
condt3 = len(p.name.split('_')[-1])>=8
|
||||
condt4 = p.name.split('_')[-1].isdigit()
|
||||
if condt1 and condt2 and condt3 and condt4:
|
||||
evtpaths.append(p)
|
||||
elif p.is_dir():
|
||||
abc.append(p.stem)
|
||||
|
||||
|
||||
# evtpaths = [p for p in paths.iterdir() if p.is_dir() and len(p.name.split('_'))>=2 and len(p.name.split('_')[-1])>8]
|
||||
# evtpaths = [p for p in paths.iterdir() if p.is_dir()]
|
||||
|
||||
alg_times = []
|
||||
|
||||
events, similars = [], []
|
||||
##===================================== 扫A放A, 扫A放B场景()
|
||||
one2oneAA, one2oneAB = [], []
|
||||
@ -157,7 +164,7 @@ def contrast_pr(paths):
|
||||
barcode = path.stem.split('_')[-1]
|
||||
datapath = path.joinpath('process.data')
|
||||
|
||||
if not barcode.isdigit() or len(barcode)<10: continue
|
||||
if not barcode.isdigit() or len(barcode)<8: continue
|
||||
if not datapath.is_file(): continue
|
||||
|
||||
bcdList.append(barcode)
|
||||
@ -175,10 +182,15 @@ def contrast_pr(paths):
|
||||
|
||||
if len(one2one)+len(one2SN)+len(one2n) == 0:
|
||||
errorFile.append(path.stem)
|
||||
|
||||
dtime = SimiDict["algroStartToEnd"]
|
||||
if dtime >= 0:
|
||||
alg_times.append((dtime, path.stem))
|
||||
|
||||
|
||||
'''================== 0. 1:1 ==================='''
|
||||
barcodes, similars = [], []
|
||||
barcodes_ = []
|
||||
for dt in one2one:
|
||||
one2onePath.append((path.stem))
|
||||
if dt['similar']==0:
|
||||
@ -186,6 +198,12 @@ def contrast_pr(paths):
|
||||
continue
|
||||
barcodes.append(dt['barcode'])
|
||||
similars.append(dt['similar'])
|
||||
|
||||
|
||||
barcodes_.append(path.stem)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if len(barcodes)==len(similars) and len(barcodes)!=0:
|
||||
@ -216,6 +234,8 @@ def contrast_pr(paths):
|
||||
_fp_events.append(path.stem)
|
||||
else:
|
||||
errorFile_one2one.append(path.stem)
|
||||
elif len(one2SN)+len(one2n) == 0:
|
||||
errorFile_one2one.append(path.stem)
|
||||
|
||||
|
||||
'''================== 2. 取出场景下的 1 : Small N ==================='''
|
||||
@ -223,6 +243,7 @@ def contrast_pr(paths):
|
||||
for dt in one2SN:
|
||||
barcodes.append(dt['barcode'])
|
||||
similars.append(dt['similar'])
|
||||
|
||||
|
||||
if len(barcodes)==len(similars) and len(barcodes)!=0:
|
||||
## 扫A放A, 扫A放B场景
|
||||
@ -231,11 +252,11 @@ def contrast_pr(paths):
|
||||
|
||||
one2SNAA.extend(simAA)
|
||||
one2SNAB.extend(simAB)
|
||||
|
||||
one2SNPath.append(path.stem)
|
||||
if len(simAA)==0:
|
||||
one2SNPath1.append(path.stem)
|
||||
|
||||
|
||||
errorFile_one2SN.append(path.stem)
|
||||
|
||||
## 相似度排序,barcode相等且排名第一为TP,适用于多的barcode相似度比较
|
||||
max_idx = similars.index(max(similars))
|
||||
max_sim = similars[max_idx]
|
||||
@ -256,6 +277,7 @@ def contrast_pr(paths):
|
||||
fp_events.append(path.stem)
|
||||
else:
|
||||
errorFile_one2SN.append(path.stem)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -266,10 +288,17 @@ def contrast_pr(paths):
|
||||
evt_barcodes.append(dt["barcode"])
|
||||
evt_similars.append(dt["similar"])
|
||||
evt_types.append(dt["type"])
|
||||
|
||||
if len(events)==len(evt_barcodes) and len(evt_barcodes)==len(evt_similars) \
|
||||
and len(evt_similars)==len(evt_types) and len(events)>0:
|
||||
|
||||
|
||||
|
||||
if len(events)==len(evt_barcodes)==len(evt_similars)==len(evt_types) and len(events)>0:
|
||||
if not barcode in evt_barcodes:
|
||||
errorFile_one2n.append(path.stem)
|
||||
continue
|
||||
|
||||
if len(barcodes_):
|
||||
print("do")
|
||||
|
||||
one2nPath.append(path.stem)
|
||||
maxsim = evt_similars[evt_similars.index(max(evt_similars))]
|
||||
for i in range(len(one2n)):
|
||||
@ -324,9 +353,9 @@ def contrast_pr(paths):
|
||||
_TN = sum(np.array(one2oneAB) < th)
|
||||
|
||||
_PPrecise.append(_TP/(_TP+_FP+1e-6))
|
||||
_PRecall.append(_TP/(len(one2oneAA)+1e-6))
|
||||
_PRecall.append(_TP/(_TP+_FN+1e-6))
|
||||
_NPrecise.append(_TN/(_TN+_FN+1e-6))
|
||||
_NRecall.append(_TN/(len(one2oneAB)+1e-6))
|
||||
_NRecall.append(_TN/(_TN+_FP+1e-6))
|
||||
|
||||
'''===================================== 1:SN 均值'''
|
||||
TP_ = sum(np.array(one2SNAA) >= th)
|
||||
@ -346,10 +375,10 @@ def contrast_pr(paths):
|
||||
FNX = sum(np.array(fn_simi) < th)
|
||||
TNX = sum(np.array(tn_simi) < th)
|
||||
PPreciseX.append(TPX/(TPX+FPX+1e-6))
|
||||
PRecallX.append(TPX/(len(tp_simi)+len(fn_simi)+1e-6))
|
||||
PRecallX.append(TPX/(TPX+FNX+1e-6))
|
||||
|
||||
NPreciseX.append(TNX/(TNX+FNX+1e-6))
|
||||
NRecallX.append(TNX/(len(tn_simi)+len(fp_simi)+1e-6))
|
||||
NRecallX.append(TNX/(TNX+FPX+1e-6))
|
||||
|
||||
|
||||
'''===================================== 1:n'''
|
||||
@ -359,13 +388,19 @@ def contrast_pr(paths):
|
||||
TN = sum(np.array(tnsimi) < th)
|
||||
|
||||
PPrecise.append(TP/(TP+FP+1e-6))
|
||||
PRecall.append(TP/(len(tpsimi)+len(fnsimi)+1e-6))
|
||||
PRecall.append(TP/(TP+FN+1e-6))
|
||||
NPrecise.append(TN/(TN+FN+1e-6))
|
||||
NRecall.append(TN/(len(tnsimi)+len(fpsimi)+1e-6))
|
||||
NRecall.append(TN/(TN+FP+1e-6))
|
||||
|
||||
algtime = []
|
||||
for tm, _ in alg_times:
|
||||
algtime.append(tm)
|
||||
fig, ax = plt.subplots()
|
||||
ax.hist(np.array(algtime), bins=100, edgecolor='black')
|
||||
ax.set_title('Algorthm Spend Time')
|
||||
ax.set_xlabel(f"Event Num: {len(alg_times)}")
|
||||
plt.show()
|
||||
|
||||
|
||||
|
||||
|
||||
'''1. ============================= 1:1 最大值方案 曲线'''
|
||||
fig, ax = plt.subplots()
|
||||
ax.plot(Thresh, _PPrecise, 'r', label='Precise_Pos: TP/TPFP')
|
||||
@ -374,7 +409,9 @@ def contrast_pr(paths):
|
||||
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_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
ax.set_title('1:1 Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(one2oneAA)+len(one2oneAB)}")
|
||||
ax.legend()
|
||||
@ -393,30 +430,30 @@ def contrast_pr(paths):
|
||||
|
||||
|
||||
'''2. ============================= 1:1 均值方案 曲线'''
|
||||
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:1 Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(one2SNAA)}")
|
||||
ax.legend()
|
||||
plt.show()
|
||||
## ============================= 1:1 均值方案 直方图'''
|
||||
fig, axes = plt.subplots(2, 1)
|
||||
axes[0].hist(np.array(one2SNAA), bins=60, edgecolor='black')
|
||||
axes[0].set_xlim([-0.2, 1])
|
||||
axes[0].set_title('AA')
|
||||
axes[0].set_xlabel(f"Event Num: {len(one2SNAA)}")
|
||||
# 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:1 Precise & Recall')
|
||||
# ax.set_xlabel(f"Event Num: {len(one2SNAA)}")
|
||||
# ax.legend()
|
||||
# plt.show()
|
||||
# ## ============================= 1:1 均值方案 直方图'''
|
||||
# fig, axes = plt.subplots(2, 1)
|
||||
# axes[0].hist(np.array(one2SNAA), bins=60, edgecolor='black')
|
||||
# axes[0].set_xlim([-0.2, 1])
|
||||
# axes[0].set_title('AA')
|
||||
# axes[0].set_xlabel(f"Event Num: {len(one2SNAA)}")
|
||||
|
||||
axes[1].hist(np.array(one2SNAB), bins=60, edgecolor='black')
|
||||
axes[1].set_xlim([-0.2, 1])
|
||||
axes[1].set_title('BB')
|
||||
axes[1].set_xlabel(f"Event Num: {len(one2SNAB)}")
|
||||
plt.show()
|
||||
# axes[1].hist(np.array(one2SNAB), bins=60, edgecolor='black')
|
||||
# axes[1].set_xlim([-0.2, 1])
|
||||
# axes[1].set_title('BB')
|
||||
# axes[1].set_xlabel(f"Event Num: {len(one2SNAB)}")
|
||||
# plt.show()
|
||||
|
||||
''''3. ============================= 1:SN 曲线'''
|
||||
fig, ax = plt.subplots()
|
||||
@ -426,7 +463,9 @@ def contrast_pr(paths):
|
||||
ax.plot(Thresh, NRecallX, 'c', label='Recall_Neg: TN/TNFN')
|
||||
ax.set_xlim([0, 1])
|
||||
ax.set_ylim([0, 1])
|
||||
ax.grid(True)
|
||||
ax.set_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
ax.set_title('1:SN Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(one2SNAA)}")
|
||||
ax.legend()
|
||||
@ -456,7 +495,9 @@ def contrast_pr(paths):
|
||||
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_xticks(np.arange(0, 1, 0.1))
|
||||
ax.set_yticks(np.arange(0, 1, 0.1))
|
||||
ax.grid(True, linestyle='--')
|
||||
ax.set_title('1:n Precise & Recall')
|
||||
ax.set_xlabel(f"Event Num: {len(tpsimi)+len(fnsimi)}")
|
||||
ax.legend()
|
||||
@ -473,11 +514,11 @@ def contrast_pr(paths):
|
||||
axes[1, 0].set_xlim([-0.2, 1])
|
||||
axes[1, 0].set_title(f'TN({len(tnsimi)})')
|
||||
axes[1, 1].hist(fnsimi, bins=60, edgecolor='black')
|
||||
|
||||
axes[1, 1].set_xlim([-0.2, 1])
|
||||
axes[1, 1].set_title(f'FN({len(fnsimi)})')
|
||||
plt.show()
|
||||
|
||||
|
||||
# fpsnErrFile = str(paths.joinpath("one2SN_Error.txt"))
|
||||
# with open(fpsnErrFile, "w") as file:
|
||||
# for item in fp_events:
|
||||
@ -487,27 +528,24 @@ def contrast_pr(paths):
|
||||
# with open(fpErrFile, "w") as file:
|
||||
# for item in fpevents:
|
||||
# file.write(item + "\n")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# bcdSet = set(bcdList)
|
||||
# one2nErrFile = str(paths.joinpath("one_2_Small_n_Error.txt"))
|
||||
# with open(one2nErrFile, "w") as file:
|
||||
# for item in fnevents:
|
||||
# file.write(item + "\n")
|
||||
one2nErrFile = os.path.join(evtPaths, "one_2_Small_n_Error.txt")
|
||||
with open(one2nErrFile, "w") as file:
|
||||
for item in fnevents:
|
||||
file.write(item + "\n")
|
||||
|
||||
# one2NErrFile = str(paths.joinpath("one_2_Big_N_Error.txt"))
|
||||
# with open(one2NErrFile, "w") as file:
|
||||
# for item in fn_events:
|
||||
# file.write(item + "\n")
|
||||
one2NErrFile = os.path.join(evtPaths, "one_2_Big_N_Error.txt")
|
||||
with open(one2NErrFile, "w") as file:
|
||||
for item in fn_events:
|
||||
file.write(item + "\n")
|
||||
|
||||
print('Done!')
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-2-26_2"
|
||||
evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-3-3"
|
||||
contrast_pr(evtpaths)
|
||||
|
||||
|
||||
|
Binary file not shown.
@ -82,7 +82,11 @@ def array2list(bboxes):
|
||||
|
||||
class ShoppingEvent:
|
||||
def __init__(self, eventpath, stype="data"):
|
||||
'''stype: str, 'source', 'data', 'realtime', 共三种 '''
|
||||
'''stype: str, 'source', 'data', 'realtime', 共三种
|
||||
source: 前后摄视频经 pipeline 生成的文件
|
||||
data: 基于事件切分的原 data 文件版本
|
||||
realtime: 全实时生成的 data 文件
|
||||
'''
|
||||
|
||||
self.eventpath = eventpath
|
||||
self.evtname = str(Path(eventpath).stem)
|
||||
|
Reference in New Issue
Block a user