modify 1:1 比对方式
This commit is contained in:
@ -11,7 +11,7 @@ Created on Fri Aug 30 17:53:03 2024
|
||||
标准特征提取,并保存至文件夹 stdFeaturePath 中,
|
||||
也可在运行过程中根据与购物事件集合 barcodes 交集执行
|
||||
2. 1:1 比对性能测试,
|
||||
func: one2one_eval(resultPath)
|
||||
func: one2one_eval(similPath)
|
||||
(1) 求购物事件和标准特征级 Barcode 交集,构造 evtDict、stdDict
|
||||
(2) 构造扫 A 放 A、扫 A 放 B 组合,mergePairs = AA_list + AB_list
|
||||
(3) 循环计算 mergePairs 中元素 "(A, A) 或 (A, B)" 相似度;
|
||||
@ -32,6 +32,7 @@ import os
|
||||
import sys
|
||||
import random
|
||||
import pickle
|
||||
import json
|
||||
# import torch
|
||||
import time
|
||||
# import json
|
||||
@ -47,10 +48,12 @@ from datetime import datetime
|
||||
# from feat_inference import inference_image
|
||||
|
||||
sys.path.append(r"D:\DetectTracking")
|
||||
from tracking.utils.read_data import extract_data, read_tracking_output, read_one2one_simi, read_deletedBarcode_file
|
||||
|
||||
from config import config as conf
|
||||
from genfeats import model_init, genfeatures, stdfeat_infer
|
||||
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 Event
|
||||
from genfeats import gen_bcd_features
|
||||
|
||||
IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
|
||||
|
||||
@ -107,6 +110,10 @@ def creat_shopping_event(eventPath):
|
||||
evtType = 'other'
|
||||
|
||||
'''================ 1. 构造事件描述字典,暂定 9 items ==============='''
|
||||
|
||||
|
||||
|
||||
|
||||
event = {}
|
||||
event['barcode'] = barcode
|
||||
event['type'] = evtType
|
||||
@ -118,7 +125,8 @@ def creat_shopping_event(eventPath):
|
||||
event['back_feats'] = np.empty((0, 256), dtype=np.float64)
|
||||
event['front_feats'] = np.empty((0, 256), dtype=np.float64)
|
||||
event['feats_compose'] = np.empty((0, 256), dtype=np.float64)
|
||||
event['one2one_simi'] = None
|
||||
event['one2one'] = None
|
||||
event['one2n'] = None
|
||||
event['feats_select'] = np.empty((0, 256), dtype=np.float64)
|
||||
|
||||
|
||||
@ -145,8 +153,9 @@ def creat_shopping_event(eventPath):
|
||||
event['front_feats'] = tracking_output_feats
|
||||
|
||||
if dataname.find("process.data")==0:
|
||||
simiDict = read_one2one_simi(datapath)
|
||||
event['one2one_simi'] = simiDict
|
||||
simiDict = read_similar(datapath)
|
||||
event['one2one'] = simiDict['one2one']
|
||||
event['one2n'] = simiDict['one2n']
|
||||
|
||||
|
||||
if len(event['back_boxes'])==0 or len(event['front_boxes'])==0:
|
||||
@ -215,6 +224,52 @@ def creat_shopping_event(eventPath):
|
||||
return event
|
||||
|
||||
|
||||
|
||||
|
||||
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):
|
||||
'''
|
||||
功能: 保存一次购物事件的轨迹子图
|
||||
@ -224,160 +279,92 @@ def save_event_subimg(event, savepath):
|
||||
子图保存次序:先前摄、后后摄,以 k 为编号,和 "feats_compose" 中次序相同
|
||||
'''
|
||||
cameras = ('front', 'back')
|
||||
k = 0
|
||||
for camera in cameras:
|
||||
if camera == 'front':
|
||||
boxes = event['front_boxes']
|
||||
imgpaths = event['front_imgpaths']
|
||||
boxes = event.front_boxes
|
||||
imgpaths = event.front_imgpaths
|
||||
else:
|
||||
boxes = event['back_boxes']
|
||||
imgpaths = event['back_imgpaths']
|
||||
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[i]
|
||||
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"{k}_cam-{camerType}_tid-{int(tid)}_fid-({int(fid)}, {frameID}).png"
|
||||
subimgName = f"cam{camerType}_{i}_tid{int(tid)}_fid({int(fid)}, {frameID}).png"
|
||||
spath = os.path.join(savepath, subimgName)
|
||||
|
||||
cv2.imwrite(spath, subimg)
|
||||
k += 1
|
||||
# basename = os.path.basename(event['filepath'])
|
||||
print(f"Image saved: {os.path.basename(event['filepath'])}")
|
||||
|
||||
|
||||
print(f"Image saved: {os.path.basename(event.eventpath)}")
|
||||
|
||||
def one2one_eval(resultPath):
|
||||
|
||||
# stdBarcode = [p.stem for p in Path(stdFeaturePath).iterdir() if p.is_file() and p.suffix=='.pickle']
|
||||
stdBarcode = [p.stem for p in Path(stdBarcodePath).iterdir() if p.is_file() and p.suffix=='.pickle']
|
||||
|
||||
|
||||
'''购物事件列表,该列表中的 Barcode 存在于标准的 stdBarcode 内'''
|
||||
evtList = [(p.stem, p.stem.split('_')[-1]) for p in Path(eventFeatPath).iterdir()
|
||||
if p.is_file()
|
||||
and p.suffix=='.pickle'
|
||||
and (len(p.stem.split('_'))==2 or len(p.stem.split('_'))==3)
|
||||
and p.stem.split('_')[-1].isdigit()
|
||||
and p.stem.split('_')[-1] in stdBarcode
|
||||
]
|
||||
|
||||
barcodes = set([bcd for _, bcd in evtList])
|
||||
|
||||
'''标准特征集图像样本经特征提取并保存,运行一次后无需再运行'''
|
||||
stdfeat_infer(stdBarcodePath, stdFeaturePath, barcodes)
|
||||
|
||||
'''========= 构建用于比对的标准特征字典 ============='''
|
||||
stdDict = {}
|
||||
for barcode in barcodes:
|
||||
stdpath = os.path.join(stdFeaturePath, barcode+'.pickle')
|
||||
with open(stdpath, 'rb') as f:
|
||||
stddata = pickle.load(f)
|
||||
stdDict[barcode] = stddata
|
||||
|
||||
'''========= 构建用于比对的操作事件字典 ============='''
|
||||
evtDict = {}
|
||||
for event, barcode in evtList:
|
||||
evtpath = os.path.join(eventFeatPath, event+'.pickle')
|
||||
with open(evtpath, 'rb') as f:
|
||||
evtdata = pickle.load(f)
|
||||
evtDict[event] = evtdata
|
||||
|
||||
|
||||
'''===== 构造 3 个事件对: 扫 A 放 A, 扫 A 放 B, 合并 ===================='''
|
||||
AA_list = [(event, barcode, "same") for event, barcode in evtList]
|
||||
AB_list = []
|
||||
for event, barcode in evtList:
|
||||
dset = list(barcodes.symmetric_difference(set([barcode])))
|
||||
idx = random.randint(0, len(dset)-1)
|
||||
AB_list.append((event, dset[idx], "diff"))
|
||||
|
||||
mergePairs = AA_list + AB_list
|
||||
|
||||
'''读取事件、标准特征文件中数据,以 AA_list 和 AB_list 中关键字为 key 生成字典'''
|
||||
rltdata, rltdata_ft16, rltdata_ft16_ = [], [], []
|
||||
for evt, stdbcd, label in mergePairs:
|
||||
event = evtDict[evt]
|
||||
|
||||
## 判断是否存在轨迹图像文件夹,不存在则创建文件夹并保存轨迹图像
|
||||
pairpath = os.path.join(subimgPath, f"{evt}")
|
||||
if not os.path.exists(pairpath):
|
||||
os.makedirs(pairpath)
|
||||
save_event_subimg(event, pairpath)
|
||||
|
||||
## 判断是否存在 barcode 标准样本集图像文件夹,不存在则创建文件夹并存储 barcode 样本集图像
|
||||
stdImgpath = stdDict[stdbcd]["imgpaths"]
|
||||
pstdpath = os.path.join(subimgPath, f"{stdbcd}")
|
||||
if not os.path.exists(pstdpath):
|
||||
os.makedirs(pstdpath)
|
||||
ii = 1
|
||||
for filepath in stdImgpath:
|
||||
stdpath = os.path.join(pstdpath, f"{stdbcd}_{ii}.png")
|
||||
shutil.copy2(filepath, stdpath)
|
||||
ii += 1
|
||||
|
||||
##============================================ float32
|
||||
stdfeat = stdDict[stdbcd]["feats"]
|
||||
evtfeat = event["feats_compose"]
|
||||
|
||||
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.append((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.append((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_.append((label, stdbcd, evt, simi_mean_ft16_, simi_max_ft16_, simi_mfeat_ft16_[0,0]))
|
||||
|
||||
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]]
|
||||
|
||||
tm = datetime.fromtimestamp(time.time()).strftime('%Y%m%d_%H%M%S')
|
||||
##================================================ save as float32,
|
||||
rppath = os.path.join(resultPath, f'{tm}.pickle')
|
||||
|
||||
##================================================================= 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(resultPath, f'{tm}.txt')
|
||||
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]
|
||||
@ -385,12 +372,12 @@ def one2one_eval(resultPath):
|
||||
f.write(line + '\n')
|
||||
|
||||
|
||||
##================================================ save as float16,
|
||||
rppath_ft16 = os.path.join(resultPath, f'{tm}_ft16.pickle')
|
||||
##========================================================= 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(resultPath, f'{tm}_ft16.txt')
|
||||
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]
|
||||
@ -398,42 +385,145 @@ def one2one_eval(resultPath):
|
||||
f.write(line + '\n')
|
||||
|
||||
|
||||
##================================================ save as uint8,
|
||||
rppath_uint8 = os.path.join(resultPath, f'{tm}_uint8.pickle')
|
||||
##=========================================================== 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(resultPath, f'{tm}_uint8.txt')
|
||||
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 one2one_simi():
|
||||
'''
|
||||
stdFeaturePath: 标准特征集地址
|
||||
eventDataPath: Event对象地址
|
||||
'''
|
||||
|
||||
stdBarcode = [p.stem for p in Path(stdFeaturePath).iterdir() if p.is_file() and p.suffix=='.pickle']
|
||||
|
||||
'''======1. 购物事件列表,该列表中的 Barcode 存在于标准的 stdBarcode 内 ==='''
|
||||
evtList = [(p.stem, p.stem.split('_')[-1]) for p in Path(eventDataPath).iterdir()
|
||||
if p.is_file()
|
||||
and p.suffix=='.pickle'
|
||||
and (len(p.stem.split('_'))==2 or len(p.stem.split('_'))==3)
|
||||
and p.stem.split('_')[-1].isdigit()
|
||||
and p.stem.split('_')[-1] in stdBarcode
|
||||
]
|
||||
barcodes = set([bcd for _, bcd in evtList])
|
||||
|
||||
'''======2. 构建用于比对的标准特征字典 ============='''
|
||||
stdDict = {}
|
||||
for barcode in barcodes:
|
||||
stdpath = os.path.join(stdFeaturePath, barcode+'.pickle')
|
||||
with open(stdpath, 'rb') as f:
|
||||
stddata = pickle.load(f)
|
||||
stdDict[barcode] = stddata
|
||||
|
||||
|
||||
'''======3. 构建用于比对的操作事件字典 ============='''
|
||||
evtDict = {}
|
||||
for evtname, barcode in evtList:
|
||||
evtpath = os.path.join(eventDataPath, evtname+'.pickle')
|
||||
with open(evtpath, 'rb') as f:
|
||||
evtdata = pickle.load(f)
|
||||
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:
|
||||
save_event_subimg(event, pairpath)
|
||||
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:
|
||||
plot_save_image(event, img_path)
|
||||
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"]
|
||||
# pstdpath = os.path.join(subimgPath, f"{stdbcd}")
|
||||
# if not os.path.exists(pstdpath):
|
||||
# os.makedirs(pstdpath)
|
||||
# ii = 1
|
||||
# for filepath in stdImgpath:
|
||||
# stdpath = os.path.join(pstdpath, f"{stdbcd}_{ii}.png")
|
||||
# shutil.copy2(filepath, stdpath)
|
||||
# ii += 1
|
||||
|
||||
'''======5 构造 3 个事件对: 扫 A 放 A, 扫 A 放 B, 合并 ===================='''
|
||||
AA_list = [(evtname, barcode, "same") for evtname, barcode in evtList]
|
||||
AB_list = []
|
||||
for evtname, barcode in evtList:
|
||||
dset = list(barcodes.symmetric_difference(set([barcode])))
|
||||
if len(dset):
|
||||
idx = random.randint(0, len(dset)-1)
|
||||
AB_list.append((evtname, dset[idx], "diff"))
|
||||
|
||||
mergePairs = AA_list + AB_list
|
||||
|
||||
'''======6 计算事件、标准特征集相似度 =================='''
|
||||
rltdata = []
|
||||
for i in range(len(mergePairs)):
|
||||
evtname, stdbcd, label = mergePairs[i]
|
||||
event = evtDict[evtname]
|
||||
|
||||
##============================================ float32
|
||||
stdfeat = stdDict[stdbcd]["feats_ft32"]
|
||||
evtfeat = event.feats_compose
|
||||
|
||||
if len(evtfeat)==0: continue
|
||||
|
||||
matrix = 1 - cdist(stdfeat, evtfeat, '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'))
|
||||
rltdata.append((label, stdbcd, evtname, simi_mean, simi_max, simi_mfeat[0,0]))
|
||||
|
||||
'''================ float32、16、int8 精度比较与存储 ============='''
|
||||
# data_precision_compare(stdfeat, evtfeat, mergePairs[i], save=True)
|
||||
|
||||
print("func: one2one_eval(), have finished!")
|
||||
|
||||
return rltdata
|
||||
|
||||
|
||||
|
||||
|
||||
def compute_precise_recall(pickpath):
|
||||
|
||||
pickfile = os.path.basename(pickpath)
|
||||
file, ext = os.path.splitext(pickfile)
|
||||
|
||||
if ext != '.pickle': return
|
||||
if file.find('ft16') < 0: return
|
||||
|
||||
with open(pickpath, 'rb') as f:
|
||||
results = pickle.load(f)
|
||||
|
||||
def compute_precise_recall(rltdata):
|
||||
Same, Cross = [], []
|
||||
for label, stdbcd, evt, simi_mean, simi_max, simi_mft in results:
|
||||
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)
|
||||
TPFN = len(Same)
|
||||
@ -480,115 +570,135 @@ def compute_precise_recall(pickpath):
|
||||
ax.set_xlabel(f"Same Num: {TPFN}, Cross Num: {TNFP}")
|
||||
ax.legend()
|
||||
plt.show()
|
||||
plt.savefig(f'./result/{file}_pr.png') # svg, png, pdf
|
||||
|
||||
rltpath = os.path.join(similPath, 'pr.png')
|
||||
plt.savefig(rltpath) # svg, png, pdf
|
||||
|
||||
|
||||
|
||||
def gen_eventdict(eventDatePath, saveimg=True):
|
||||
def gen_eventdict(sourcePath, saveimg=True):
|
||||
eventList = []
|
||||
# k = 0
|
||||
for datePath in eventDatePath:
|
||||
for eventName in os.listdir(datePath):
|
||||
errEvents = []
|
||||
k = 0
|
||||
for source_path in sourcePath:
|
||||
bname = os.path.basename(source_path)
|
||||
|
||||
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
|
||||
if os.path.isfile(pickpath): continue
|
||||
|
||||
# if bname != "20241129-100321-a9dae9e3-7db5-4e31-959c-d7dfc228923e_6972636670213":
|
||||
# continue
|
||||
|
||||
pickpath = os.path.join(eventFeatPath, f"{eventName}.pickle")
|
||||
if os.path.isfile(pickpath):
|
||||
continue
|
||||
eventPath = os.path.join(datePath, eventName)
|
||||
|
||||
|
||||
# eventDict = creat_shopping_event(eventPath)
|
||||
# if eventDict:
|
||||
# eventList.append(eventDict)
|
||||
# with open(pickpath, 'wb') as f:
|
||||
# pickle.dump(eventDict, f)
|
||||
# print(f"Event: {eventName}, have saved!")
|
||||
|
||||
eventDict = creat_shopping_event(eventPath)
|
||||
if eventDict:
|
||||
eventList.append(eventDict)
|
||||
with open(pickpath, 'wb') as f:
|
||||
pickle.dump(eventDict, f)
|
||||
print(f"Event: {eventName}, have saved!")
|
||||
# if saveimg and eventDict:
|
||||
# basename = os.path.basename(eventDict['filepath'])
|
||||
# savepath = os.path.join(subimgPath, basename)
|
||||
# if not os.path.exists(savepath):
|
||||
# os.makedirs(savepath)
|
||||
# save_event_subimg(eventDict, savepath)
|
||||
|
||||
try:
|
||||
event = Event(source_path)
|
||||
eventList.append(event)
|
||||
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==10:
|
||||
# break
|
||||
|
||||
# k += 1
|
||||
# if k==1:
|
||||
# break
|
||||
|
||||
## 保存轨迹中 boxes 子图
|
||||
if not saveimg:
|
||||
return
|
||||
for event in eventList:
|
||||
basename = os.path.basename(event['filepath'])
|
||||
savepath = os.path.join(subimgPath, basename)
|
||||
if not os.path.exists(savepath):
|
||||
os.makedirs(savepath)
|
||||
save_event_subimg(event, savepath)
|
||||
errfile = os.path.join(eventDataPath, f'error_events.txt')
|
||||
with open(errfile, 'w', encoding='utf-8') as f:
|
||||
for line in errEvents:
|
||||
f.write(line + '\n')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def test_one2one():
|
||||
eventDatePath = [r'\\192.168.1.28\share\测试_202406\1101\images',
|
||||
# r'\\192.168.1.28\share\测试_202406\0910\images',
|
||||
# r'\\192.168.1.28\share\测试_202406\0723\0723_1',
|
||||
# r'\\192.168.1.28\share\测试_202406\0723\0723_2',
|
||||
# r'\\192.168.1.28\share\测试_202406\0723\0723_3',
|
||||
# r'\\192.168.1.28\share\测试_202406\0722\0722_01',
|
||||
# r'\\192.168.1.28\share\测试_202406\0722\0722_02'
|
||||
# r'\\192.168.1.28\share\测试_202406\0719\719_3',
|
||||
# r'\\192.168.1.28\share\测试_202406\0716\0716_1',
|
||||
# r'\\192.168.1.28\share\测试_202406\0716\0716_2',
|
||||
# r'\\192.168.1.28\share\测试_202406\0716\0716_3',
|
||||
# r'\\192.168.1.28\share\测试_202406\0712\0712_1', # 无帧图像
|
||||
# r'\\192.168.1.28\share\测试_202406\0712\0712_2', # 无帧图像
|
||||
]
|
||||
bcdList = []
|
||||
for evtpath in eventDatePath:
|
||||
bcdList, event_spath = [], []
|
||||
for evtpath in eventSourcePath:
|
||||
for evtname in os.listdir(evtpath):
|
||||
evt = evtname.split('_')
|
||||
dirpath = os.path.join(evtpath, evtname)
|
||||
if os.path.isfile(dirpath): continue
|
||||
if len(evt)>=2 and evt[-1].isdigit() and len(evt[-1])>=10:
|
||||
bcdList.append(evt[-1])
|
||||
|
||||
bcdList.append(evt[-1])
|
||||
event_spath.append(os.path.join(evtpath, evtname))
|
||||
|
||||
bcdSet = set(bcdList)
|
||||
|
||||
|
||||
|
||||
|
||||
model = model_init(conf)
|
||||
|
||||
'''==== 1. 生成标准特征集, 只需运行一次 ==============='''
|
||||
genfeatures(model, stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet)
|
||||
'''==== 1. 生成标准特征集, 只需运行一次, 在 genfeats.py 中实现 ==========='''
|
||||
# gen_bcd_features(stdSamplePath, stdBarcodePath, stdFeaturePath, bcdSet)
|
||||
print("stdFeats have generated and saved!")
|
||||
|
||||
|
||||
'''==== 2. 生成事件字典, 只需运行一次 ==============='''
|
||||
|
||||
gen_eventdict(eventDatePath)
|
||||
gen_eventdict(event_spath)
|
||||
print("eventList have generated and saved!")
|
||||
|
||||
|
||||
'''==== 3. 1:1性能评估 ==============='''
|
||||
one2one_eval(resultPath)
|
||||
for filename in os.listdir(resultPath):
|
||||
if filename.find('.pickle') < 0: continue
|
||||
if filename.find('0911') < 0: continue
|
||||
pickpath = os.path.join(resultPath, filename)
|
||||
compute_precise_recall(pickpath)
|
||||
|
||||
|
||||
rltdata = one2one_simi()
|
||||
compute_precise_recall(rltdata)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
'''
|
||||
共6个地址:
|
||||
共7个地址:
|
||||
(1) stdSamplePath: 用于生成比对标准特征集的原始图像地址
|
||||
(2) stdBarcodePath: 比对标准特征集原始图像地址的pickle文件存储,{barcode: [imgpath1, imgpath1, ...]}
|
||||
(3) stdFeaturePath: 比对标准特征集特征存储地址
|
||||
(4) eventFeatPath: 用于1:1比对的购物事件特征存储地址、对应子图存储地址
|
||||
(5) subimgPath: 1:1比对购物事件轨迹、标准barcode所对应的 subimgs 存储地址
|
||||
(6) resultPath: 1:1比对结果存储地址
|
||||
(4) eventSourcePath: 事件地址
|
||||
(5) resultPath: 结果存储地址
|
||||
(6) eventDataPath: 用于1:1比对的购物事件特征存储地址、对应子图存储地址
|
||||
(7) subimgPath: 1:1比对购物事件轨迹、标准barcode所对应的 subimgs 存储地址
|
||||
(8) similPath: 1:1比对结果存储地址(事件级)
|
||||
'''
|
||||
|
||||
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"
|
||||
eventFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\events"
|
||||
subimgPath = r'\\192.168.1.28\share\测试_202406\contrast\subimgs'
|
||||
resultPath = r"D:\DetectTracking\contrast\result\pickle"
|
||||
if not os.path.exists(resultPath):
|
||||
os.makedirs(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测试"]
|
||||
|
||||
|
||||
|
||||
'''定义当前事件存储地址及生成相应文件件'''
|
||||
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")
|
||||
|
||||
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)
|
||||
|
||||
test_one2one()
|
||||
|
||||
|
Reference in New Issue
Block a user