Files
detecttracking/tracking/feat_select.py
王庆刚 0cc36ba920 bakeup
2024-09-02 11:50:08 +08:00

433 lines
18 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- 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 compute_recall_precision, show_recall_prec
from tracking.contrast_analysis import performance_evaluate
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
back_sole_boxes后摄boxes
front_sole_boxes前摄boxes
back_sole_feats后摄特征
front_sole_feats前摄特征
feats_compose将前后摄特征进行合并
feats_select特征选择优先选择前摄特征
'''
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)
# '''读取 track.data 文件中的数据'''
# fpath_0_track = os.path.join(datapath, '0_track.data')
# fpath_1_track = os.path.join(datapath, '1_track.data')
# if os.path.exists(fpath_0_track) and os.path.isfile(fpath_0_track):
# _, _, _, _, tracking_boxes, tracking_feat_dict = extract_data(fpath_0_track)
# event['back_tracking_boxes'] = tracking_boxes
# event['back_tracking_feats'] = tracking_feat_dict
# if os.path.exists(fpath_1_track) and os.path.isfile(fpath_1_track):
# _, _, _, _, tracking_boxes, tracking_feat_dict = extract_data(fpath_1_track)
# event['front_tracking_boxes'] = tracking_boxes
# event['front_tracking_feats'] = tracking_feat_dict
# =============================================================================
# '''================1. 直接指定读取,速度快======================================'''
# '''读取 tracking_output.data 文件中的数据'''
# fpath_0_tracking = os.path.join(datapath, '0_tracking_output.data')
# fpath_1_tracking = os.path.join(datapath, '1_tracking_output.data')
# if os.path.exists(fpath_0_tracking) and os.path.isfile(fpath_0_tracking):
# tracking_output_boxes, tracking_output_feats = read_tracking_output(fpath_0_tracking)
# event['back_sole_boxes'] = tracking_output_boxes
# event['back_sole_feats'] = tracking_output_feats
#
# if os.path.exists(fpath_1_tracking) and os.path.isfile(fpath_1_tracking):
# tracking_output_boxes, tracking_output_feats = read_tracking_output(fpath_1_tracking)
# event['front_sole_boxes'] = tracking_output_boxes
# event['front_sole_feats'] = tracking_output_feats
# =============================================================================
'''================2. 遍历方式读取(与以上方式二选一)======================================'''
'''读取当前事件的 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):
'''
生成deletedBarcodeTest.txt
'''
# filepath = r'\\192.168.1.28\share\测试_202406\0723\0723_1\deletedBarcode.txt'
basepath, _ = os.path.split(filepath)
bcdlist = read_deletedBarcode_file(filepath)
MatchList = []
k = 0
for s_list in bcdlist:
getout_fold = s_list['SeqDir'].strip()
getout_path = os.path.join(basepath, getout_fold)
'''取出事件文件夹不存在,跳出循环'''
if not os.path.exists(getout_path) and not os.path.isdir(getout_path):
continue
day, hms = getout_fold.strip('_').split('-')
''' 生成取出事件字典 '''
getout_event = {}
getout_event['barcode'] = s_list['Deleted'].strip()
getout_event['path'] = getout_path
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
if len(infold[0])<=14 or len(infold[1])<=10: 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))
if len(input_folds)==0: continue
''' 根据时间排序,选择离取出操作最近时间的文件夹,作为取出操作应的放入操作所对应的文件夹 '''
input_fold = input_folds[times.index(max(times))]
input_path = os.path.join(basepath, input_fold)
if not os.path.exists(getout_path) and not os.path.isdir(getout_path):
continue
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: Event init 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: Event update 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: Similarity conputation 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: File writting Done!')
def precision_compare(filepath, savepath):
'''
1. deletedBarcode.txt 中的相似度的计算为现场算法前后摄轨迹特征合并
2. deletedBarcodeTest.txt 中的 3 个相似度计算方式依次为:
(1)现场算法前后摄轨迹特征合并;
(2)本地算法前后摄轨迹特征合并;
(3)本地算法优先选择前摄
'''
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 = 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():
'''
1. 成deletedBarcodeTest.txt
2. 不同特征选择下的精度比对性能比较
'''
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\719_1\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\0719\719_2\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\0719\719_3\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\0719\719_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_1\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\0712\0712_2\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\702_pm_1\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\702_pm_3\702_pm_3\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\701_am\deletedBarcode.txt',
# r'\\192.168.1.28\share\测试_202406\701_pm\701_pm\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',
]
savepath = r'\\192.168.1.28\share\测试_202406\deletedBarcode\illustration'
for filepath in fplist:
try:
#1. 生成deletedBarcodeTest.txt 文件
creatd_deletedBarcode_front(filepath)
#2. 确保该目录下存在deletedBarcode.txt, deletedBarcodeTest.txt 文件
precision_compare(filepath, savepath)
except Exception as e:
print(f'{filepath}, Error: {e}')
if __name__ == '__main__':
main()