回传数据解析,兼容v5和v10

This commit is contained in:
jiajie555
2025-04-18 14:41:53 +08:00
commit 010f5c445a
888 changed files with 93632 additions and 0 deletions

View File

@ -0,0 +1,337 @@
# -*- coding: utf-8 -*-
"""
Created on Fri Aug 30 17:53:03 2024
have Deprecated!
1. 确认在相同CamerType下track.data 中 CamerID 项数量 = 图像数 = 帧ID数 = 最大帧ID
2. 读取0/1_tracking_output.data 中数据boxes、featslen(boxes)=len(feats)
帧ID约束
3. 优先选择前摄
4. 保存图像数据
5. 一次购物事件类型
shopEvent: {barcode:
type: getout, input
front_traj:[{imgpath: str,
box: arrar(1, 9),
feat: array(1, 256)
}]
back_traj: [{imgpath: str,
box: arrar(1, 9),
feat: array(1, 256)
}]
}
@author: ym
"""
import numpy as np
import cv2
import os
import sys
import json
import pickle
sys.path.append(r"D:\DetectTracking")
from tracking.utils.read_data import extract_data, read_tracking_output, read_deletedBarcode_file
IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
def creat_shopping_event(basepath):
eventList = []
'''一、构造放入商品事件列表'''
k = 0
for filename in os.listdir(basepath):
# filename = "20240723-155413_6904406215720"
'''filename下为一次购物事件'''
filepath = os.path.join(basepath, filename)
'''================ 0. 检查 filename 及 filepath 正确性和有效性 ================'''
nmlist = filename.split('_')
if filename.find('2024')<0 or len(nmlist)!=2 or len(nmlist[0])!=15 or len(nmlist[1])<11:
continue
if not os.path.isdir(filepath): continue
print(f"Event name: {filename}")
'''================ 1. 构造事件描述字典,暂定 9 items ==============='''
event = {}
event['barcode'] = nmlist[1]
event['type'] = 'input'
event['filepath'] = filepath
event['back_imgpaths'] = []
event['front_imgpaths'] = []
event['back_boxes'] = np.empty((0, 9), dtype=np.float64)
event['front_boxes'] = np.empty((0, 9), dtype=np.float64)
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['feats_select'] = np.empty((0, 256), dtype=np.float64)
'''================= 1. 读取 data 文件 ============================='''
for dataname in os.listdir(filepath):
# filename = '1_track.data'
datapath = os.path.join(filepath, dataname)
if not os.path.isfile(datapath): continue
CamerType = dataname.split('_')[0]
''' 3.1 读取 0/1_track.data 中数据,暂不考虑'''
# if dataname.find("_track.data")>0:
# bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict = extract_data(datapath)
''' 3.2 读取 0/1_tracking_output.data 中数据'''
if dataname.find("_tracking_output.data")>0:
tracking_output_boxes, tracking_output_feats = read_tracking_output(datapath)
if len(tracking_output_boxes) != len(tracking_output_feats): continue
if CamerType == '0':
event['back_boxes'] = tracking_output_boxes
event['back_feats'] = tracking_output_feats
elif CamerType == '1':
event['front_boxes'] = tracking_output_boxes
event['front_feats'] = tracking_output_feats
# '''1.1 事件的特征表征方式选择'''
# bk_feats = event['back_feats']
# ft_feats = event['front_feats']
# feats_compose = np.empty((0, 256), dtype=np.float64)
# if len(ft_feats):
# feats_compose = np.concatenate((feats_compose, ft_feats), axis=0)
# if len(bk_feats):
# feats_compose = np.concatenate((feats_compose, bk_feats), axis=0)
# event['feats_compose'] = feats_compose
# '''3. 构造前摄特征'''
# if len(ft_feats):
# event['feats_select'] = ft_feats
'''================ 2. 读取图像文件地址并按照帧ID排序 ============='''
frontImgs, frontFid = [], []
backImgs, backFid = [], []
for imgname in os.listdir(filepath):
name, ext = os.path.splitext(imgname)
if ext not in IMG_FORMAT or name.find('frameId')<0: continue
CamerType = name.split('_')[0]
frameId = int(name.split('_')[3])
imgpath = os.path.join(filepath, imgname)
if CamerType == '0':
backImgs.append(imgpath)
backFid.append(frameId)
if CamerType == '1':
frontImgs.append(imgpath)
frontFid.append(frameId)
frontIdx = np.argsort(np.array(frontFid))
backIdx = np.argsort(np.array(backFid))
'''2.1 生成依据帧 ID 排序的前后摄图像地址列表'''
frontImgs = [frontImgs[i] for i in frontIdx]
backImgs = [backImgs[i] for i in backIdx]
'''2.2 将前、后摄图像路径添加至事件字典'''
bfid = event['back_boxes'][:, 7].astype(np.int64)
ffid = event['front_boxes'][:, 7].astype(np.int64)
if len(bfid) and max(bfid) <= len(backImgs):
event['back_imgpaths'] = [backImgs[i-1] for i in bfid]
if len(ffid) and max(ffid) <= len(frontImgs):
event['front_imgpaths'] = [frontImgs[i-1] for i in ffid]
'''================ 3. 判断当前事件有效性,并添加至事件列表 =========='''
condt1 = len(event['back_imgpaths'])==0 or len(event['front_imgpaths'])==0
condt2 = len(event['front_feats'])==0 and len(event['back_feats'])==0
if condt1 or condt2:
print(f" Error, condt1: {condt1}, condt2: {condt2}")
continue
eventList.append(event)
# k += 1
# if k==1:
# continue
'''一、构造放入商品事件列表,暂不处理'''
# delepath = os.path.join(basepath, 'deletedBarcode.txt')
# bcdList = read_deletedBarcode_file(delepath)
# for slist in bcdList:
# getoutFold = slist['SeqDir'].strip()
# getoutPath = os.path.join(basepath, getoutFold)
# '''取出事件文件夹不存在,跳出循环'''
# if not os.path.exists(getoutPath) and not os.path.isdir(getoutPath):
# continue
# ''' 生成取出事件字典 '''
# event = {}
# event['barcode'] = slist['Deleted'].strip()
# event['type'] = 'getout'
# event['basepath'] = getoutPath
return eventList
def get_std_barcodeDict(bcdpath):
stdBlist = []
for filename in os.listdir(bcdpath):
filepath = os.path.join(bcdpath, filename)
if not os.path.isdir(filepath) or not filename.isdigit(): continue
stdBlist.append(filename)
bcdpaths = [(barcode, os.path.join(bcdpath, barcode)) for barcode in stdBlist]
stdBarcodeDict = {}
for barcode, bpath in bcdpaths:
stdBarcodeDict[barcode] = []
for root, dirs, files in os.walk(bpath):
imgpaths = []
if "base" in dirs:
broot = os.path.join(root, "base")
for imgname in os.listdir(broot):
imgpath = os.path.join(broot, imgname)
_, ext = os.path.splitext(imgpath)
if ext not in IMG_FORMAT: continue
imgpaths.append(imgpath)
stdBarcodeDict[barcode].extend(imgpaths)
break
else:
for imgname in files:
imgpath = os.path.join(root, imgname)
_, ext = os.path.splitext(imgpath)
if ext not in IMG_FORMAT: continue
imgpaths.append(imgpath)
stdBarcodeDict[barcode].extend(imgpaths)
jsonpath = os.path.join(r'\\192.168.1.28\share\测试_202406\contrast\barcodes', f"{barcode}.pickle")
with open(jsonpath, 'wb') as f:
pickle.dump(stdBarcodeDict, f)
print(f"Barcode: {barcode}")
return stdBarcodeDict
def one2one_test(filepath):
savepath = r'\\192.168.1.28\share\测试_202406\contrast'
'''获得 Barcode 列表'''
bcdpath = r'\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_1771'
stdBarcodeDict = get_std_barcodeDict(bcdpath)
eventList = creat_shopping_event(filepath)
print("=========== eventList have generated! ===========")
barcodeDict = {}
for event in eventList:
'''9 items: barcode, type, filepath, back_imgpaths, front_imgpaths,
back_boxes, front_boxes, back_feats, front_feats
'''
barcode = event['barcode']
if barcode not in stdBarcodeDict.keys():
continue
if len(event['feats_select']):
event_feats = event['feats_select']
elif len(event['back_feats']):
event_feats = event['back_feats']
else:
continue
std_bcdpath = os.path.join(bcdpath, barcode)
for root, dirs, files in os.walk(std_bcdpath):
if "base" in files:
std_bcdpath = os.path.join(root, "base")
break
'''保存一次购物事件的轨迹子图'''
basename = os.path.basename(event['filepath'])
spath = os.path.join(savepath, basename)
if not os.path.exists(spath):
os.makedirs(spath)
cameras = ('front', 'back')
for camera in cameras:
if camera == 'front':
boxes = event['front_boxes']
imgpaths = event['front_imgpaths']
else:
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]
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"{camerType}_{tid}_fid({fid}, {frameID}).png"
subimgPath = os.path.join(spath, subimgName)
cv2.imwrite(subimgPath, subimg)
print(f"Image saved: {basename}")
def main():
fplist = [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'
]
for filepath in fplist:
one2one_test(filepath)
# for filepath in fplist:
# try:
# one2one_test(filepath)
# except Exception as e:
# print(f'{filepath}, Error: {e}')
if __name__ == '__main__':
main()

