增加了单帧入侵判断及yoloV10

This commit is contained in:
18262620154
2025-04-11 17:02:39 +08:00
parent 798c596acc
commit e044c85a04
197 changed files with 1863 additions and 997 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -9,17 +9,19 @@ import cv2
import json
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
from matplotlib import rcParams
from matplotlib.font_manager import FontProperties
from scipy.spatial.distance import cdist
from utils.event import ShoppingEvent, save_data
from utils.calsimi import calsimi_vs_stdfeat_new, get_topk_percent, cluster
from utils.tools import get_evtList
import pickle
rcParams['font.sans-serif'] = ['SimHei'] # 用黑体显示中文
rcParams['axes.unicode_minus'] = False # 正确显示负号
'''*********** USearch ***********'''
def read_usearch():
stdFeaturePath = r"D:\contrast\stdlib\v11_test.json"
@ -35,13 +37,12 @@ def read_usearch():
return stdlib
def get_eventlist():
def get_eventlist_errortxt(evtpaths):
'''
读取一次测试中的错误事件
'''
evtpaths = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\images"
text1 = "one2n_Error.txt"
text2 = "one2SN_Error.txt"
'''
text1 = "one_2_Small_n_Error.txt"
text2 = "one_2_Big_N_Error.txt"
events = []
text = (text1, text2)
for txt in text:
@ -53,16 +54,16 @@ def get_eventlist():
if line:
fpath=os.path.join(evtpaths, line)
events.append(fpath)
events = list(set(events))
return events
def single_event():
events = get_eventlist()
def save_eventdata():
evtpaths = r"/home/wqg/dataset/test_dataset/performence_dataset/"
events = get_eventlist_errortxt(evtpaths)
'''定义当前事件存储地址及生成相应文件件'''
resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result\single_event"
@ -74,121 +75,148 @@ def single_event():
def get_topk_percent(data, k):
"""
获取数据中最大的 k% 的元素
"""
# 将数据转换为 NumPy 数组
if isinstance(data, list):
data = np.array(data)
# def get_topk_percent(data, k):
# """
# 获取数据中最大的 k% 的元素
# """
# # 将数据转换为 NumPy 数组
# if isinstance(data, list):
# data = np.array(data)
percentile = np.percentile(data, 100-k)
top_k_percent = data[data >= percentile]
# percentile = np.percentile(data, 100-k)
# top_k_percent = data[data >= percentile]
return top_k_percent
def cluster(data, thresh=0.15):
# data = np.array([0.1, 0.13, 0.7, 0.2, 0.8, 0.52, 0.3, 0.7, 0.85, 0.58])
# data = np.array([0.1, 0.13, 0.2, 0.3])
# data = np.array([0.1])
# return top_k_percent
# def cluster(data, thresh=0.15):
# # data = np.array([0.1, 0.13, 0.7, 0.2, 0.8, 0.52, 0.3, 0.7, 0.85, 0.58])
# # data = np.array([0.1, 0.13, 0.2, 0.3])
# # data = np.array([0.1])
if isinstance(data, list):
data = np.array(data)
# if isinstance(data, list):
# data = np.array(data)
data1 = np.sort(data)
cluter, Cluters, = [data1[0]], []
for i in range(1, len(data1)):
if data1[i] - data1[i-1]< thresh:
cluter.append(data1[i])
else:
Cluters.append(cluter)
cluter = [data1[i]]
Cluters.append(cluter)
# data1 = np.sort(data)
# cluter, Cluters, = [data1[0]], []
# for i in range(1, len(data1)):
# if data1[i] - data1[i-1]< thresh:
# cluter.append(data1[i])
# else:
# Cluters.append(cluter)
# cluter = [data1[i]]
# Cluters.append(cluter)
clt_center = []
for clt in Cluters:
## 是否应该在此处限制一个聚类中的最小轨迹样本数,应该将该因素放在轨迹分析中
# if len(clt)>=3:
# clt_center.append(np.mean(clt))
clt_center.append(np.mean(clt))
# clt_center = []
# for clt in Cluters:
# ## 是否应该在此处限制一个聚类中的最小轨迹样本数,应该将该因素放在轨迹分析中
# # if len(clt)>=3:
# # clt_center.append(np.mean(clt))
# clt_center.append(np.mean(clt))
# print(clt_center)
# # print(clt_center)
return clt_center
# return clt_center
def calc_simil(event, stdfeat):
'''事件与标准库的对比策略
该比对策略是否可以拓展到事件与事件的比对?
'''
# def calsimi_vs_stdfeat_new(event, stdfeat):
# '''事件与标准库的对比策略
# 该比对策略是否可以拓展到事件与事件的比对?
# '''
def calsiml(feat1, feat2, topkp=75, cluth=0.15):
'''轨迹样本和标准特征集样本相似度的选择策略'''
matrix = 1 - cdist(feat1, feat2, 'cosine')
simi_max = []
for i in range(len(matrix)):
sim = np.mean(get_topk_percent(matrix[i, :], topkp))
simi_max.append(sim)
cltc_max = cluster(simi_max, cluth)
Simi = max(cltc_max)
# def calsiml(feat1, feat2, topkp=75, cluth=0.15):
# '''轨迹样本和标准特征集样本相似度的选择策略'''
# matrix = 1 - cdist(feat1, feat2, 'cosine')
# simi_max = []
# for i in range(len(matrix)):
# sim = np.mean(get_topk_percent(matrix[i, :], topkp))
# simi_max.append(sim)
# cltc_max = cluster(simi_max, cluth)
# Simi = max(cltc_max)
## cltc_max为空属于编程考虑不周应予以排查解决
# if len(cltc_max):
# Simi = max(cltc_max)
# else:
# Simi = 0 #不应该走到该处
# ## cltc_max为空属于编程考虑不周应予以排查解决
# # if len(cltc_max):
# # Simi = max(cltc_max)
# # else:
# # Simi = 0 #不应该走到该处
return Simi
# return Simi
front_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
front_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(event.front_boxes)):
front_boxes = np.concatenate((front_boxes, event.front_boxes[i]), axis=0)
front_feats = np.concatenate((front_feats, event.front_feats[i]), axis=0)
# front_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
# front_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
# for i in range(len(event.front_boxes)):
# front_boxes = np.concatenate((front_boxes, event.front_boxes[i]), axis=0)
# front_feats = np.concatenate((front_feats, event.front_feats[i]), axis=0)
back_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
back_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(event.back_boxes)):
back_boxes = np.concatenate((back_boxes, event.back_boxes[i]), axis=0)
back_feats = np.concatenate((back_feats, event.back_feats[i]), axis=0)
# back_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
# back_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
# for i in range(len(event.back_boxes)):
# back_boxes = np.concatenate((back_boxes, event.back_boxes[i]), axis=0)
# back_feats = np.concatenate((back_feats, event.back_feats[i]), axis=0)
if len(front_feats):
front_simi = calsiml(front_feats, stdfeat)
if len(back_feats):
back_simi = calsiml(back_feats, stdfeat)
# if len(front_feats):
# front_simi = calsiml(front_feats, stdfeat)
# if len(back_feats):
# back_simi = calsiml(back_feats, stdfeat)
# '''前后摄相似度融合策略'''
# if len(front_feats) and len(back_feats):
# diff_simi = abs(front_simi - back_simi)
# if diff_simi>0.15:
# Similar = max([front_simi, back_simi])
# else:
# Similar = (front_simi+back_simi)/2
# elif len(front_feats) and len(back_feats)==0:
# Similar = front_simi
# elif len(front_feats)==0 and len(back_feats):
# Similar = back_simi
# else:
# Similar = None # 在event.front_feats和event.back_feats同时为空时
# return Similar
'''前后摄相似度融合策略'''
if len(front_feats) and len(back_feats):
diff_simi = abs(front_simi - back_simi)
if diff_simi>0.15:
Similar = max([front_simi, back_simi])
else:
Similar = (front_simi+back_simi)/2
elif len(front_feats) and len(back_feats)==0:
Similar = front_simi
elif len(front_feats)==0 and len(back_feats):
Similar = back_simi
else:
Similar = None # 在event.front_feats和event.back_feats同时为空时
return Similar
def simi_matrix():
resultPath = r"\\192.168.1.28\share\测试视频数据以及日志\算法全流程测试\202412\result\single_event"
evtpaths = r"/home/wqg/dataset/pipeline/contrast/single_event_V10/evtobjs/"
stdlib = read_usearch()
events = get_eventlist()
for evtpath in events:
evtname = os.path.basename(evtpath)
_, barcode = evtname.split("_")
stdfeatPath = r"/home/wqg/dataset/test_dataset/total_barcode/features_json/v11_barcode_0304/"
resultPath = r"/home/wqg/dataset/performence_dataset/result/"
evt_paths, bcdSet = get_evtList(evtpaths)
## read std features
stdDict={}
evtDict = {}
for barcode in bcdSet:
stdpath = os.path.join(stdfeatPath, f"{barcode}.json")
if not os.path.isfile(stdpath):
continue
# 生成事件与相应标准特征集
event = ShoppingEvent(evtpath)
stdfeat = stdlib[barcode]
with open(stdpath, 'r', encoding='utf-8') as f:
stddata = json.load(f)
feat = np.array(stddata["value"])
stdDict[barcode] = feat
for evtpath in evt_paths:
barcode = Path(evtpath).stem.split("_")[-1]
if barcode not in stdDict.keys():
continue
Similar = calc_simil(event, stdfeat)
# try:
# with open(evtpath, 'rb') as f:
# evtdata = pickle.load(f)
# except Exception as e:
# print(evtname)
with open(evtpath, 'rb') as f:
event = pickle.load(f)
stdfeat = stdDict[barcode]
Similar = calsimi_vs_stdfeat_new(event, stdfeat)
# 构造 boxes 子图存储路径
subimgpath = os.path.join(resultPath, f"{event.evtname}", "subimg")
@ -217,9 +245,9 @@ def simi_matrix():
evtfeat = np.concatenate((evtfeat, event.back_feats[i]), axis=0)
imgpaths = event.back_imgpaths
assert len(boxes)==len(evtfeat), f"Please check the Event: {evtname}"
assert len(boxes)==len(evtfeat), f"Please check the Event: {event.evtname}"
if len(boxes)==0: continue
print(evtname)
print(event.evtname)
matrix = 1 - cdist(evtfeat, stdfeat, 'cosine')
simi_1d = matrix.flatten()
@ -309,8 +337,8 @@ def simi_matrix():
mean_diff = abs(mean_values[1]-mean_values[0])
ax[0, 1].set_title(f"mean diff: {mean_diff:.3f}")
if len(max_values)==2:
max_values = abs(max_values[1]-max_values[0])
ax[0, 2].set_title(f"max diff: {max_values:.3f}")
max_diff = abs(max_values[1]-max_values[0])
ax[0, 2].set_title(f"max diff: {max_diff:.3f}")
try:
fig.suptitle(f"Similar: {Similar:.3f}", fontsize=16)
except Exception as e:
@ -319,19 +347,14 @@ def simi_matrix():
pltpath = os.path.join(subimgpath, f"hist_max_{kpercent}%_.png")
plt.savefig(pltpath)
pltpath1 = os.path.join(histpath, f"{evtname}_.png")
pltpath1 = os.path.join(histpath, f"{event.evtname}_.png")
plt.savefig(pltpath1)
plt.close()
def main():
simi_matrix()

