418 lines
16 KiB
Python
418 lines
16 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Sat Jul 27 14:07:25 2024
|
|
|
|
@author: ym
|
|
"""
|
|
import os.path
|
|
import numpy as np
|
|
from scipy.spatial.distance import cdist
|
|
import matplotlib.pyplot as plt
|
|
import sys
|
|
sys.path.append(r"D:\DetectTracking")
|
|
from tracking.utils.read_data import extract_data, read_deletedBarcode_file, read_tracking_output
|
|
from tracking.dotrack.dotracks import Track
|
|
|
|
from tracking.contrast_analysis import performance_evaluate, compute_recall_precision, show_recall_prec
|
|
|
|
def compute_similar(feat1, feat2):
|
|
|
|
if len(feat1)==0 or len(feat2)==0:
|
|
return 0
|
|
|
|
similar = 1 - np.maximum(0.0, cdist(feat1, feat2, metric = 'cosine'))
|
|
smean = np.mean(similar)
|
|
|
|
return smean
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def update_event(datapath):
|
|
'''一次购物事件,包含 8 个keys'''
|
|
event = {}
|
|
# event['front_tracking_boxes'] = []
|
|
# event['front_tracking_feats'] = {}
|
|
# event['back_tracking_boxes'] = []
|
|
# event['back_tracking_feats'] = {}
|
|
|
|
event['back_sole_boxes'] = np.empty((0, 9), dtype=np.float64)
|
|
event['front_sole_boxes'] = np.empty((0, 9), dtype=np.float64)
|
|
|
|
event['back_sole_feats'] = np.empty((0, 256), dtype=np.float64)
|
|
event['front_sole_feats'] = np.empty((0, 256), dtype=np.float64)
|
|
|
|
event['feats_compose'] = np.empty((0, 256), dtype=np.float64)
|
|
event['feats_select'] = np.empty((0, 256), dtype=np.float64)
|
|
|
|
'''读取当前事件的 data 文件'''
|
|
for filename in os.listdir(datapath):
|
|
# filename = '1_track.data'
|
|
fpath = os.path.join(datapath, filename)
|
|
CamerType = filename.split('_')[0]
|
|
# if os.path.isfile(fpath) and filename.find("track.data")>0:
|
|
# bboxes, ffeats, trackerboxes, tracker_feat_dict, tracking_boxes, tracking_feat_dict = extract_data(fpath)
|
|
|
|
# if CamerType == '0':
|
|
# event['back_tracking_boxes'] = tracking_boxes
|
|
# event['back_tracking_feats'] = tracking_feat_dict
|
|
# elif CamerType == '1':
|
|
# event['front_tracking_boxes'] = tracking_boxes
|
|
# event['front_tracking_feats'] = tracking_feat_dict
|
|
|
|
|
|
|
|
if os.path.isfile(fpath) and filename.find("tracking_output.data")>0:
|
|
tracking_output_boxes, tracking_output_feats = read_tracking_output(fpath)
|
|
if CamerType == '0':
|
|
event['back_sole_boxes'] = tracking_output_boxes
|
|
event['back_sole_feats'] = tracking_output_feats
|
|
elif CamerType == '1':
|
|
event['front_sole_boxes'] = tracking_output_boxes
|
|
event['front_sole_feats'] = tracking_output_feats
|
|
|
|
|
|
'''事件的特征表征方式选择'''
|
|
|
|
fs_feats = event['front_sole_feats']
|
|
bs_feats = event['back_sole_feats']
|
|
|
|
'''1. 如果前后摄均没有轨迹选择输出,返回'''
|
|
condt1 = len(fs_feats) + len(bs_feats) == 0
|
|
if condt1:
|
|
return event
|
|
|
|
|
|
'''2. 构造综合特征'''
|
|
feats_compose = np.empty((0, 256), dtype=np.float64)
|
|
if len(fs_feats):
|
|
feats_compose = np.concatenate((feats_compose, fs_feats), axis=0)
|
|
if len(bs_feats):
|
|
feats_compose = np.concatenate((feats_compose, bs_feats), axis=0)
|
|
event['feats_compose'] = feats_compose
|
|
|
|
'''3. 构造前摄特征'''
|
|
if len(fs_feats):
|
|
event['feats_select'] = fs_feats
|
|
return event
|
|
|
|
|
|
'''4. 从前摄输出轨迹中选取特定轨迹对应的特征'''
|
|
ftrboxes = event['front_tracking_boxes']
|
|
ftrfeats = event['front_tracking_feats']
|
|
|
|
condt2 = len(ftrboxes) + len(ftrfeats) == 0
|
|
condt3 = len(ftrfeats) != len(ftrboxes)
|
|
if condt2 or condt3:
|
|
return event
|
|
|
|
bprops = []
|
|
for boxes in ftrboxes:
|
|
track = Track(boxes)
|
|
bprops.append(max(track.trajdist))
|
|
|
|
index = bprops.index(max(bprops))
|
|
box_select = ftrboxes[index]
|
|
tid = int(box_select[0, 4])
|
|
|
|
feat_select = ftrfeats[f"track_{tid}"]
|
|
feats_select = np.empty((0, 256), dtype=np.float64)
|
|
for fid_bid, feat in feat_select['feats'].items():
|
|
feats_select = np.concatenate((feats_select, feat[None, :]), axis=0)
|
|
event['feats_select'] = feats_select
|
|
|
|
return event
|
|
|
|
|
|
def creatd_deletedBarcode_front(filepath):
|
|
# filepath = r'\\192.168.1.28\share\测试_202406\0723\0723_1\deletedBarcode.txt'
|
|
|
|
basepath, _ = os.path.split(filepath)
|
|
|
|
MatchList = []
|
|
|
|
bcdlist = read_deletedBarcode_file(filepath)
|
|
|
|
k = 0
|
|
for s_list in bcdlist:
|
|
getout_fold = s_list['SeqDir'].strip()
|
|
day, hms = getout_fold.strip('_').split('-')
|
|
|
|
''' 生成取出事件字典 '''
|
|
getout_event = {}
|
|
getout_event['barcode'] = s_list['Deleted'].strip()
|
|
getout_event['path'] = os.path.join(basepath, getout_fold)
|
|
|
|
getout_event['feats_compose'] = np.empty((0, 256), dtype=np.float64)
|
|
getout_event['feats_select'] = np.empty((0, 256), dtype=np.float64)
|
|
|
|
|
|
InputList = []
|
|
barcodes = [s.strip() for s in s_list['barcode']]
|
|
similarity = [float(s.strip()) for s in s_list['similarity']]
|
|
for i, barcode in enumerate(barcodes):
|
|
|
|
''' 生成放入事件字典 '''
|
|
input_event = {}
|
|
|
|
input_folds, times = [], []
|
|
for pathname in os.listdir(basepath):
|
|
if pathname.endswith('_'): continue
|
|
if os.path.isfile(os.path.join(basepath, pathname)):continue
|
|
|
|
infold = pathname.split('_')
|
|
if len(infold)!=2: continue
|
|
|
|
day1, hms1 = infold[0].split('-')
|
|
|
|
if day1==day and infold[1]==barcode and int(hms1)<int(hms):
|
|
input_folds.append(pathname)
|
|
times.append(int(hms1))
|
|
|
|
''' 根据时间排序,选择离取出操作最近时间的文件夹,作为取出操作应的放入操作所对应的文件夹 '''
|
|
input_path = ''
|
|
if len(input_folds):
|
|
indice = np.argsort(np.array(times))
|
|
input_fold = input_folds[indice[-1]]
|
|
input_path = os.path.join(basepath, input_fold)
|
|
|
|
input_event['barcode'] = barcode
|
|
input_event['path'] = input_path
|
|
input_event['similarity'] = float(similarity[i])
|
|
input_event['feats_compose'] = np.empty((0, 256), dtype=np.float64)
|
|
input_event['feats_select'] = np.empty((0, 256), dtype=np.float64)
|
|
|
|
|
|
InputList.append(input_event)
|
|
|
|
MatchList.append((getout_event, InputList))
|
|
|
|
# k += 1
|
|
# if k==2:
|
|
# break
|
|
print('Step 1 Done!')
|
|
|
|
for getout_event, InputList in MatchList:
|
|
getout_path = getout_event['path']
|
|
if os.path.exists(getout_path) and os.path.isdir(getout_path):
|
|
event = update_event(getout_path)
|
|
getout_event.update(event)
|
|
|
|
for input_event in InputList:
|
|
input_path = input_event['path']
|
|
if os.path.exists(input_path) and os.path.isdir(input_path):
|
|
event = update_event(input_path)
|
|
input_event.update(event)
|
|
|
|
print('Step 2 Done!')
|
|
|
|
results = []
|
|
for getout_event, InputList in MatchList:
|
|
getout_barcode = getout_event['barcode']
|
|
getout_feats_compose = getout_event['feats_compose']
|
|
getout_feats_select = getout_event['feats_select']
|
|
|
|
if len(getout_feats_select):
|
|
outfeats_select = getout_feats_select.copy()
|
|
else:
|
|
outfeats_select = getout_feats_compose.copy()
|
|
|
|
result = {}
|
|
result['SeqDir'] = os.path.split(getout_event['path'])[1]
|
|
result['Deleted'] = getout_barcode
|
|
result['List'] = {}
|
|
for input_event in InputList:
|
|
input_barcode = input_event['barcode']
|
|
|
|
input_feats_compose = input_event['feats_compose']
|
|
input_feats_select = input_event['feats_select']
|
|
|
|
if len(input_feats_select):
|
|
infeats_select = input_feats_select.copy()
|
|
else:
|
|
infeats_select = input_feats_compose.copy()
|
|
|
|
similar_comp = compute_similar(getout_feats_compose, input_feats_compose)
|
|
similar_selt = compute_similar(outfeats_select, infeats_select)
|
|
|
|
'''现场测试相似度,组合特征相似度,前摄选择特征相似度'''
|
|
result['List'][f'{input_barcode}'] = (input_event['similarity'], similar_comp, similar_selt)
|
|
# result[f'{input_barcode}'] = (input_event['similarity'], similar_comp, similar_selt)
|
|
results.append(result)
|
|
|
|
print('Step 3 Done!')
|
|
|
|
wpath = os.path.split(filepath)[0]
|
|
wfile = os.path.join(wpath, 'deletedBarcodeTest.txt')
|
|
with open(wfile, 'w', encoding='utf-8') as file:
|
|
for result in results:
|
|
|
|
SeqDir = result['SeqDir']
|
|
Deleted = result['Deleted']
|
|
|
|
file.write('\n')
|
|
file.write(f'SeqDir: {SeqDir}\n')
|
|
file.write(f'Deleted: {Deleted}\n')
|
|
file.write('List:\n')
|
|
for key, value in result['List'].items():
|
|
file.write(f'{key}: ')
|
|
file.write(f'{value[0]}, {value[1]:.3f}, {value[2]:.3f}\n')
|
|
|
|
print('Step 4 Done!')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def front_performance_evaluate(all_list):
|
|
|
|
corrpairs, correct_barcode_list, correct_similarity, errpairs, err_barcode_list, err_similarity = [], [], [], [], [], []
|
|
|
|
for s_list in all_list:
|
|
seqdir = s_list['SeqDir'].strip()
|
|
delete = s_list['Deleted'].strip()
|
|
barcodes = [s.strip() for s in s_list['barcode']]
|
|
|
|
similarity, front_similarity = [], []
|
|
for simil in s_list['similarity']:
|
|
ss = [float(s.strip()) for s in simil.split(',')]
|
|
|
|
similarity.append(ss[0])
|
|
if len(ss)==3:
|
|
front_similarity.append(ss[2])
|
|
|
|
# similarity = [float(s.strip()) for s in s_list['similarity']]
|
|
|
|
|
|
index = front_similarity.index(max(front_similarity))
|
|
matched_barcode = barcodes[index]
|
|
if matched_barcode == delete:
|
|
corrpairs.append((seqdir, delete))
|
|
correct_barcode_list.append(delete)
|
|
correct_similarity.append(max(front_similarity))
|
|
else:
|
|
errpairs.append((seqdir, delete, matched_barcode))
|
|
err_barcode_list.append(delete)
|
|
err_similarity.append(max(front_similarity))
|
|
|
|
|
|
|
|
|
|
return errpairs, corrpairs, err_similarity, correct_similarity
|
|
|
|
|
|
|
|
def compute_pres(filepath, savepath):
|
|
|
|
|
|
fpath = os.path.split(filepath)[0]
|
|
_, basefile = os.path.split(fpath)
|
|
|
|
'''1. 综合前后摄特征的相似度比对性能'''
|
|
fpath1 = os.path.join(fpath, 'deletedBarcode.txt')
|
|
blist1 = read_deletedBarcode_file(fpath1)
|
|
errpairs, corrpairs, err_similarity, correct_similarity = performance_evaluate(blist1)
|
|
recall, prec, ths = compute_recall_precision(err_similarity, correct_similarity)
|
|
|
|
|
|
|
|
os.path.split(fpath1)
|
|
plt1 = show_recall_prec(recall, prec, ths)
|
|
# plt1.show()
|
|
plt1.xlabel(f'threshold, Num: {len(blist1)}')
|
|
plt1.title(basefile + ', compose')
|
|
plt1.savefig(os.path.join(savepath, basefile+'_pr.png'))
|
|
plt1.close()
|
|
|
|
'''2. 优先选取前摄特征的相似度比对性能'''
|
|
fpath2 = os.path.join(fpath, 'deletedBarcodeTest.txt')
|
|
blist2 = read_deletedBarcode_file(fpath2)
|
|
front_errpairs, front_corrpairs, front_err_similarity, front_correct_similarity = front_performance_evaluate(blist2)
|
|
front_recall, front_prec, front_ths = compute_recall_precision(front_err_similarity, front_correct_similarity)
|
|
|
|
plt2 = show_recall_prec(front_recall, front_prec, front_ths)
|
|
# plt2.show()
|
|
plt2.xlabel(f'threshold, Num: {len(blist2)}')
|
|
plt1.title(basefile + ', front')
|
|
plt2.savefig(os.path.join(savepath, basefile+'_pr_front.png'))
|
|
plt2.close()
|
|
|
|
def main():
|
|
fplist = [r'\\192.168.1.28\share\测试_202406\0723\0723_1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0723\0723_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0723\0723_3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0722\0722_01\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0722\0722_02\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0719\0719_1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0719\0719_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0719\0719_3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0719\0719_4\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0718\0718-1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0718\0718-2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0717\0717-1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0717\0717-2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0717\0717-3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0716\0716_1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0716\0716_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0716\0716_3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0715\0715_1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0715\0715_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0715\0715_3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0712\0712_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\0712\0712_3\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\711\images01\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\711\images02\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\710\images_1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\710\images_2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\709\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\705\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\703\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\702_pm_1\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\702_pm_2\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\702_pm_3\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\702_am\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\702_pm\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\701_am\images\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\628\1\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\628\2\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\627\deletedBarcode.txt',
|
|
r'\\192.168.1.28\share\测试_202406\625\deletedBarcode.txt',
|
|
]
|
|
|
|
savepath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\illustration'
|
|
for filepath in fplist:
|
|
print(filepath)
|
|
|
|
try:
|
|
creatd_deletedBarcode_front(filepath)
|
|
compute_pres(filepath, savepath)
|
|
except Exception as e:
|
|
print(f'Error: {e}')
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|