View File

@ -0,0 +1,806 @@
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 16 11:51:07 2024
@author: ym
"""
import cv2
import os
import numpy as np
# import time
import pickle
import json
# import matplotlib.pyplot as plt
import pandas as pd
import shutil
import random
import math
import sys
from scipy.spatial.distance import cdist
import matplotlib.pyplot as plt
from pathlib import Path
from utils.gen import Profile
sys.path.append(r"D:\DetectTracking\tracking")
from dotrack.dotracks_back import doBackTracks
from dotrack.dotracks_front import doFrontTracks
from utils.drawtracks import plot_frameID_y2, draw_all_trajectories
# from utils.drawtracks import draw5points, drawTrack, drawtracefeat, drawFeatures
# from datetime import datetime
from utils.mergetrack import readDict
import csv
def read_csv_file():
file_path = r'D:\DeepLearning\yolov5_track\tracking\matching\featdata\Similarity.csv'
with open(file_path, mode='r', newline='') as file:
data = list(csv.reader(file))
matrix = []
for i in range(1, len(data)):
matrix.append(data[i][1:])
matrix = np.array(matrix, dtype = np.float32)
simil = 1 + (matrix-1)/2
print("done!!!")
def get_img_filename(imgpath = r'./matching/images/' ):
imgexts = ['.png', '.jpg', '.jpeg']
ImgFileList = []
for root, dirs, files in os.walk(imgpath):
ImgList = []
for file in files:
_, ext = os.path.splitext(file)
if ext in imgexts:
ImgFileList.append(os.path.join(root, file))
return ImgFileList
def calculate_similarity_track(similarmode = 'other'):
'''
similarmode:
'mean'
'other'
'''
ContrastDict = np.load('./matching/featdata/imgs_feats_data_refined.pkl', allow_pickle=True)
print(f"The Num of imgsample: {len(ContrastDict)}")
''''================= 构造空字典 MatchObjDict ================='''
def splitkey(key):
videoname = key.split('_')
BarCode = videoname[0]
SampleTime = videoname[1].split('-')[1]
CameraType = videoname[2]
ActionType = videoname[3]
TrackID = '_'.join(key.split('_')[7:])
return BarCode, SampleTime, CameraType, ActionType, TrackID
MatchObjList = []
CameraList = []
for key in ContrastDict.keys():
BarCode, SampleTime, CameraType, ActionType, FeatureID = splitkey(key)
MatchObjList.append('_'.join([BarCode, SampleTime, ActionType]))
CameraList.append(CameraType)
# MatchObjSet = set(MatchObjList)
# CameraSet = set(CameraList)
objects = list(set(MatchObjList))
cameras = list(set(CameraList))
assert len(cameras) == 2, "The num of cameras is error!"
MatchObjDict = {}
for obj in objects:
CameraDict = {}
for camera in cameras:
CameraDict[camera] = {}
MatchObjDict[obj] = CameraDict
for key, value in ContrastDict.items():
BarCode, SampleTime, CameraType, ActionType, FeatureID = splitkey(key)
MatchObj = '_'.join([BarCode, SampleTime, ActionType])
vdict = {}
if FeatureID not in MatchObjDict[MatchObj][CameraType]:
vdict[FeatureID] = value['feature']
MatchObjDict[MatchObj][CameraType].update(vdict)
print(f"The Num of MatchObjDict: {len(MatchObjDict)}")
# MatchKeys = [key for key in MatchObjDict.keys()]
num = len(objects)
GtMatrix = np.zeros((num, num), dtype=np.float32)
Similarity = np.zeros((num, num), dtype=np.float32)
InterMatrix = np.zeros((num, num), dtype=np.float32) # 类间
IntraMatrix = np.zeros((num, num), dtype=np.float32) # 类内
'''生成GT矩阵: GtMatrix, IntraMatrix, InterMatrix'''
for i, obi in enumerate(objects):
barcode_i = obi.split('_')[0]
for j, obj in enumerate(objects):
barcode_j = obj.split('_')[0]
if barcode_i == barcode_j:
GtMatrix[i, j] = 1
if i!=j: IntraMatrix[i, j] = 1
else:
GtMatrix[i, j] = 0
InterMatrix[i, j] = 1
'''生成相似度矩阵: Similarity '''
ObjFeatList = []
for i, obi in enumerate(objects):
obidict = MatchObjDict[obi]
camlist = []
for camera in obidict.keys():
featlist = []
for fid in obidict[camera].keys():
featlist.append(MatchObjDict[obi][camera][fid])
camlist.append(featlist)
ObjFeatList.append(camlist)
Similarity_1 = Similarity.copy()
for i in range(len(objects)):
obi = ObjFeatList[i]
for j in range(len(objects)):
obj = ObjFeatList[j]
simival = []
for ii in range(len(obi)):
if len(obi[ii])==0: continue
feat_ii = np.asarray(obi[ii])
for jj in range(len(obj)):
if len(obj[jj])==0: continue
feat_jj = np.asarray(obj[jj])
if similarmode == 'mean':
featii = np.mean(feat_ii, axis=0)
featjj = np.mean(feat_jj, axis=0)
try:
matrix = 1- np.maximum(0.0, cdist(featii[None, :], featjj[None, :], 'cosine'))
except Exception as e:
print(f'error is {e.__class__.__name__}')
else:
matrix = 1- np.maximum(0.0, cdist(feat_ii, feat_jj, 'cosine'))
simival.append(np.max(matrix))
if len(simival)==0: continue
Similarity[i, j] = max(simival)
# feat_i = np.empty((0, 256), dtype = np.float32)
# feat_j = np.empty((0, 256), dtype = np.float32)
# for ii in range(len(obi)):
# feat_ii = np.asarray(obi[ii])
# feat_i = np.concatenate((feat_i, feat_ii), axis=0)
# for jj in range(len(obj)):
# feat_jj = np.asarray(obi[jj])
# feat_j = np.concatenate((feat_j, feat_jj), axis=0)
# if similarmode == 'mean':
# feati = np.mean(feat_i, axis=0)
# featj = np.mean(feat_j, axis=0)
# matrix = 1- np.maximum(0.0, cdist(feati[None, :], featj[None, :], 'cosine'))
# else:
# matrix = 1- np.maximum(0.0, cdist(feat_i, feat_j, 'cosine'))
# Similarity_1[i, j] = np.max(matrix)
SimiDict = {'keys': objects, 'GtMatrix': GtMatrix, 'Similarity': Similarity,
'IntraMatrix':IntraMatrix, 'InterMatrix':InterMatrix}
with open(r"./matching/featdata/MatchDict_track.pkl", "wb") as f:
pickle.dump(SimiDict, f)
# SimiDict_1 = {'keys': objects, 'GtMatrix': GtMatrix, 'Similarity':Similarity_1,
# 'IntraMatrix':IntraMatrix, 'InterMatrix':InterMatrix}
# with open(r"./matching/featdata/MatchDict_track_1.pkl", "wb") as f:
# pickle.dump(SimiDict_1, f)
df_GtMatrix = pd.DataFrame(data=GtMatrix, columns = objects, index = objects)
df_GtMatrix.to_csv('./matching/featdata/GtMatrix_track.csv',index=True)
df_similarity = pd.DataFrame(data=Similarity, columns = objects, index = objects)
df_similarity.to_csv('./matching/featdata/Similarity_track.csv',index=True)
# df_similarity_1 = pd.DataFrame(data=Similarity_1, columns = objects, index = objects)
# df_similarity_1.to_csv('./matching/featdata/Similarity_track_1.csv',index=True)
print("Done!!!!")
# SimilarMode = ['mean', 'max']
def calculate_similarity(similarmode = 'mean'):
ContrastDict = np.load('./matching/featdata/imgs_feats_data_noplane.pkl', allow_pickle=True)
print(f"The Num of imgsample: {len(ContrastDict)}")
FrontBackMerged = True
TracKeys = {}
for key, value in ContrastDict.items():
feature = value['feature']
videoname = key.split('_')[:7]
BarCode = videoname[0]
SampleTime = videoname[1].split('-')[1]
CameraType = videoname[2]
ActionType = videoname[3]
TrackID = key.split('_')[7]
if FrontBackMerged:
TracKey = '_'.join([BarCode, SampleTime, ActionType])
else:
TracKey = '_'.join([BarCode, SampleTime, CameraType, ActionType])
if TracKey in TracKeys:
TracKeys[TracKey].append(feature)
else:
TracKeys[TracKey] = []
TracKeys[TracKey].append(feature)
'''===== 生成GT矩阵: Similarity、GtMatrix、IntraMatrix、InterMatrix ====='''
num = len(TracKeys)
keys = [key for key in TracKeys.keys()]
GtMatrix = np.zeros((num, num), dtype=np.float32)
Similarity = np.zeros((num, num), dtype=np.float32)
InterMatrix = np.zeros((num, num), dtype=np.float32) # 类间
IntraMatrix = np.zeros((num, num), dtype=np.float32) # 类内
for i, key_i in enumerate(keys):
barcode_i = key_i.split('_')[0]
feat_i = np.asarray(TracKeys[key_i], dtype=np.float32)
for j, key_j in enumerate(keys):
barcode_j = key_j.split('_')[0]
feat_j = np.asarray(TracKeys[key_j], dtype=np.float32)
if similarmode == 'mean':
feati = np.mean(feat_i, axis=0)
featj = np.mean(feat_j, axis=0)
matrix = 1- np.maximum(0.0, cdist(feati[None, :], featj[None, :], 'cosine'))
else:
matrix = 1- np.maximum(0.0, cdist(feat_i, feat_j, 'cosine'))
Similarity[i, j] = np.max(matrix)
if barcode_i == barcode_j:
GtMatrix[i, j] = 1
if i!=j: IntraMatrix[i, j] = 1
else:
GtMatrix[i, j] = 0
InterMatrix[i, j] = 1
# =============================================================================
# '''生成相似度矩阵: Similarity '''
# for i, key_i in enumerate(keys):
# feat_i = np.asarray(TracKeys[key_i], dtype=np.float32)
# for j, key_j in enumerate(keys):
# feat_j = np.asarray(TracKeys[key_j], dtype=np.float32)
#
# if similarmode == 'mean':
# feati = np.mean(feat_i, axis=0)
# featj = np.mean(feat_j, axis=0)
# matrix = 1- np.maximum(0.0, cdist(feati[None, :], featj[None, :], 'cosine'))
# else:
# matrix = 1- np.maximum(0.0, cdist(feat_i, feat_j, 'cosine'))
# Similarity[i, j] = np.max(matrix)
# =============================================================================
MatchDict = {'keys': keys, 'GtMatrix':GtMatrix, 'Similarity':Similarity,
'IntraMatrix':IntraMatrix, 'InterMatrix':InterMatrix}
with open(r"./matching/featdata/MatchDict_noplane.pkl", "wb") as f:
pickle.dump(MatchDict, f)
df_GtMatrix = pd.DataFrame(data=GtMatrix, columns = keys, index = keys)
df_GtMatrix.to_csv('./matching/featdata/GtMatrix_noplane.csv',index=True)
df_similarity = pd.DataFrame(data=Similarity, columns = keys, index = keys)
df_similarity.to_csv('./matching/featdata/Similarity_noplane.csv',index=True)
def sortN_matching(filename = r'./matching/featdata/MatchDict.pkl'):
SimilarDict = np.load(filename, allow_pickle=True)
'''********** keys的顺序与Similarity中行列值索引一一对应 **********'''
keys = SimilarDict['keys']
Similarity = SimilarDict['Similarity']
'''1. 将时间根据 Barcode 归并,并确保每个 Barcode 下至少两个事件'''
BarcodeDict1 = {}
for i, key in enumerate(keys):
barcode = key.split('_')[0]
if barcode not in BarcodeDict1.keys():
BarcodeDict1[barcode] = []
BarcodeDict1[barcode].append(i)
BarcodeDict = {}
BarcodeList = []
for barcode, value in BarcodeDict1.items():
if len(value) < 2: continue
BarcodeDict[barcode] = value
BarcodeList.append(barcode)
BarcodeList = list(set(BarcodeList))
'''实验参数设定
N: 任意选取的 Barcode 数
R重复实验次数每次从同一 Barcode 下随机选取2个事件分别归入加购、退购集合
Thresh相似度阈值
'''
N = 10
if N > len(BarcodeList):
N = math.ceil(len(BarcodeList)/2)
R = 20
Thresh = np.linspace(0.1, 1, 100)
# Thresh = np.linspace(0.601, 0.7, 100)
Recall, Precision = [], []
for th in Thresh:
recall = np.zeros((1, R), dtype=np.float32)
precision = np.zeros((1, R), dtype=np.float32)
for rep in range(R):
BarcodeSelect = random.sample(BarcodeList, N)
AddDict = {}
TakeoutDict = {}
for barcode in BarcodeSelect:
barlist = BarcodeDict[barcode]
if len(barlist) < 2:continue
selected = random.sample(barlist, 2)
AddDict[barcode] = selected[0]
TakeoutDict[barcode] = selected[1]
OrderMatrix = np.zeros((N, N), dtype=np.float32)
GTMatrix = np.zeros((N, N), dtype=np.float32)
MatchMatrix_1 = np.zeros((N, N), dtype=np.float32)
MatchMatrix_2 = np.zeros((N, N), dtype=np.float32)
i = 0
for keyi in BarcodeSelect:
ii = TakeoutDict[keyi]
j = 0
for keyj in BarcodeSelect:
jj = AddDict[keyj]
OrderMatrix[i, j] = Similarity[int(ii), int(jj)]
if keyi == keyj:
GTMatrix[i, j] = 1
j += 1
i += 1
max_indices = np.argmax(OrderMatrix, axis = 1)
for i in range(N):
MatchMatrix_1[i, max_indices[i]] = 1
similar = OrderMatrix[i, max_indices[i]]
if similar > th:
MatchMatrix_2[i, max_indices[i]] = 1
GT_indices = np.where(GTMatrix == 1)
FNTP = MatchMatrix_2[GT_indices]
pred_indices = np.where(MatchMatrix_2 == 1)
TP = np.sum(FNTP==1)
FN = np.sum(FNTP==0)
FPTP = GTMatrix[pred_indices]
FP = np.sum(FPTP == 0)
# assert TP == np.sum(FPTP == 0), "Please Check Errors!!!"
recall[0, rep] = TP/(TP+FN)
precision[0, rep] = TP/(TP+FP+1e-3) # 阈值太大时可能TP、FP都为0
Recall.append(recall)
Precision.append(precision)
Recall = np.asarray(Recall).reshape([len(Thresh),-1])
Precision = np.asarray(Precision).reshape([len(Thresh),-1])
reclmean = np.sum(Recall, axis=1) / (np.count_nonzero(Recall, axis=1) + 1e-3)
precmean = np.sum(Precision, axis=1) / (np.count_nonzero(Precision, axis=1) + 1e-3)
print("Done!!!!!")
# th1, recl = [c[0] for c in Recall], [c[1] for c in Recall]
# th2, prep = [c[0] for c in Precision], [c[1] for c in Precision]
recl = [r for r in reclmean]
prep = [p for p in precmean]
'''================= Precision & Recall ================='''
fig, ax = plt.subplots()
ax.plot(Thresh, recl, 'g', label='Recall = TP/(TP+FN)')
ax.plot(Thresh, prep, 'r', label='PrecisePos = TP/(TP+FP)')
# ax.set_xlim([0, 1])
# ax.set_ylim([0, 1])
ax.grid(True)
ax.set_title('Precision & Recall')
ax.legend()
plt.show()
def match_evaluate(filename = r'./matching/featdata/MatchDict.pkl'):
SimiDict = np.load(filename, allow_pickle=True)
keys = SimiDict['keys']
GtMatrix = SimiDict['GtMatrix']
Similarity = SimiDict['Similarity']
IntraMatrix = SimiDict['IntraMatrix']
InterMatrix = SimiDict['InterMatrix']
BarcodeList = []
for key in keys:
BarcodeList.append(key.split('_')[0])
BarcodeList = list(set(BarcodeList))
IntraRows, IntraCols = np.nonzero(IntraMatrix)
InterRows, InterCols = np.nonzero(InterMatrix)
IntraN, InterN = len(IntraRows), len(InterRows)
assert IntraN <= InterN, "类内大于类间数,样本不平衡"
InterNSelect = IntraN
Thresh = np.linspace(0.1, 1, 100)
# Thresh = np.linspace(0.2, 0.4, 11)
Correct = []
PrecisePos = []
PreciseNeg = []
Recall = []
CorrectMatries = []
for th in Thresh:
MatchMatrix = Similarity > th
CorrectMatrix = MatchMatrix == GtMatrix
CorrectMatries.append(CorrectMatrix)
nn = np.random.permutation(np.arange(InterN))[:InterNSelect]
InterRowsSelect, InterColsSelect = InterRows[nn], InterCols[nn]
IntraCorrMatrix = CorrectMatrix[IntraRows, IntraCols]
InterCorrMatrix = CorrectMatrix[InterRowsSelect, InterColsSelect]
TP = np.sum(IntraCorrMatrix)
TN = np.sum(InterCorrMatrix)
FN = IntraN - TP
FP = InterNSelect - TN
if TP+FP > 0:
PrecisePos.append((th, TP/(TP+FP)))
if TN+FN > 0:
PreciseNeg.append((th, TN/(TN+FN)))
if TP+FN > 0:
Recall.append((th, TP/(TP+FN)))
if TP+TN+FP+FN > 0:
Correct.append((th, (TP+TN)/(TP+TN+FP+FN)))
# print(f'Th: {th}')
# print(f'TP:{TP}, FP:{FP}, TN:{TN}, FN:{FN}')
CorrectMatries = np.asarray(CorrectMatries)
'''====================== 分析错误原因 =========================='''
'''
keys两种构成方式其中的元素来自于MatchingDict
BarCode, SampleTime, ActionType #不考虑摄像头类型(前后摄)
BarCode, SampleTime, CameraType, ActionType# 考虑摄像头类型(前后摄)
为了便于显示,在图像文件名中,将 ActionType 进行了缩写,匹配时取 [:3]
"addGood" --------> "add"
"returnGood" --------> "return"
'''
##============= 获取图像存储位置,可以通过 keys 检索到对应的图像文件
imgpath = r'./matching/images/'
ImgFileList = get_img_filename(imgpath)
rowx, colx = np.where(CorrectMatries[66,:,:] == False)
rows, cols = [], []
for i in range(len(rowx)):
ri, ci = rowx[i], colx[i]
if ci > ri:
rows.append(ri)
cols.append(ci)
KeysError = [(keys[rows[i]], keys[cols[i]]) for i in range(len(rows))]
SimiScore = [Similarity[rows[i], cols[i]] for i in range(len(rows))]
for i, keykey in enumerate(KeysError):
key1, key2 = keykey
sscore = SimiScore[i]
kt1, kt2 = key1.split('_'), key2.split('_')
if len(kt1)==3 and len(kt2)==3:
file1 = [f for f in ImgFileList if kt1[0] in f and kt1[1] in f and kt1[2][:3] in f]
file2 = [f for f in ImgFileList if kt2[0] in f and kt2[1] in f and kt2[2][:3] in f]
elif len(kt1)==4 and len(kt1)==4:
file1 = [f for f in ImgFileList if kt1[0] in f and kt1[1] in f and kt1[2] in f and kt1[3][:3] in f]
file2 = [f for f in ImgFileList if kt2[0] in f and kt2[1] in f and kt2[2] in f and kt2[3][:3] in f]
else:
pass
if len(file1)==0 or len(file2)==0:
continue
if kt1[0] == kt2[0]:
gt = "same"
else:
gt = "diff"
path = Path(f'./matching/results/{i}_{gt}_{sscore:.2f}')
if path.exists() and path.is_dir():
shutil.rmtree(path)
path1, path2 = path.joinpath(key1), path.joinpath(key2)
path1.mkdir(parents=True, exist_ok=True)
path2.mkdir(parents=True, exist_ok=True)
for file in file1:
shutil.copy2(file, path1)
for file in file2:
shutil.copy2(file, path2)
if i==99:
break
th1, corr = [c[0] for c in Correct], [c[1] for c in Correct]
th2, recl = [c[0] for c in Recall], [c[1] for c in Recall]
th3, prep = [c[0] for c in PrecisePos], [c[1] for c in PrecisePos]
th4, pren = [c[0] for c in PreciseNeg], [c[1] for c in PreciseNeg]
'''================= Correct ==================='''
fig, ax = plt.subplots()
ax.plot(th1, corr, 'b', label='Correct = (TP+TN)/(TP+TN+FP+FN)')
max_corr = max(corr)
max_index = corr.index(max_corr)
max_thresh = th1[max_index]
ax.plot([0, max_thresh], [max_corr, max_corr], 'r--')
ax.plot([max_thresh, max_thresh], [0, max_corr], 'r--')
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.grid(True)
ax.set_title('Correct')
ax.legend()
plt.show()
'''================= PrecisePos & PreciseNeg & Recall ================='''
fig, ax = plt.subplots()
ax.plot(th2, recl, 'g', label='Recall = TP/(TP+FN)')
ax.plot(th3, prep, 'c', label='PrecisePos = TP/(TP+FP)')
ax.plot(th4, pren, 'm', label='PreciseNeg = TN/(TN+FN)')
ax.set_xlim([0, 1])
ax.set_ylim([0, 1])
ax.grid(True)
ax.set_title('PrecisePos & PreciseNeg')
ax.legend()
plt.show()
def have_tracked():
trackdir = r"./data/tracks"
# =============================================================================
# FileList = []
# with open(r'./matching/视频分类/单.txt', 'r') as file:
# lines = file.readlines()
# for line in lines:
# file = line.split('.')[0]
# FileList.append(file)
# FileList = list(set(FileList))
# =============================================================================
MatchingDict = {}
k, gt = 0, Profile()
for filename in os.listdir(trackdir):
file, ext = os.path.splitext(filename)
# if file not in FileList: continue
if file.find('20240508')<0: continue
filepath = os.path.join(trackdir, filename)
tracksDict = np.load(filepath, allow_pickle=True)
bboxes = tracksDict['TrackBoxes']
with gt:
if filename.find("front") >= 0:
vts = doFrontTracks(bboxes, tracksDict)
vts.classify()
elif filename.find("back") >= 0:
vts = doBackTracks(bboxes, tracksDict)
vts.classify()
print(file+f" need time: {gt.dt:.2f}s")
elements = file.split('_')
assert len(elements) == 7, f"{filename} fields num: {len(elements)}"
BarCode = elements[0]
## ====================================== 只用于在images文件夹下保存图片
SampleTime = elements[1].split('-')[1]
CameraType = elements[2]
if elements[3]=="addGood":
ActionType = "add"
elif elements[3]=="returnGood":
ActionType = "return"
else:
ActionType = "x"
subimg_dir = Path(f'./matching/images/{BarCode}_{SampleTime}_{ActionType}/')
if not subimg_dir.exists():
subimg_dir.mkdir(parents=True, exist_ok=True)
# boxes: [x1, y1, x2, y2, track_id, score, cls, frame_index, box_index]
# 0, 1, 2, 3, 4, 5, 6, 7, 8
for track in vts.Residual:
boxes = track.boxes
for i in range(boxes.shape[0]):
box = boxes[i, :]
tid, fid, bid = int(box[4]), int(box[7]), int(box[8])
feat_dict = tracksDict[fid]
feature = feat_dict[bid]
img = feat_dict[f'{bid}_img']
sub_img_file = subimg_dir.joinpath(f"{BarCode}_{SampleTime}_{CameraType}_{ActionType}_{tid}_{fid}_{bid}.png")
cv2.imwrite(str(sub_img_file), img)
condict = {f"{file}_{tid}_{fid}_{bid}": {'img': img, 'feature': feature}}
MatchingDict.update(condict)
# k += 1
# if k == 100:
# break
featpath = Path('./matching/featdata/')
if not featpath.exists():
featpath.mkdir(parents=True, exist_ok=True)
featdata = featpath.joinpath('imgs_feats_data_noplane.pkl')
with open(featdata, 'wb') as file:
pickle.dump(MatchingDict, file)
def imgsample_cleaning():
ContrastDict = np.load('./matching/featdata/imgs_feats_data.pkl', allow_pickle=True)
print(f"The Num of imgsample: {len(ContrastDict)}")
MatchingDict_refined = {}
for filename, value in ContrastDict.items():
elements = filename.split('_')
tid = elements[7]
fid = elements[8]
bid = elements[9]
BarCode = elements[0]
SampleTime = elements[1].split('-')[1]
CameraType = elements[2]
if elements[3]=="addGood":
ActionType = "add"
elif elements[3]=="returnGood":
ActionType = "return"
else:
ActionType = "x"
refimgdir = f'.\matching\images_refined\{BarCode}_{SampleTime}_{ActionType}'
file = '_'.join(elements[0:7])
if os.path.exists(refimgdir) and os.path.isdir(refimgdir):
imgpath = os.path.join(refimgdir, f"{BarCode}_{SampleTime}_{CameraType}_{ActionType}_{tid}_{fid}_{bid}.png")
if os.path.isfile(imgpath):
condict = {f"{file}_{tid}_{fid}_{bid}": value}
MatchingDict_refined.update(condict)
featpath = Path('./matching/featdata/')
if not featpath.exists():
featpath.mkdir(parents=True, exist_ok=True)
featdata = featpath.joinpath('imgs_feats_data_refined.pkl')
with open(featdata, 'wb') as file:
pickle.dump(MatchingDict_refined, file)
print(f"The Num of ContrastDict: {len(ContrastDict)}")
print(f"The Num of MatchingDict_refined: {len(MatchingDict_refined)}")
print(f"The Num of cleaned img: {len(ContrastDict)} - {len(MatchingDict_refined)}")
def main():
'''1. 提取运动商品轨迹'''
# have_tracked()
'''2. 清除一次事件中包含多件商品的事件'''
# imgsample_cleaning()
'''3.1 计算事件间相似度: 将 front、back 的所有 track 特征合并'''
calculate_similarity()
'''3.2 计算事件间相似度: 考虑前后摄的不同组合,或 track 间的不同组合'''
# calculate_similarity_track()
'''4.1 事件间匹配的总体性能评估'''
filename = r'./matching/featdata/MatchDict_plane.pkl'
match_evaluate(filename)
filename = r'./matching/featdata/MatchDict_noplane.pkl'
match_evaluate(filename)
'''4.2 模拟实际场景任选N件作为一组作为加购取出其中一件时的性能评估'''
# filename = r'./matching/featdata/MatchDict_refined.pkl'
# sortN_matching(filename)
if __name__ == "__main__":
# save_dir = Path(f'./result/')
# read_csv_file()
main()