View File

@ -38,13 +38,13 @@ def get_std_barcodeDict(bcdpath, savepath, bcdSet):
'''
inputs:
bcdpath: 已清洗的barcode样本图像如果barcode下有'base'文件夹,只选用该文件夹下图像
(default = r'\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_1771')
(default = r'\\\\192.168.1.28\\share\\已标注数据备份\\对比数据\\barcode\\barcode_1771')
功能:
生成并保存只有一个key值的字典 {barcode: [imgpath1, imgpath1, ...]}
savepath: 字典存储地址文件名格式barcode.pickle
'''
# savepath = r'\\192.168.1.28\share\测试_202406\contrast\std_barcodes'
# savepath = r'\\\\192.168.1.28\\share\\测试_202406\\contrast\\std_barcodes'
'''读取数据集中 barcode 列表'''
stdBarcodeList = []

View File

@ -6,57 +6,11 @@ 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
from scipy.spatial.distance import cdist
from utils.event import ShoppingEvent
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 evtname in os.listdir(sourcePath):
bname, ext = os.path.splitext(evtname)
source_path = os.path.join(sourcePath, evtname)
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
evt = bname.split('_')
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
if not condt: 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(evtname)
except Exception as e:
errEvents.append(source_path)
print(f"Error: {evtname}, {e}")
# k += 1
# if k==1:
# break
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')
from utils.tools import init_eventDict
def read_eventdict(eventDataPath):
evtDict = {}

