# -*- 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()
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    


                