1:n modified

This commit is contained in:
王庆刚
2025-02-28 17:55:40 +08:00
parent b657be729b
commit 0efe8892f3
11 changed files with 198 additions and 112 deletions

View File

@ -6,6 +6,7 @@ Created on Wed Dec 18 11:49:01 2024
"""
import os
import pickle
import copy
import numpy as np
from pathlib import Path
import matplotlib.pyplot as plt
@ -17,44 +18,47 @@ def init_eventdict(sourcePath, stype="data"):
'''stype: str,
'source': 由 videos 或 images 生成的 pickle 文件
'data': 从 data 文件中读取的现场运行数据
'''
"realtime": 全实时数据,从 data 文件中读取的现场运行数据
'''
k, errEvents = 0, []
for bname in os.listdir(sourcePath):
# bname = r"20241126-135911-bdf91cf9-3e9a-426d-94e8-ddf92238e175_6923555210479"
source_path = os.path.join(sourcePath, bname)
if stype=="data" or stype=="realtime":
if stype=="source" and not os.path.isfile(source_path): 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")
if not os.path.isdir(source_path) or os.path.isfile(pickpath):
continue
if stype=="source":
else:
pickpath = os.path.join(eventDataPath, bname)
if not os.path.isfile(source_path) or os.path.isfile(pickpath):
continue
if os.path.isfile(pickpath):
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
# event = ShoppingEvent(source_path, stype)
try:
event = ShoppingEvent(source_path, stype)
with open(pickpath, 'wb') as f:
pickle.dump(event, f)
print(bname)
except Exception as e:
errEvents.append(source_path)
print(e)
print(f"Error: {bname}, {e}")
# k += 1
# if k==1:
# break
# errfile = os.path.join(resultPath, 'error_events.txt')
# with open(errfile, 'a', encoding='utf-8') as f:
# for line in errEvents:
# f.write(line + '\n')
errfile = os.path.join(resultPath, 'error_events.txt')
with open(errfile, 'a', encoding='utf-8') as f:
for line in errEvents:
f.write(line + '\n')
def read_eventdict(eventDataPath):
evtDict = {}
@ -70,38 +74,38 @@ def read_eventdict(eventDataPath):
return evtDict
def simi_calc(event, o2nevt, typee=None):
if typee == "11":
boxes1 = event.front_boxes
boxes2 = o2nevt.front_boxes
feat1 = event.front_feats
feat2 = o2nevt.front_feats
if typee == "10":
boxes1 = event.front_boxes
boxes2 = o2nevt.back_boxes
feat1 = event.front_feats
feat2 = o2nevt.back_feats
if typee == "00":
boxes1 = event.back_boxes
boxes2 = o2nevt.back_boxes
feat1 = event.back_feats
feat2 = o2nevt.back_feats
if typee == "01":
boxes1 = event.back_boxes
boxes2 = o2nevt.front_boxes
feat1 = event.back_feats
feat2 = o2nevt.front_feats
def simi_calc(event, o2nevt, pattern, typee=None):
if pattern==1 or pattern==2:
if typee == "11":
boxes1 = event.front_boxes
boxes2 = o2nevt.front_boxes
feat1 = event.front_feats
feat2 = o2nevt.front_feats
if typee == "10":
boxes1 = event.front_boxes
boxes2 = o2nevt.back_boxes
feat1 = event.front_feats
feat2 = o2nevt.back_feats
if typee == "00":
boxes1 = event.back_boxes
boxes2 = o2nevt.back_boxes
feat1 = event.back_feats
feat2 = o2nevt.back_feats
if typee == "01":
boxes1 = event.back_boxes
boxes2 = o2nevt.front_boxes
feat1 = event.back_feats
feat2 = o2nevt.front_feats
'''自定义事件特征选择'''
if typee==3 and len(event.feats_compose) and len(o2nevt.feats_compose):
if pattern==3 and len(event.feats_compose) and len(o2nevt.feats_compose):
feat1 = [event.feats_compose]
feat2 = [o2nevt.feats_compose]
if len(feat1) and len(feat2):
matrix = 1 - cdist(feat1[0], feat2[0], 'cosine')
simi = np.mean(matrix)
@ -114,64 +118,64 @@ def one2n_pr(evtDicts, pattern=1):
'''
pattern:
1: process.data 中记录的相似度
2: 根据 process.data 中标记的 type 选择特征计算相似度
3: 以其它方式选择特征计算相似度
2: 根据 process.data 中标记的 type 选择特征组合方式计算相似度
3: 利用 process.data 中的轨迹特征,以其它方式计算相似度
'''
tpevents, fnevents, fpevents, tnevents = [], [], [], []
tpsimi, fnsimi, tnsimi, fpsimi = [], [], [], []
one2nFile, errorFile_one2n = [], []
errorFile_one2n_ = []
evts_output = []
for evtname, event in evtDicts.items():
evt_names, evt_barcodes, evt_similars, evt_types = [], [], [], []
if len(event.barcode)==0:
evt_names, evt_barcodes, evt_similars, evt_types = [], [], [], []
if len(event.one2n)==0 or len(event.barcode)==0:
continue
evts_output.append(evtname)
for ndict in event.one2n:
nname = ndict["event"]
barcode = ndict["barcode"]
similar = ndict["similar"]
typee = ndict["type"].strip()
if len(barcode)==0:
continue
if typee.find(",") >=0:
typee = typee.split(",")[-1]
if pattern==1:
evt_similars.append(similar)
if pattern==2 or pattern==3:
o2n_evt = [evt for name, evt in evtDicts.items() if name.find(nname[:15])==0]
if len(o2n_evt)!=1:
continue
simival = simi_calc(event, o2n_evt[0], pattern, typee)
if simival==None:
continue
evt_similars.append(simival)
evt_names.append(nname)
evt_barcodes.append(barcode)
evt_types.append(typee)
if pattern==1:
evt_similars.append(similar)
if pattern==2 or pattern==3:
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:
continue
if pattern==2:
simival = simi_calc(event, o2nevt, typee)
if pattern==3:
simival = simi_calc(event, o2nevt, typee=pattern)
# if evtname == "20250226-170321-327_6903244678377":
# print("evtname")
if simival==None:
continue
evt_similars.append(simival)
## process.data的oneTon的各项中均不包括当前事件的barcode
if event.barcode not in evt_barcodes:
errorFile_one2n.append(evtname)
continue
else:
one2nFile.append(evtname)
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:
if len(evt_names)==len(evt_barcodes)==len(evt_similars)==len(evt_types) and len(evt_names)>0:
# maxsim = evt_similars[evt_similars.index(max(evt_similars))]
maxsim = max(evt_similars)
for i in range(len(evt_names)):
bcd, simi = evt_barcodes[i], evt_similars[i]
if bcd==event.barcode and simi==maxsim:
tpsimi.append(simi)
tpevents.append(evtname)
@ -185,14 +189,11 @@ def one2n_pr(evtDicts, pattern=1):
fpsimi.append(simi)
fpevents.append(evtname)
else:
errorFile_one2n.append(evtname)
errorFile_one2n_.append(evtname)
''' 1:n 数据存储,需根据相似度排序'''
PPrecise, PRecall = [], []
NPrecise, NRecall = [], []
Thresh = np.linspace(-0.2, 1, 100)
for th in Thresh:
'''============================= 1:n 计算'''
@ -202,9 +203,9 @@ def one2n_pr(evtDicts, pattern=1):
TN = sum(np.array(tnsimi) < th)
PPrecise.append(TP/(TP+FP+1e-6))
PRecall.append(TP/(len(one2nFile)+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))
'''4. ============================= 1:n 曲线,'''
@ -238,25 +239,22 @@ def one2n_pr(evtDicts, pattern=1):
return fpevents
def main():
def main():
'''1. 生成事件字典并保存至 eventDataPath, 只需运行一次 '''
init_eventdict(eventSourcePath, stype="source") # 'source', 'data', 'realtime'
init_eventdict(eventSourcePath, stype="realtime") # 'source', 'data', 'realtime'
# for pfile in os.listdir(eventDataPath):
# evt = os.path.splitext(pfile)[0].split('_')
# cont = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
# if not cont:
# continue
'''2. 读取事件字典 '''
evtDicts = read_eventdict(eventDataPath)
'''3. 1:n 比对事件评估 '''
fpevents = one2n_pr(evtDicts, pattern=2)
fpevents = one2n_pr(evtDicts, pattern=1)
fpErrFile = str(Path(resultPath).joinpath("one2n_fp_Error.txt"))
with open(fpErrFile, "w") as file:
@ -266,10 +264,10 @@ def main():
if __name__ == '__main__':
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\result_V12\ShoppingDict_pkfile"
eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\V12\2025-2-27"
resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\全实时测试\testing"
eventDataPath = os.path.join(resultPath, "evtobjs_data")
eventDataPath = os.path.join(resultPath, "evtobjs_wang")
if not os.path.exists(eventDataPath):
os.makedirs(eventDataPath)