View File

@ -27,188 +27,24 @@ Created on Fri Aug 30 17:53:03 2024
"""
import numpy as np
import cv2
import os
import sys
import random
import pickle
import json
import random
import copy
import sys
# import torch
import time
# import json
from pathlib import Path
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
import shutil
from datetime import datetime
# from openpyxl import load_workbook, Workbook
# from config import config as conf
# from model import resnet18 as resnet18
# from feat_inference import inference_image
FILE = Path(__file__).resolve()
ROOT = FILE.parents[1] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT))
sys.path.append(r"D:\DetectTracking")
from tracking.utils.read_data import extract_data, read_tracking_output, read_similar, read_deletedBarcode_file
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, save_data
from utils.calsimi import calsimi_vs_stdfeat, calsimi_vs_stdfeat_new
from utils.tools import get_evtList, init_eventDict
from utils.databits import data_precision_compare
from genfeats import gen_bcd_features
from event_test import calc_simil
from one2n_contrast import init_eventDict
def int8_to_ft16(arr_uint8, amin, amax):
arr_ft16 = (arr_uint8 / 255 * (amax-amin) + amin).astype(np.float16)
return arr_ft16
def ft16_to_uint8(arr_ft16):
# pickpath = r"\\192.168.1.28\share\测试_202406\contrast\std_features_ft32vsft16\6902265587712_ft16.pickle"
# with open(pickpath, 'rb') as f:
# edict = pickle.load(f)
# arr_ft16 = edict['feats']
amin = np.min(arr_ft16)
amax = np.max(arr_ft16)
arr_ft255 = (arr_ft16 - amin) * 255 / (amax-amin)
arr_uint8 = arr_ft255.astype(np.uint8)
arr_ft16_ = int8_to_ft16(arr_uint8, amin, amax)
arrDistNorm = np.linalg.norm(arr_ft16_ - arr_ft16) / arr_ft16_.size
return arr_uint8, arr_ft16_
def data_precision_compare(stdfeat, evtfeat, evtMessage, save=True):
evt, stdbcd, label = evtMessage
rltdata, rltdata_ft16, rltdata_ft16_ = [], [], []
matrix = 1 - cdist(stdfeat, evtfeat, 'cosine')
simi_mean = np.mean(matrix)
simi_max = np.max(matrix)
stdfeatm = np.mean(stdfeat, axis=0, keepdims=True)
evtfeatm = np.mean(evtfeat, axis=0, keepdims=True)
simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine'))
rltdata = [label, stdbcd, evt, simi_mean, simi_max, simi_mfeat[0,0]]
##================================================================= float16
stdfeat_ft16 = stdfeat.astype(np.float16)
evtfeat_ft16 = evtfeat.astype(np.float16)
stdfeat_ft16 /= np.linalg.norm(stdfeat_ft16, axis=1)[:, None]
evtfeat_ft16 /= np.linalg.norm(evtfeat_ft16, axis=1)[:, None]
matrix_ft16 = 1 - cdist(stdfeat_ft16, evtfeat_ft16, 'cosine')
simi_mean_ft16 = np.mean(matrix_ft16)
simi_max_ft16 = np.max(matrix_ft16)
stdfeatm_ft16 = np.mean(stdfeat_ft16, axis=0, keepdims=True)
evtfeatm_ft16 = np.mean(evtfeat_ft16, axis=0, keepdims=True)
simi_mfeat_ft16 = 1- np.maximum(0.0, cdist(stdfeatm_ft16, evtfeatm_ft16, 'cosine'))
rltdata_ft16 = [label, stdbcd, evt, simi_mean_ft16, simi_max_ft16, simi_mfeat_ft16[0,0]]
'''****************** uint8 is ok!!!!!! ******************'''
##=================================================================== uint8
# stdfeat_uint8, stdfeat_ft16_ = ft16_to_uint8(stdfeat_ft16)
# evtfeat_uint8, evtfeat_ft16_ = ft16_to_uint8(evtfeat_ft16)
stdfeat_uint8 = (stdfeat_ft16*128).astype(np.int8)
evtfeat_uint8 = (evtfeat_ft16*128).astype(np.int8)
stdfeat_ft16_ = stdfeat_uint8.astype(np.float16)/128
evtfeat_ft16_ = evtfeat_uint8.astype(np.float16)/128
absdiff = np.linalg.norm(stdfeat_ft16_ - stdfeat) / stdfeat.size
matrix_ft16_ = 1 - cdist(stdfeat_ft16_, evtfeat_ft16_, 'cosine')
simi_mean_ft16_ = np.mean(matrix_ft16_)
simi_max_ft16_ = np.max(matrix_ft16_)
stdfeatm_ft16_ = np.mean(stdfeat_ft16_, axis=0, keepdims=True)
evtfeatm_ft16_ = np.mean(evtfeat_ft16_, axis=0, keepdims=True)
simi_mfeat_ft16_ = 1- np.maximum(0.0, cdist(stdfeatm_ft16_, evtfeatm_ft16_, 'cosine'))
rltdata_ft16_ = [label, stdbcd, evt, simi_mean_ft16_, simi_max_ft16_, simi_mfeat_ft16_[0,0]]
if not save:
return
##========================================================= save as float32
rppath = os.path.join(similPath, f'{evt}_ft32.pickle')
with open(rppath, 'wb') as f:
pickle.dump(rltdata, f)
rtpath = os.path.join(similPath, f'{evt}_ft32.txt')
with open(rtpath, 'w', encoding='utf-8') as f:
for result in rltdata:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')
##========================================================= save as float16
rppath_ft16 = os.path.join(similPath, f'{evt}_ft16.pickle')
with open(rppath_ft16, 'wb') as f:
pickle.dump(rltdata_ft16, f)
rtpath_ft16 = os.path.join(similPath, f'{evt}_ft16.txt')
with open(rtpath_ft16, 'w', encoding='utf-8') as f:
for result in rltdata_ft16:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')
##=========================================================== save as uint8
rppath_uint8 = os.path.join(similPath, f'{evt}_uint8.pickle')
with open(rppath_uint8, 'wb') as f:
pickle.dump(rltdata_ft16_, f)
rtpath_uint8 = os.path.join(similPath, f'{evt}_uint8.txt')
with open(rtpath_uint8, 'w', encoding='utf-8') as f:
for result in rltdata_ft16_:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')
def simi_calc(event, stdfeat):
evtfeat = event.feats_compose
if isinstance(event.feats_select, list):
if len(event.feats_select) and len(event.feats_select[0]):
evtfeat = event.feats_select[0]
else:
return None, None, None
else:
evtfeat = event.feats_select
if len(evtfeat)==0 or len(stdfeat)==0:
return None, None, None
evtfeat /= np.linalg.norm(evtfeat, axis=1)[:, None]
stdfeat /= np.linalg.norm(stdfeat, axis=1)[:, None]
matrix = 1 - cdist(evtfeat, stdfeat, 'cosine')
matrix[matrix < 0] = 0
simi_mean = np.mean(matrix)
simi_max = np.max(matrix)
stdfeatm = np.mean(stdfeat, axis=0, keepdims=True)
evtfeatm = np.mean(evtfeat, axis=0, keepdims=True)
simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine'))
return simi_mean, simi_max, simi_mfeat[0,0]
def build_std_evt_dict():
@ -218,18 +54,6 @@ def build_std_evt_dict():
'''
stdBarcode = [p.stem for p in Path(stdFeaturePath).iterdir() if p.is_file() and (p.suffix=='.json' or p.suffix=='.pickle')]
'''*********** USearch ***********'''
# stdFeaturePath = r"D:\contrast\stdlib\v11_test.json"
# stdBarcode = []
# stdlib = {}
# with open(stdFeaturePath, 'r', encoding='utf-8') as f:
# data = json.load(f)
# for dic in data['total']:
# barcode = dic['key']
# feature = np.array(dic['value'])
# stdBarcode.append(barcode)
# stdlib[barcode] = feature
'''======1. 购物事件列表,该列表中的 Barcode 存在于标准的 stdBarcode 内 ==='''
evtList = [(p.stem, p.stem.split('_')[-1]) for p in Path(eventDataPath).iterdir()
@ -259,10 +83,7 @@ def build_std_evt_dict():
stddata = pickle.load(f)
feat = stddata["feats_ft32"]
stdDict[barcode] = feat
'''*********** USearch ***********'''
# stdDict = {}
# for barcode in barcodes:
@ -282,7 +103,7 @@ def build_std_evt_dict():
return evtList, evtDict, stdDict
def one2SN_pr(evtList, evtDict, stdDict):
def one2SN_pr(evtList, evtDict, stdDict, simType="simple"):
std_barcodes = set([bcd for _, bcd in evtList])
@ -312,8 +133,14 @@ def one2SN_pr(evtList, evtDict, stdDict):
barcodes, similars = [], []
for stdbcd in bcd_selected:
stdfeat = stdDict[stdbcd]
simi_mean, simi_max, simi_mfeat = simi_calc(event, stdfeat)
# simi_mean = calc_simil(event, stdfeat)
if simType=="typea":
simi_mean, simi_max, simi_mfeat = calsimi_vs_stdfeat(event, stdfeat)
elif simType=="typeb":
pass
else:
simi_mean, simi_1, simi_2 = calsimi_vs_stdfeat_new(event, stdfeat)
## 在event.front_feats和event.back_feats同时为空时此处不需要保护
# if simi_mean==None:
@ -376,6 +203,10 @@ def one2SN_pr(evtList, evtDict, stdDict):
ax.set_xlabel(f"Event Num: {len(tp_events) + len(fn_events)}")
ax.legend()
plt.show()
rltpath = os.path.join(similPath, f'pr_1toSN_{simType}.png')
plt.savefig(rltpath)
## ============================= 1:N 展厅 直方图'''
fig, axes = plt.subplots(2, 2)
axes[0, 0].hist(tp_simi, bins=60, range=(-0.2, 1), edgecolor='black')
@ -391,11 +222,14 @@ def one2SN_pr(evtList, evtDict, stdDict):
axes[1, 1].set_xlim([-0.2, 1])
axes[1, 1].set_title(f'FN({len(fn_simi)})')
plt.show()
rltpath = os.path.join(similPath, f'hist_1toSN_{simType}.png')
plt.savefig(rltpath)
def one2one_simi(evtList, evtDict, stdDict):
def one2one_simi(evtList, evtDict, stdDict, simType):
barcodes = set([bcd for _, bcd in evtList])
'''======1 构造 3 个事件对: 扫 A 放 A, 扫 A 放 B, 合并 ===================='''
@ -421,31 +255,50 @@ def one2one_simi(evtList, evtDict, stdDict):
continue
stdfeat = stdDict[stdbcd] # float32
simi_mean, simi_max, simi_mfeat = simi_calc(event, stdfeat)
if simType=="typea":
simi_mean, simi_1, simi_2 = calsimi_vs_stdfeat_new(event, stdfeat)
elif simType=="typeb":
pass
else:
simi_mean, simi_1, simi_2 = calsimi_vs_stdfeat(event, stdfeat)
if simi_mean is None:
continue
rltdata.append((label, stdbcd, evtname, simi_mean, simi_max, simi_mfeat))
rltdata.append((label, stdbcd, evtname, simi_mean, simi_1, simi_2))
'''================ float32、16、int8 精度比较与存储 ============='''
# data_precision_compare(stdfeat, evtfeat, mergePairs[i], save=True)
# data_precision_compare(stdfeat, evtfeat, mergePairs[i], similPath, save=True)
errorFile_one2one = list(set(errorFile_one2one))
return rltdata, errorFile_one2one
def one2one_pr(evtList, evtDict, stdDict):
def one2one_pr(evtList, evtDict, stdDict, simType="simple"):
rltdata, errorFile_one2one = one2one_simi(evtList, evtDict, stdDict)
rltdata, errorFile_one2one = one2one_simi(evtList, evtDict, stdDict, simType)
Same, Cross = [], []
for label, stdbcd, evtname, simi_mean, simi_max, simi_mft in rltdata:
if label == "same":
if simType=="simple" and label == "same":
Same.append(simi_max)
if label == "diff":
if simType=="simple" and label == "diff":
Cross.append(simi_max)
if simType=="typea" and label == "same":
Same.append(simi_mean)
if simType=="typea" and label == "diff":
Cross.append(simi_mean)
# for label, stdbcd, evtname, simi_mean, simi_max, simi_mft in rltdata:
# if label == "same":
# Same.append(simi_mean)
# if label == "diff":
# Cross.append(simi_mean)
Same = np.array(Same)
Cross = np.array(Cross)
@ -508,7 +361,7 @@ def one2one_pr(evtList, evtDict, stdDict):
ax.legend()
plt.show()
rltpath = os.path.join(similPath, 'pr.png')
rltpath = os.path.join(similPath, f'pr_1to1_{simType}.png')
plt.savefig(rltpath) # svg, png, pdf
@ -521,7 +374,7 @@ def one2one_pr(evtList, evtDict, stdDict):
axes[1].set_xlim([-0.2, 1])
axes[1].set_title(f'TN({len(Cross)})')
rltpath = os.path.join(similPath, 'hist.png')
rltpath = os.path.join(similPath, f'hist_1to1_{simType}.png')
plt.savefig(rltpath)
@ -529,158 +382,25 @@ def one2one_pr(evtList, evtDict, stdDict):
def gen_eventdict(sourcePath, saveimg=True):
k, errEvents = 0, []
for source_path in sourcePath:
evtpath, bname = os.path.split(source_path)
## 兼容事件的两种情况:文件夹 和 Yolo-Resnet-Tracker 的输出
if os.path.isfile(source_path):
bname, ext = os.path.splitext(bname)
# evt = bname.split("_")
evt = bname.split('_')
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
if not condt: continue
# 如果已完成事件生成,则不执行
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
if os.path.isfile(pickpath): continue
try:
event = ShoppingEvent(source_path, stype=source_type)
# 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 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)
## 处理事件的两种情况:文件夹 和 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])
evtpaths.append(fpath)
bcdSet = set(bcdList)
return evtpaths, bcdSet
# 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():
def test_one2one_one2SN(simType):
'''1:1性能评估'''
# evtpaths, bcdSet = get_evtList()
# evtpaths, bcdSet = get_evtList(eventSourcePath)
'''=== 1. 只需运行一次,生成事件对应的标准特征库字典,如已生成,无需运行 ===='''
# gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, eventSourcePath)
'''==== 2. 生成事件字典, 只需运行一次 ===================='''
# 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)
# init_eventDict(eventSourcePath, eventDataPath, source_type)
'''==== 2. 基于事件barcode集和标准库barcode交集构造事件集合 ========='''
'''==== 3. 基于事件barcode集和标准库barcode交集构造事件集合 ========='''
evtList, evtDict, stdDict = build_std_evt_dict()
one2one_pr(evtList, evtDict, stdDict)
one2one_pr(evtList, evtDict, stdDict, simType)
one2SN_pr(evtList, evtDict, stdDict)
one2SN_pr(evtList, evtDict, stdDict, simType)
if __name__ == '__main__':
'''
@ -694,21 +414,10 @@ if __name__ == '__main__':
(7) similPath: 1:1比对结果存储地址(事件级)在resultPath下
'''
# stdSamplePath = r"\\192.168.1.28\share\数据\已完成数据\展厅数据\v1.0\比对数据\整理\zhantingBase"
# stdBarcodePath = r"D:\exhibition\dataset\bcdpath"
# stdFeaturePath = r"\\192.168.1.28\share\数据\已完成数据\比对数据\barcode\all_totalBarocde\features_json\v11_barcode_11592"
stdSamplePath = "/home/wqg/dataset/total_barcode/totalBarcode"
stdBarcodePath = "/home/wqg/dataset/total_barcode/bcdpath"
stdFeaturePath = "/home/wqg/dataset/test_dataset/total_barcode/features_json/v11_barcode_0304/"
# eventSourcePath = r'D:\exhibition\images\20241202'
# eventSourcePath = r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\展厅测试\1129_展厅模型v801测试组测试"
# stdSamplePath = r"\\192.168.1.28\share\数据\已完成数据\展厅数据\v2.0_abroad\比对数据\all_base_二筛"
# stdBarcodePath = r"\\192.168.1.28\share\测试视频数据以及日志\海外展厅测试数据\比对测试数据20250121_testing\bcdpath"
# stdFeaturePath = r"\\192.168.1.28\share\测试视频数据以及日志\海外展厅测试数据\比对测试数据20250121_testing\stdfeats"
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\数据\已完成数据\比对数据\barcode\all_totalBarocde\features_json\v11_barcode_0304"
if not os.path.exists(stdBarcodePath):
os.makedirs(stdBarcodePath)
if not os.path.exists(stdFeaturePath):
@ -719,18 +428,24 @@ if __name__ == '__main__':
"data": 基于事件切分的原 data 文件版本
"realtime": 全实时生成的 data 文件
'''
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"
source_type = 'source' # 'source', 'data', 'realtime'
simType = "typea" # "simple", "typea", "typeb"
eventDataPath = os.path.join(resultPath, "evtobjs_0304_1")
similPath = os.path.join(resultPath, "simidata_0304_1")
evttype = "single_event_V10"
# evttype = "single_event_V5"
# evttype = "performence_V10"
# evttype = "performence_V5"
eventSourcePath = "/home/wqg/dataset/pipeline/yrt/{}/shopping_pkl".format(evttype)
resultPath = "/home/wqg/dataset/pipeline/contrast/{}".format(evttype)
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)
test_one2one_one2SN()
test_one2one_one2SN(simType)

View File

@ -16,7 +16,11 @@ from pathlib import Path
import matplotlib.pyplot as plt
import sys
sys.path.append(r"D:\DetectTracking")
FILE = Path(__file__).resolve()
ROOT = FILE.parents[1] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT))
from tracking.utils.read_data import read_similar
def read_one2one_data(filepath):
@ -531,21 +535,23 @@ def contrast_pr(evtPaths):
# bcdSet = set(bcdList)
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 = 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 = 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")
# 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-3-3"
evtpaths = r"/home/wqg/dataset/test_base_dataset/single_event/source"
contrast_pr(evtpaths)

172
contrast/trail2trail.py Normal file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
取出再放回场景下商品轨迹特征比对方式与性能分析
Created on Tue Apr 1 17:17:47 2025
@author: wqg
"""
import os
import pickle
import random
import numpy as np
from pathlib import Path
import matplotlib.pyplot as plt
from scipy.spatial.distance import cdist
from utils.calsimi import calsiml, calsimi_vs_evts
def read_eventdict(evtpaths):
evtDict = {}
for filename in os.listdir(evtpaths):
evtname, ext = os.path.splitext(filename)
if ext != ".pickle": continue
evtpath = os.path.join(evtpaths, filename)
with open(evtpath, 'rb') as f:
evtdata = pickle.load(f)
evtDict[evtname] = evtdata
return evtDict
def compute_show_pr(Same, Cross):
TPFN = len(Same)
TNFP = len(Cross)
Recall_Pos, Recall_Neg = [], []
Precision_Pos, Precision_Neg = [], []
Correct = []
Thresh = np.linspace(-0.2, 1, 100)
for th in Thresh:
TP = np.sum(Same >= th)
FN = np.sum(Same < th)
# FN = TPFN - TP
TN = np.sum(Cross < th)
FP = np.sum(Cross >= th)
# FP = TNFP - TN
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, 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, 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.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()
plt.show()
# rltpath = os.path.join(similPath, f'pr_1to1_{simType}.png')
# plt.savefig(rltpath) # svg, png, pdf
fig, axes = plt.subplots(2,1)
axes[0].hist(Same, bins=60, range=(-0.2, 1), edgecolor='black')
axes[0].set_xlim([-0.2, 1])
axes[0].set_title(f'TP({len(Same)})')
axes[1].hist(Cross, bins=60, range=(-0.2, 1), edgecolor='black')
axes[1].set_xlim([-0.2, 1])
axes[1].set_title(f'TN({len(Cross)})')
# rltpath = os.path.join(similPath, f'hist_1to1_{simType}.png')
# plt.savefig(rltpath)
plt.show()
def trail_to_trail(evtpaths, rltpaths):
# select the method type of how to calculate the feat similarity of trail
simType = 2
##1. read all the ShoppingEvent object in the dir 'evtpaths'
evtDicts = read_eventdict(evtpaths)
##2. Combine event object with the same barcode
barcodes, evtpairDict = [], {}
for k in evtDicts.keys():
evt = k.split('_')
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
if not condt: continue
barcode = evt[-1]
if barcode not in evtpairDict.keys():
evtpairDict[barcode] = []
barcodes.append(barcode)
evtpairDict[barcode].append(evtDicts[k])
barcodes = set(barcodes)
AA_list, AB_list = [], []
for barcode in evtpairDict.keys():
events = evtpairDict[barcode]
if len(events)>1:
evta, evtb = random.sample(events, 2)
AA_list.append((evta, evtb, "same"))
evtc = random.sample(events, 1)[0]
dset = list(barcodes.symmetric_difference(set([barcode])))
bcd = random.sample(dset, 1)[0]
evtd = random.sample(evtpairDict[bcd], 1)[0]
AB_list.append((evtc, evtd, "diff"))
mergePairs = AA_list + AB_list
##3. calculate the similar of two event: evta, evtb
new_pirs = []
for evta, evtb, label in mergePairs:
similar = calsimi_vs_evts(evta, evtb, simType)
if similar is None:
continue
new_pirs.append((label, round(similar, 3), evta.evtname[:15], evtb.evtname[:15]))
##4. compute PR and showing
Same = np.array([s for label, s, _, _ in new_pirs if label=="same"])
Cross = np.array([s for label, s, _, _ in new_pirs if label=="diff"])
compute_show_pr(Same, Cross)
def main():
evttypes = ["single_event_V10", "single_event_V5", "performence_V10", "performence_V5"]
# evttypes = ["single_event_V10"]
for evttype in evttypes:
evtpaths = "/home/wqg/dataset/pipeline/contrast/{}/evtobjs/".format(evttype)
rltpaths = "/home/wqg/dataset/pipeline/yrt/{}/yolos_tracking".format(evttype)
trail_to_trail(evtpaths, rltpaths)
if __name__ == '__main__':
main()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

