#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Mon Mar 31 16:25:43 2025 @author: wqg """ import numpy as np from scipy.spatial.distance import cdist def get_topk_percent(data, k): """ 获取数据中最大的 k% 的元素 """ # 将数据转换为 NumPy 数组 if isinstance(data, list): data = np.array(data) percentile = np.percentile(data, 100-k) top_k_percent = data[data >= percentile] return top_k_percent def cluster(data, thresh=0.15): # data = np.array([0.1, 0.13, 0.7, 0.2, 0.8, 0.52, 0.3, 0.7, 0.85, 0.58]) # data = np.array([0.1, 0.13, 0.2, 0.3]) # data = np.array([0.1]) if isinstance(data, list): data = np.array(data) data1 = np.sort(data) cluter, Cluters, = [data1[0]], [] for i in range(1, len(data1)): if data1[i] - data1[i-1]< thresh: cluter.append(data1[i]) else: Cluters.append(cluter) cluter = [data1[i]] Cluters.append(cluter) clt_center = [] for clt in Cluters: ## 是否应该在此处限制一个聚类中的最小轨迹样本数,应该将该因素放在轨迹分析中 # if len(clt)>=3: # clt_center.append(np.mean(clt)) clt_center.append(np.mean(clt)) # print(clt_center) return clt_center def calsiml(feat1, feat2, topkp=75, cluth=0.15): '''轨迹样本和标准特征集样本相似度的选择策略''' matrix = 1 - cdist(feat1, feat2, 'cosine') simi_max = [] for i in range(len(matrix)): sim = np.mean(get_topk_percent(matrix[i, :], topkp)) simi_max.append(sim) cltc_max = cluster(simi_max, cluth) Simi = max(cltc_max) ## cltc_max为空属于编程考虑不周,应予以排查解决 # if len(cltc_max): # Simi = max(cltc_max) # else: # Simi = 0 #不应该走到该处 return Simi def calsimi_vs_stdfeat_new(event, stdfeat): '''事件与标准库的对比策略 该比对策略是否可以拓展到事件与事件的比对? ''' front_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容 front_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(event.front_boxes)): front_boxes = np.concatenate((front_boxes, event.front_boxes[i]), axis=0) front_feats = np.concatenate((front_feats, event.front_feats[i]), axis=0) back_boxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容 back_feats = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(event.back_boxes)): back_boxes = np.concatenate((back_boxes, event.back_boxes[i]), axis=0) back_feats = np.concatenate((back_feats, event.back_feats[i]), axis=0) front_simi, back_simi = None, None if len(front_feats): front_simi = calsiml(front_feats, stdfeat) if len(back_feats): back_simi = calsiml(back_feats, stdfeat) '''前后摄相似度融合策略''' if len(front_feats) and len(back_feats): diff_simi = abs(front_simi - back_simi) if diff_simi>0.15: Similar = max([front_simi, back_simi]) else: Similar = (front_simi+back_simi)/2 elif len(front_feats) and len(back_feats)==0: Similar = front_simi elif len(front_feats)==0 and len(back_feats): Similar = back_simi else: Similar = None # 在event.front_feats和event.back_feats同时为空时 return Similar, front_simi, back_simi def calsimi_vs_stdfeat(event, stdfeat): evtfeat = event.feats_compose if isinstance(event.feats_select, list): if len(event.feats_select) and len(event.feats_select[0]): evtfeat = event.feats_select[0] else: return None, None, None else: evtfeat = event.feats_select if len(evtfeat)==0 or len(stdfeat)==0: return None, None, None evtfeat /= np.linalg.norm(evtfeat, axis=1)[:, None] stdfeat /= np.linalg.norm(stdfeat, axis=1)[:, None] matrix = 1 - cdist(evtfeat, stdfeat, 'cosine') matrix[matrix < 0] = 0 simi_mean = np.mean(matrix) simi_max = np.max(matrix) stdfeatm = np.mean(stdfeat, axis=0, keepdims=True) evtfeatm = np.mean(evtfeat, axis=0, keepdims=True) simi_mfeat = 1- np.maximum(0.0, cdist(stdfeatm, evtfeatm, 'cosine')) return simi_mean, simi_max, simi_mfeat[0,0] def calsimi_vs_evts(evta, evtb, simType=1): if simType==1: if len(evta.feats_compose) and len(evtb.feats_compose): feata = evta.feats_compose featb = evtb.feats_compose matrix = 1 - cdist(feata, featb, 'cosine') similar = np.mean(matrix) else: similar = None return similar if simType==2: if len(evta.feats_compose) and len(evtb.feats_compose): feata = evta.feats_compose featb = evtb.feats_compose matrix = 1 - cdist(feata, featb, 'cosine') similar = np.max(matrix) else: similar = None return similar if simType==3: if len(evta.feats_compose) and len(evtb.feats_compose): feata = evta.feats_compose featb = evtb.feats_compose similar = calsiml(feata, featb) else: similar = None return similar ##1. the front feats of evta, evtb fr_feata = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(evta.front_feats)): fr_feata = np.concatenate((fr_feata, evta.front_feats[i]), axis=0) fr_featb = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(evtb.front_feats)): fr_featb = np.concatenate((fr_featb, evtb.front_feats[i]), axis=0) ##2. the back feats of evta, evtb bk_feata = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(evta.back_feats)): bk_feata = np.concatenate((bk_feata, evta.back_feats[i]), axis=0) bk_featb = np.empty((0, 256), dtype=np.float64) ##和类doTracks兼容 for i in range(len(evtb.back_feats)): bk_featb = np.concatenate((bk_featb, evtb.back_feats[i]), axis=0) front_simi, back_simi = None, None if len(fr_feata) and len(fr_featb): front_simi = calsiml(fr_feata, fr_featb) if len(bk_feata) and len(bk_featb): back_simi = calsiml(bk_feata, bk_featb) '''前后摄相似度融合策略''' if front_simi is not None and back_simi is not None: diff_simi = abs(front_simi - back_simi) if diff_simi>0.15: similar = max([front_simi, back_simi]) else: similar = (front_simi+back_simi)/2 elif front_simi is not None and back_simi is None: similar = front_simi elif front_simi is None and back_simi is not None: similar = back_simi else: similar = None # 在event.front_feats和event.back_feats同时为空时 return similar