814 lines
28 KiB
Python
814 lines
28 KiB
Python
# -*- 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
|
||
|
||
from scipy.spatial.distance import cdist
|
||
import matplotlib.pyplot as plt
|
||
|
||
from pathlib import Path
|
||
from utils.gen import Profile
|
||
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():
|
||
featdir = r"./data/trackfeats"
|
||
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(featdir):
|
||
file, ext = os.path.splitext(filename)
|
||
|
||
# if file not in FileList: continue
|
||
if file.find('20240508')<0: continue
|
||
if file.find('17327712807')<0: continue
|
||
|
||
trackpath = os.path.join(trackdir, file + ".npy")
|
||
featpath = os.path.join(featdir, filename)
|
||
|
||
bboxes = np.load(trackpath)
|
||
features_dict = np.load(featpath, allow_pickle=True)
|
||
with gt:
|
||
if filename.find("front") >= 0:
|
||
vts = doFrontTracks(bboxes, features_dict)
|
||
vts.classify()
|
||
|
||
plt = plot_frameID_y2(vts)
|
||
|
||
savedir = save_dir.joinpath(f'{file}_y2.png')
|
||
|
||
plt.savefig(savedir)
|
||
plt.close()
|
||
elif filename.find("back") >= 0:
|
||
vts = doBackTracks(bboxes, features_dict)
|
||
vts.classify()
|
||
|
||
edgeline = cv2.imread("./shopcart/cart_tempt/edgeline.png")
|
||
draw_all_trajectories(vts, edgeline, save_dir, filename)
|
||
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 = features_dict[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()
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|