216
contrast/utils/calsimi.py Normal file
View File

@ -0,0 +1,216 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 31 16:25:43 2025
@author: wqg
"""
import numpy as np
from scipy.spatial.distance import cdist
def get_topk_percent(data, k):
"""
获取数据中最大的 k% 的元素
"""
# 将数据转换为 NumPy 数组
if isinstance(data, list):
data = np.array(data)
percentile = np.percentile(data, 100-k)
top_k_percent = data[data >= percentile]
return top_k_percent
def cluster(data, thresh=0.15):
# data = np.array([0.1, 0.13, 0.7, 0.2, 0.8, 0.52, 0.3, 0.7, 0.85, 0.58])
# data = np.array([0.1, 0.13, 0.2, 0.3])
# data = np.array([0.1])
if isinstance(data, list):
data = np.array(data)
data1 = np.sort(data)
cluter, Cluters, = [data1[0]], []
for i in range(1, len(data1)):
if data1[i] - data1[i-1]< thresh:
cluter.append(data1[i])
else:
Cluters.append(cluter)
cluter = [data1[i]]
Cluters.append(cluter)
clt_center = []
for clt in Cluters:
## 是否应该在此处限制一个聚类中的最小轨迹样本数,应该将该因素放在轨迹分析中
# if len(clt)>=3:
# clt_center.append(np.mean(clt))
clt_center.append(np.mean(clt))
# print(clt_center)
return clt_center
def calsiml(feat1, feat2, topkp=75, cluth=0.15):
'''轨迹样本和标准特征集样本相似度的选择策略'''
matrix = 1 - cdist(feat1, feat2, 'cosine')
simi_max = []
for i in range(len(matrix)):
sim = np.mean(get_topk_percent(matrix[i, :], topkp))
simi_max.append(sim)
cltc_max = cluster(simi_max, cluth)
Simi = max(cltc_max)
## cltc_max为空属于编程考虑不周应予以排查解决
# if len(cltc_max):
# Simi = max(cltc_max)
# else:
# Simi = 0 #不应该走到该处
return Simi
def calsimi_vs_stdfeat_new(event, stdfeat):
'''事件与标准库的对比策略
该比对策略是否可以拓展到事件与事件的比对?
'''
front_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
front_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(event.front_boxes)):
front_boxes = np.concatenate((front_boxes, event.front_boxes[i]), axis=0)
front_feats = np.concatenate((front_feats, event.front_feats[i]), axis=0)
back_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
back_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(event.back_boxes)):
back_boxes = np.concatenate((back_boxes, event.back_boxes[i]), axis=0)
back_feats = np.concatenate((back_feats, event.back_feats[i]), axis=0)
front_simi, back_simi = None, None
if len(front_feats):
front_simi = calsiml(front_feats, stdfeat)
if len(back_feats):
back_simi = calsiml(back_feats, stdfeat)
'''前后摄相似度融合策略'''
if len(front_feats) and len(back_feats):
diff_simi = abs(front_simi - back_simi)
if diff_simi>0.15:
Similar = max([front_simi, back_simi])
else:
Similar = (front_simi+back_simi)/2
elif len(front_feats) and len(back_feats)==0:
Similar = front_simi
elif len(front_feats)==0 and len(back_feats):
Similar = back_simi
else:
Similar = None # 在event.front_feats和event.back_feats同时为空时
return Similar, front_simi, back_simi
def calsimi_vs_stdfeat(event, stdfeat):
evtfeat = event.feats_compose
if isinstance(event.feats_select, list):
if len(event.feats_select) and len(event.feats_select[0]):
evtfeat = event.feats_select[0]
else:
return None, None, None
else:
evtfeat = event.feats_select
if len(evtfeat)==0 or len(stdfeat)==0:
return None, None, None
evtfeat /= np.linalg.norm(evtfeat, axis=1)[:, None]
stdfeat /= np.linalg.norm(stdfeat, axis=1)[:, None]
matrix = 1 - cdist(evtfeat, stdfeat, 'cosine')
matrix[matrix < 0] = 0
simi_mean = np.mean(matrix)
simi_max = np.max(matrix)
stdfeatm = np.mean(stdfeat, axis=0, keepdims=True)
evtfeatm = np.mean(evtfeat, axis=0, keepdims=True)
simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine'))
return simi_mean, simi_max, simi_mfeat[0,0]
def calsimi_vs_evts(evta, evtb, simType=1):
if simType==1:
if len(evta.feats_compose) and len(evtb.feats_compose):
feata = evta.feats_compose
featb = evtb.feats_compose
matrix = 1 - cdist(feata, featb, 'cosine')
similar = np.mean(matrix)
else:
similar = None
return similar
if simType==2:
if len(evta.feats_compose) and len(evtb.feats_compose):
feata = evta.feats_compose
featb = evtb.feats_compose
matrix = 1 - cdist(feata, featb, 'cosine')
similar = np.max(matrix)
else:
similar = None
return similar
if simType==3:
if len(evta.feats_compose) and len(evtb.feats_compose):
feata = evta.feats_compose
featb = evtb.feats_compose
similar = calsiml(feata, featb)
else:
similar = None
return similar
##1. the front feats of evta, evtb
fr_feata = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(evta.front_feats)):
fr_feata = np.concatenate((fr_feata, evta.front_feats[i]), axis=0)
fr_featb = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(evtb.front_feats)):
fr_featb = np.concatenate((fr_featb, evtb.front_feats[i]), axis=0)
##2. the back feats of evta, evtb
bk_feata = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(evta.back_feats)):
bk_feata = np.concatenate((bk_feata, evta.back_feats[i]), axis=0)
bk_featb = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容
for i in range(len(evtb.back_feats)):
bk_featb = np.concatenate((bk_featb, evtb.back_feats[i]), axis=0)
front_simi, back_simi = None, None
if len(fr_feata) and len(fr_featb):
front_simi = calsiml(fr_feata, fr_featb)
if len(bk_feata) and len(bk_featb):
back_simi = calsiml(bk_feata, bk_featb)
'''前后摄相似度融合策略'''
if front_simi is not None and back_simi is not None:
diff_simi = abs(front_simi - back_simi)
if diff_simi>0.15:
similar = max([front_simi, back_simi])
else:
similar = (front_simi+back_simi)/2
elif front_simi is not None and back_simi is None:
similar = front_simi
elif front_simi is None and back_simi is not None:
similar = back_simi
else:
similar = None # 在event.front_feats和event.back_feats同时为空时
return similar

127
contrast/utils/databits.py Normal file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 1 16:43:04 2025
@author: wqg
"""
import os
import pickle
import numpy as np
from scipy.spatial.distance import cdist
def int8_to_ft16(arr_uint8, amin, amax):
arr_ft16 = (arr_uint8 / 255 * (amax-amin) + amin).astype(np.float16)
return arr_ft16
def ft16_to_uint8(arr_ft16):
# pickpath = r"\\192.168.1.28\share\测试_202406\contrast\std_features_ft32vsft16\6902265587712_ft16.pickle"
# with open(pickpath, 'rb') as f:
# edict = pickle.load(f)
# arr_ft16 = edict['feats']
amin = np.min(arr_ft16)
amax = np.max(arr_ft16)
arr_ft255 = (arr_ft16 - amin) * 255 / (amax-amin)
arr_uint8 = arr_ft255.astype(np.uint8)
arr_ft16_ = int8_to_ft16(arr_uint8, amin, amax)
arrDistNorm = np.linalg.norm(arr_ft16_ - arr_ft16) / arr_ft16_.size
return arr_uint8, arr_ft16_
def data_precision_compare(stdfeat, evtfeat, evtMessage, similPath='', save=True):
evt, stdbcd, label = evtMessage
rltdata, rltdata_ft16, rltdata_ft16_ = [], [], []
matrix = 1 - cdist(stdfeat, evtfeat, 'cosine')
simi_mean = np.mean(matrix)
simi_max = np.max(matrix)
stdfeatm = np.mean(stdfeat, axis=0, keepdims=True)
evtfeatm = np.mean(evtfeat, axis=0, keepdims=True)
simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine'))
rltdata = [label, stdbcd, evt, simi_mean, simi_max, simi_mfeat[0,0]]
##================================================================= float16
stdfeat_ft16 = stdfeat.astype(np.float16)
evtfeat_ft16 = evtfeat.astype(np.float16)
stdfeat_ft16 /= np.linalg.norm(stdfeat_ft16, axis=1)[:, None]
evtfeat_ft16 /= np.linalg.norm(evtfeat_ft16, axis=1)[:, None]
matrix_ft16 = 1 - cdist(stdfeat_ft16, evtfeat_ft16, 'cosine')
simi_mean_ft16 = np.mean(matrix_ft16)
simi_max_ft16 = np.max(matrix_ft16)
stdfeatm_ft16 = np.mean(stdfeat_ft16, axis=0, keepdims=True)
evtfeatm_ft16 = np.mean(evtfeat_ft16, axis=0, keepdims=True)
simi_mfeat_ft16 = 1- np.maximum(0.0, cdist(stdfeatm_ft16, evtfeatm_ft16, 'cosine'))
rltdata_ft16 = [label, stdbcd, evt, simi_mean_ft16, simi_max_ft16, simi_mfeat_ft16[0,0]]
'''****************** uint8 is ok!!!!!! ******************'''
##=================================================================== uint8
# stdfeat_uint8, stdfeat_ft16_ = ft16_to_uint8(stdfeat_ft16)
# evtfeat_uint8, evtfeat_ft16_ = ft16_to_uint8(evtfeat_ft16)
stdfeat_uint8 = (stdfeat_ft16*128).astype(np.int8)
evtfeat_uint8 = (evtfeat_ft16*128).astype(np.int8)
stdfeat_ft16_ = stdfeat_uint8.astype(np.float16)/128
evtfeat_ft16_ = evtfeat_uint8.astype(np.float16)/128
absdiff = np.linalg.norm(stdfeat_ft16_ - stdfeat) / stdfeat.size
matrix_ft16_ = 1 - cdist(stdfeat_ft16_, evtfeat_ft16_, 'cosine')
simi_mean_ft16_ = np.mean(matrix_ft16_)
simi_max_ft16_ = np.max(matrix_ft16_)
stdfeatm_ft16_ = np.mean(stdfeat_ft16_, axis=0, keepdims=True)
evtfeatm_ft16_ = np.mean(evtfeat_ft16_, axis=0, keepdims=True)
simi_mfeat_ft16_ = 1- np.maximum(0.0, cdist(stdfeatm_ft16_, evtfeatm_ft16_, 'cosine'))
rltdata_ft16_ = [label, stdbcd, evt, simi_mean_ft16_, simi_max_ft16_, simi_mfeat_ft16_[0,0]]
if not save:
return
##========================================================= save as float32
rppath = os.path.join(similPath, f'{evt}_ft32.pickle')
with open(rppath, 'wb') as f:
pickle.dump(rltdata, f)
rtpath = os.path.join(similPath, f'{evt}_ft32.txt')
with open(rtpath, 'w', encoding='utf-8') as f:
for result in rltdata:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')
##========================================================= save as float16
rppath_ft16 = os.path.join(similPath, f'{evt}_ft16.pickle')
with open(rppath_ft16, 'wb') as f:
pickle.dump(rltdata_ft16, f)
rtpath_ft16 = os.path.join(similPath, f'{evt}_ft16.txt')
with open(rtpath_ft16, 'w', encoding='utf-8') as f:
for result in rltdata_ft16:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')
##=========================================================== save as uint8
rppath_uint8 = os.path.join(similPath, f'{evt}_uint8.pickle')
with open(rppath_uint8, 'wb') as f:
pickle.dump(rltdata_ft16_, f)
rtpath_uint8 = os.path.join(similPath, f'{evt}_uint8.txt')
with open(rtpath_uint8, 'w', encoding='utf-8') as f:
for result in rltdata_ft16_:
part = [f"{x:.3f}" if isinstance(x, float) else str(x) for x in result]
line = ', '.join(part)
f.write(line + '\n')

View File

@ -5,19 +5,25 @@ Created on Tue Nov 26 17:35:05 2024
@author: ym
"""
import os
import sys
import cv2
import pickle
import numpy as np
from pathlib import Path
import sys
sys.path.append(r"D:\DetectTracking")
FILE = Path(__file__).resolve()
ROOT = FILE.parents[2] # YOLOv5 root directory
if str(ROOT) not in sys.path:
sys.path.append(str(ROOT))
from tracking.utils.plotting import Annotator, colors
from tracking.utils.drawtracks import drawTrack
from tracking.utils.read_data import extract_data, read_tracking_output, read_similar
from tracking.utils.read_data import extract_data_realtime, read_tracking_output_realtime
# import platform
# import pathlib
# plt = platform.system()

View File

@ -4,8 +4,81 @@ Created on Thu Oct 31 15:17:01 2024
@author: ym
"""
import os
import numpy as np
import pickle
from pathlib import Path
import matplotlib.pyplot as plt
from .event import ShoppingEvent
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 evtname in os.listdir(sourcePath):
bname, ext = os.path.splitext(evtname)
source_path = os.path.join(sourcePath, evtname)
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
evt = bname.split('_')
condt = len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10
if not condt: 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(evtname)
except Exception as e:
errEvents.append(source_path)
print(f"Error: {evtname}, {e}")
# k += 1
# if k==1:
# break
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')
def get_evtList(evtpath):
'''==== 0. 生成事件列表和对应的 Barcodes 集合 ==========='''
bcdList, evtpaths = [], []
for evtname in os.listdir(evtpath):
bname, ext = os.path.splitext(evtname)
## 处理事件的两种情况:文件夹 和 Yolo-Resnet-Tracker 的输出
fpath = os.path.join(evtpath, 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])
evtpaths.append(fpath)
bcdSet = set(bcdList)
return evtpaths, bcdSet