modify at output data format

This commit is contained in:
王庆刚
2024-12-10 19:01:54 +08:00
parent 1e6c5deee4
commit afd033b965
15 changed files with 545 additions and 290 deletions

View File

@ -52,10 +52,10 @@ from tracking.utils.read_data import extract_data, read_tracking_output, read_si
from tracking.utils.plotting import Annotator, colors
from feat_extract.config import config as conf
from feat_extract.inference import FeatsInterface
from utils.event import Event
from utils.event import ShoppingEvent
from genfeats import gen_bcd_features
IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
@ -83,148 +83,6 @@ def ft16_to_uint8(arr_ft16):
return arr_uint8, arr_ft16_
def creat_shopping_event(eventPath):
'''构造放入商品事件字典,这些事件需满足条件:
1) 前后摄至少有一条轨迹输出
2) 保存有帧图像,以便裁剪出 boxe 子图
'''
'''evtName 为一次购物事件'''
evtName = os.path.basename(eventPath)
evtList = evtName.split('_')
'''================ 0. 检查 evtName 及 eventPath 正确性和有效性 ================'''
if evtName.find('2024')<0 and len(evtList[0])!=15:
return
if not os.path.isdir(eventPath):
return
if len(evtList)==1 or (len(evtList)==2 and len(evtList[1])==0):
barcode = ''
else:
barcode = evtList[-1]
if len(evtList)==3 and evtList[-1]== evtList[-2]:
evtType = 'input'
else:
evtType = 'other'
'''================ 1. 构造事件描述字典,暂定 9 items ==============='''
event = {}
event['barcode'] = barcode
event['type'] = evtType
event['filepath'] = eventPath
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['one2one'] = None
event['one2n'] = None
event['feats_select'] = np.empty((0, 256), dtype=np.float64)
'''================= 2. 读取 data 文件 ============================='''
for dataname in os.listdir(eventPath):
# filename = '1_track.data'
datapath = os.path.join(eventPath, dataname)
if not os.path.isfile(datapath): continue
CamerType = dataname.split('_')[0]
''' 2.1 读取 0/1_track.data 中数据,暂不考虑'''
# if dataname.find("_track.data")>0:
# bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict = extract_data(datapath)
''' 2.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
if dataname.find("process.data")==0:
simiDict = read_similar(datapath)
event['one2one'] = simiDict['one2one']
event['one2n'] = simiDict['one2n']
if len(event['back_boxes'])==0 or len(event['front_boxes'])==0:
return None
'''2.3 事件的特征表征方式: 特征选择、特征集成'''
bk_feats = event['back_feats']
ft_feats = event['front_feats']
'''2.3.1 特征集成'''
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
'''2.3.1 特征选择'''
if len(ft_feats):
event['feats_select'] = ft_feats
'''================ 3. 读取图像文件地址并按照帧ID排序 ============='''
frontImgs, frontFid = [], []
backImgs, backFid = [], []
for imgname in os.listdir(eventPath):
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(eventPath, 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))
'''3.1 生成依据帧 ID 排序的前后摄图像地址列表'''
frontImgs = [frontImgs[i] for i in frontIdx]
backImgs = [backImgs[i] for i in backIdx]
'''3.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]
'''================ 4. 判断当前事件有效性,并添加至事件列表 =========='''
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"Event: {evtName}, Error, condt1: {condt1}, condt2: {condt2}")
return None
return event
def plot_save_image(event, savepath):
cameras = ('front', 'back')
@ -287,9 +145,6 @@ def save_event_subimg(event, savepath):
boxes = event.back_boxes
imgpaths = event.back_imgpaths
for i, box in enumerate(boxes):
x1, y1, x2, y2, tid, score, cls, fid, bid = box
@ -491,8 +346,8 @@ def one2one_simi():
##============================================ float32
stdfeat = stdDict[stdbcd]["feats_ft32"]
evtfeat = event.feats_compose
evtfeat = event.feats_compose
if len(evtfeat)==0: continue
matrix = 1 - cdist(stdfeat, evtfeat, 'cosine')
@ -586,27 +441,8 @@ def gen_eventdict(sourcePath, saveimg=True):
pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
if os.path.isfile(pickpath): continue
# if bname != "20241129-100321-a9dae9e3-7db5-4e31-959c-d7dfc228923e_6972636670213":
# continue
# eventDict = creat_shopping_event(eventPath)
# if eventDict:
# eventList.append(eventDict)
# with open(pickpath, 'wb') as f:
# pickle.dump(eventDict, f)
# print(f"Event: {eventName}, have saved!")
# if saveimg and eventDict:
# basename = os.path.basename(eventDict['filepath'])
# savepath = os.path.join(subimgPath, basename)
# if not os.path.exists(savepath):
# os.makedirs(savepath)
# save_event_subimg(eventDict, savepath)
try:
event = Event(source_path)
event = ShoppingEvent(source_path, stype="data")
eventList.append(event)
with open(pickpath, 'wb') as f:
pickle.dump(event, f)
@ -626,8 +462,6 @@ def gen_eventdict(sourcePath, saveimg=True):
def test_one2one():
bcdList, event_spath = [], []
for evtpath in eventSourcePath:

155
contrast/utils/dotest.py Normal file
View File

@ -0,0 +1,155 @@
# -*- coding: utf-8 -*-
"""
Created on Tue Dec 10 14:30:16 2024
@author: ym
"""
import os
import sys
import numpy as np
sys.path.append(r"D:\DetectTracking")
from tracking.utils.read_data import read_tracking_output, read_similar #, extract_data, read_deletedBarcode_file
IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
def creat_shopping_event(eventPath):
'''构造放入商品事件字典,这些事件需满足条件:
1) 前后摄至少有一条轨迹输出
2) 保存有帧图像,以便裁剪出 boxe 子图
'''
'''evtName 为一次购物事件'''
evtName = os.path.basename(eventPath)
evtList = evtName.split('_')
'''================ 0. 检查 evtName 及 eventPath 正确性和有效性 ================'''
if evtName.find('2024')<0 and len(evtList[0])!=15:
return
if not os.path.isdir(eventPath):
return
if len(evtList)==1 or (len(evtList)==2 and len(evtList[1])==0):
barcode = ''
else:
barcode = evtList[-1]
if len(evtList)==3 and evtList[-1]== evtList[-2]:
evtType = 'input'
else:
evtType = 'other'
'''================ 1. 构造事件描述字典,暂定 9 items ==============='''
event = {}
event['barcode'] = barcode
event['type'] = evtType
event['filepath'] = eventPath
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['one2one'] = None
event['one2n'] = None
event['feats_select'] = np.empty((0, 256), dtype=np.float64)
'''================= 2. 读取 data 文件 ============================='''
for dataname in os.listdir(eventPath):
# filename = '1_track.data'
datapath = os.path.join(eventPath, dataname)
if not os.path.isfile(datapath): continue
CamerType = dataname.split('_')[0]
''' 2.1 读取 0/1_track.data 中数据,暂不考虑'''
# if dataname.find("_track.data")>0:
# bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict = extract_data(datapath)
''' 2.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
if dataname.find("process.data")==0:
simiDict = read_similar(datapath)
event['one2one'] = simiDict['one2one']
event['one2n'] = simiDict['one2n']
if len(event['back_boxes'])==0 or len(event['front_boxes'])==0:
return None
'''2.3 事件的特征表征方式: 特征选择、特征集成'''
bk_feats = event['back_feats']
ft_feats = event['front_feats']
'''2.3.1 特征集成'''
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
'''2.3.1 特征选择'''
if len(ft_feats):
event['feats_select'] = ft_feats
'''================ 3. 读取图像文件地址并按照帧ID排序 ============='''
frontImgs, frontFid = [], []
backImgs, backFid = [], []
for imgname in os.listdir(eventPath):
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(eventPath, 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))
'''3.1 生成依据帧 ID 排序的前后摄图像地址列表'''
frontImgs = [frontImgs[i] for i in frontIdx]
backImgs = [backImgs[i] for i in backIdx]
'''3.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]
'''================ 4. 判断当前事件有效性,并添加至事件列表 =========='''
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"Event: {evtName}, Error, condt1: {condt1}, condt2: {condt2}")
return None
return event

View File

@ -5,6 +5,7 @@ Created on Tue Nov 26 17:35:05 2024
@author: ym
"""
import os
import pickle
import numpy as np
from pathlib import Path
@ -15,9 +16,9 @@ from tracking.utils.read_data import extract_data, read_tracking_output, read_si
IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
VID_FORMAT = ['.mp4', '.avi']
class Event:
class ShoppingEvent:
def __init__(self, eventpath, stype="data"):
'''stype: str, 'video', 'image', 'data', '''
'''stype: str, 'pickle', 'data', '''
self.eventpath = eventpath
self.evtname = str(Path(eventpath).stem)
@ -35,36 +36,114 @@ class Event:
self.one2n = None
'''=========== 0/1_track.data ============================='''
self.back_yolobboxes = np.empty((0, 6), dtype=np.float64)
self.back_yolofeats = np.empty((0, 256), dtype=np.float64)
self.back_trackerboxes = np.empty((0, 9), dtype=np.float64)
self.back_trackerfeats = np.empty((0, 256), dtype=np.float64)
self.back_trackingboxes = np.empty((0, 9), dtype=np.float64)
self.back_trackingfeats = np.empty((0, 256), dtype=np.float64)
self.back_yolobboxes = []
self.back_yolofeats = []
self.back_trackerboxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
self.back_trackerfeats = {}
self.back_trackingboxes = []
self.back_trackingfeats = []
self.front_yolobboxes = np.empty((0, 6), dtype=np.float64)
self.front_yolofeats = np.empty((0, 256), dtype=np.float64)
self.front_trackerboxes = np.empty((0, 9), dtype=np.float64)
self.front_trackerfeats = np.empty((0, 256), dtype=np.float64)
self.front_trackingboxes = np.empty((0, 9), dtype=np.float64)
self.front_trackingfeats = np.empty((0, 256), dtype=np.float64)
self.front_yolobboxes = []
self.front_yolofeats = []
self.front_trackerboxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
self.front_trackerfeats = {}
self.front_trackingboxes = []
self.front_trackingfeats = []
'''=========== 0/1_tracking_output.data ==================='''
self.back_boxes = np.empty((0, 9), dtype=np.float64)
self.front_boxes = np.empty((0, 9), dtype=np.float64)
self.back_feats = np.empty((0, 256), dtype=np.float64)
self.front_feats = np.empty((0, 256), dtype=np.float64)
self.feats_compose = np.empty((0, 256), dtype=np.float64)
self.feats_select = np.empty((0, 256), dtype=np.float64)
self.back_boxes = []
self.back_feats = []
self.front_boxes = []
self.front_feats = []
if stype=="data":
self.from_datafile(eventpath)
if stype=="pickle":
self.from_pklfile(eventpath)
if stype=="video":
self.from_video(eventpath)
self.feats_select = []
self.feats_compose = np.empty((0, 256), dtype=np.float64)
self.select_feats()
self.compose_feats()
# if stype=="image":
# self.from_image(eventpath)
def kerndata(self, ShoppingDict, camtype="backCamera"):
'''
camtype: str, "backCamera" or "frontCamera"
'''
yoloboxes, resfeats = [], []
trackerboxes = np.empty((0, 9), dtype=np.float64)
trackefeats = {}
trackingboxes, trackingfeats = [], []
frameDictList = ShoppingDict[camtype]["yoloResnetTracker"]
for frameDict in frameDictList:
yoloboxes.append(frameDict["bboxes"])
tboxes = frameDict["tboxes"]
trackefeats.update(frameDict["feats"])
trackerboxes = np.concatenate((trackerboxes, np.array(tboxes)), axis=0)
Residual = ShoppingDict[camtype]["tracking"].Residual
for track in Residual:
trackingboxes.append(track.boxes)
trackingfeats.append(track.features)
kdata = (yoloboxes, resfeats, trackerboxes, trackefeats, trackingboxes, trackingfeats)
tracking_out_boxes, tracking_out_feats = [], []
Confirmed = ShoppingDict[camtype]["tracking"].Confirmed
for track in Confirmed:
tracking_out_boxes.append(track.boxes)
tracking_out_feats.append(track.features)
outdata = (tracking_out_boxes, tracking_out_feats)
return kdata, outdata
def from_pklfile(self, eventpath):
with open(eventpath, 'rb') as f:
ShoppingDict = pickle.load(f)
self.eventpath = ShoppingDict["eventPath"]
self.evtname = ShoppingDict["eventName"]
self.barcode = ShoppingDict["barcode"]
'''=========== path of image and video =========== '''
self.back_videopath = ShoppingDict["backCamera"]["videoPath"]
self.front_videopath = ShoppingDict["frontCamera"]["videoPath"]
self.back_imgpaths = ShoppingDict["backCamera"]["imagePaths"]
self.front_imgpaths = ShoppingDict["frontCamera"]["imagePaths"]
'''===========对应于 0/1_track.data ============================='''
backdata, back_outdata = self.kerndata(ShoppingDict, "backCamera")
frontdata, front_outdata = self.kerndata(ShoppingDict, "frontCamera")
self.back_yolobboxes = backdata[0]
self.back_yolofeats = backdata[1]
self.back_trackerboxes = backdata[2]
self.back_trackerfeats = [3]
self.back_trackingboxes = [4]
self.back_trackingfeats = [5]
self.front_yolobboxes = frontdata[0]
self.front_yolofeats = frontdata[1]
self.front_trackerboxes = frontdata[2]
self.front_trackerfeats = frontdata[3]
self.front_trackingboxes = frontdata[4]
self.front_trackingfeats = frontdata[5]
'''===========对应于 0/1_tracking_output.data ============================='''
self.back_boxes = back_outdata[0]
self.back_feats = back_outdata[1]
self.front_boxes = front_outdata[0]
self.front_feats = front_outdata[1]
if stype=="image":
self.from_image(eventpath)
def from_datafile(self, eventpath):
evtList = self.evtname.split('_')
@ -127,21 +206,21 @@ class Event:
'''========== 0/1_track.data =========='''
if dataname.find("_track.data")>0:
bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict = extract_data(datapath)
bboxes, ffeats, trackerboxes, trackerfeats, trackingboxes, trackingfeats = extract_data(datapath)
if CamerType == '0':
self.back_yolobboxes = bboxes
self.back_yolofeats = ffeats
self.back_trackerboxes = trackerboxes
self.back_trackerfeats = tracker_feat_dict
self.back_trackerfeats = trackerfeats
self.back_trackingboxes = trackingboxes
self.back_trackingfeats = tracking_feat_dict
self.back_trackingfeats = trackingfeats
if CamerType == '1':
self.front_yolobboxes = bboxes
self.front_yolofeats = ffeats
self.front_trackerboxes = trackerboxes
self.front_trackerfeats = tracker_feat_dict
self.front_trackerfeats = trackerfeats
self.front_trackingboxes = trackingboxes
self.front_trackingfeats = tracking_feat_dict
self.front_trackingfeats = trackingfeats
'''========== 0/1_tracking_output.data =========='''
if dataname.find("_tracking_output.data")>0:
@ -152,26 +231,37 @@ class Event:
elif CamerType == '1':
self.front_boxes = tracking_output_boxes
self.front_feats = tracking_output_feats
self.select_feat()
self.compose_feats()
def compose_feats(self):
'''事件的特征集成'''
feats_compose = np.empty((0, 256), dtype=np.float64)
if len(self.front_feats):
feats_compose = np.concatenate((feats_compose, self.front_feats), axis=0)
for feat in self.front_feats:
feats_compose = np.concatenate((feats_compose, feat), axis=0)
if len(self.back_feats):
feats_compose = np.concatenate((feats_compose, self.back_feats), axis=0)
for feat in self.back_feats:
feats_compose = np.concatenate((feats_compose, feat), axis=0)
self.feats_compose = feats_compose
def select_feats(self):
'''事件的特征选择'''
self.feats_select = []
if len(self.front_feats):
self.feats_select = self.front_feats
else:
elif len(self.back_feats):
self.feats_select = self.back_feats
def main():
pklpath = r"D:\DetectTracking\evtresult\images2\ShoppingDict.pkl"
evt = ShoppingEvent(pklpath, stype='pickle')
if __name__ == "__main__":
main()

View File

@ -45,7 +45,7 @@ def get_interbcd_inputenents():
def pipeline(
eventpath,
savepath,
savepath = '',
SourceType = "image", # video
stdfeat_path = None
):
@ -53,46 +53,119 @@ def pipeline(
vpaths = get_video_pairs(eventpath)
elif SourceType == "image":
vpaths = get_image_pairs(eventpath)
'''
eventpath: 单个事件的存储路径
'''
'''======== 函数 yolo_resnet_tracker() 的参数字典 ========'''
opt = parse_opt()
optdict = vars(opt)
optdict["weights"] = r'D:\DetectTracking\ckpts\best_cls10_0906.pt'
optdict["is_save_img"] = True
optdict["is_save_video"] = True
event_tracks = []
## 构造购物事件字典
evtname = Path(eventpath).stem
barcode = evtname.split('_')[-1] if len(evtname.split('_'))>=2 \
and len(evtname.split('_')[-1])>=8 \
and evtname.split('_')[-1].isdigit() else ''
'''事件结果存储文件夹'''
if not savepath:
savepath = Path(__file__).resolve().parents[0] / "evtresult"
save_dir_event = Path(savepath) / evtname
ShoppingDict = {"eventPath": eventpath,
"eventName": evtname,
"barcode": barcode,
"eventType": '', # "input", "output", "other"
"frontCamera": {},
"backCamera": {}}
for vpath in vpaths:
'''事件结果文件夹'''
save_dir_event = Path(savepath) / Path(os.path.basename(eventpath))
'''相机事件字典构造'''
CameraEvent = {"cameraType": '', # "front", "back"
"videoPath": '',
"imagePaths": [],
"yoloResnetTracker": [],
"tracking": [],
}
if isinstance(vpath, list):
CameraEvent["imagePaths"] = vpath
bname = os.path.basename(vpath[0])
if not isinstance(vpath, list):
CameraEvent["videoPath"] = vpath
bname = os.path.basename(vpath)
if bname.split('_')[0] == "0" or bname.find('back')>=0:
CameraEvent["cameraType"] = "back"
if bname.split('_')[0] == "1" or bname.find('front')>=0:
CameraEvent["cameraType"] = "front"
'''事件结果存储文件夹'''
if isinstance(vpath, list):
save_dir_video = save_dir_event / Path("images")
else:
save_dir_video = save_dir_event / Path(str(Path(vpath).stem))
if not save_dir_video.exists():
save_dir_video.mkdir(parents=True, exist_ok=True)
'''Yolo + Resnet + Tracker'''
optdict["source"] = vpath
optdict["save_dir"] = save_dir_video
yrtOut = yolo_resnet_tracker(**optdict)
tracksdict = yolo_resnet_tracker(**optdict)
CameraEvent["yoloResnetTracker"] = yrtOut
bboxes = tracksdict['TrackBoxes']
bname = os.path.basename(vpath[0]) if isinstance(vpath, list) else os.path.basename(vpath)
if bname.split('_')[0] == "0" or bname.find('back')>=0:
vts = doBackTracks(bboxes, tracksdict)
# bboxes = np.empty((0, 9), dtype = np.float32)
# for frameDict in yrtOut:
# bboxes = np.concatenate([bboxes, frameDict["tboxes"]], axis=0)
trackerboxes = np.empty((0, 9), dtype=np.float64)
trackefeats = {}
for frameDict in yrtOut:
tboxes = frameDict["tboxes"]
ffeats = frameDict["feats"]
trackerboxes = np.concatenate((trackerboxes, np.array(tboxes)), axis=0)
for i in range(len(tboxes)):
fid, bid = int(tboxes[i, 7]), int(tboxes[i, 8])
trackefeats.update({f"{fid}_{bid}": ffeats[f"{fid}_{bid}"]})
'''tracking'''
if CameraEvent["cameraType"] == "back":
vts = doBackTracks(trackerboxes, trackefeats)
vts.classify()
event_tracks.append(("back", vts))
if bname.split('_')[0] == "1" or bname.find('front')>=0:
vts = doFrontTracks(bboxes, tracksdict)
CameraEvent["tracking"] = vts
ShoppingDict["backCamera"] = CameraEvent
if CameraEvent["cameraType"] == "front":
vts = doFrontTracks(trackerboxes, trackefeats)
vts.classify()
event_tracks.append(("front", vts))
CameraEvent["tracking"] = vts
ShoppingDict["frontCamera"] = CameraEvent
# pklpath = save_dir_event / "ShoppingDict.pkl"
# with open(str(pklpath), 'wb') as f:
# pickle.dump(ShoppingDict, f)
pklpath = Path(savepath) / evtname+".pkl"
with open(str(pklpath), 'wb') as f:
pickle.dump(ShoppingDict, f)
'''轨迹显示模块'''
illus = [None, None]
@ -182,14 +255,39 @@ def main():
'''
函数pipeline(),遍历事件文件夹,选择类型 image 或 video,
'''
parmDict = {}
parmDict["eventpath"] = r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\展厅测试\1120_展厅模型v801测试\扫A放A\20241121-144855-dce94b09-1100-43f1-92e8-33a1b538b159_6924743915848_6924743915848"
evtdir = r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\比对测试\1209永辉超市测试"
evtdir = Path(evtdir)
parmDict["savepath"] = r"D:\contrast\detect"
parmDict = {}
parmDict["savepath"] = r"D:\contrast\detect\pipeline"
parmDict["SourceType"] = "image" # video, image
parmDict["stdfeat_path"] = None
k = 1
errEvents = []
for item in evtdir.iterdir():
if item.is_dir():
item = r"D:\exhibition\images\images2\images2"
parmDict["eventpath"] = item
try:
pipeline(**parmDict)
except Exception as e:
errEvents.append(item)
# k+=1
# if k==1:
# break
errfile = os.path.join(parmDict["savepath"], f'error_events.txt')
with open(errfile, 'w', encoding='utf-8') as f:
for line in errEvents:
f.write(line + '\n')
if __name__ == "__main__":

View File

@ -196,8 +196,8 @@ def yolo_resnet_tracker(
tracker = init_trackers(tracker_yaml, bs)[0]
dt = (Profile(), Profile(), Profile())
track_boxes = np.empty((0, 9), dtype = np.float32)
TracksDict = {}
# trackerBoxes = np.empty((0, 9), dtype = np.float32)
yoloResnetTracker = []
for path, im, im0s, vid_cap, s in dataset:
with dt[0]:
im = torch.from_numpy(im).to(model.device)
@ -245,24 +245,23 @@ def yolo_resnet_tracker(
tracks[:, 7] = frameId
# trackerBoxes = np.concatenate([trackerBoxes, tracks], axis=0)
'''================== 1. 存储 dets/subimgs/features Dict ============='''
imgs, features = ReIDEncoder.inference(im0, tracks)
# imgs, features = inference_image(im0, tracks)
# TrackerFeats = np.concatenate([TrackerFeats, features], axis=0)
imgdict = {}
boxdict = {}
featdict = {}
for ii, bid in enumerate(tracks[:, 8]):
imgdict.update({int(bid): imgs[ii]}) # [f"img_{int(bid)}"] = imgs[i]
boxdict.update({int(bid): tracks[ii, :]}) # [f"box_{int(bid)}"] = tracks[i, :]
featdict.update({int(bid): features[ii, :]}) # [f"feat_{int(bid)}"] = features[i, :]
TracksDict[f"frame_{int(frameId)}"] = {"imgs":imgdict, "boxes":boxdict, "feats":featdict}
featdict.update({f"{int(frameId)}_{int(bid)}": features[ii, :]}) # [f"feat_{int(bid)}"] = features[i, :]
track_boxes = np.concatenate([track_boxes, tracks], axis=0)
frameDict = {"path": path,
"fid": int(frameId),
"bboxes": det,
"tboxes": tracks,
"imgs": imgs,
"feats": featdict}
yoloResnetTracker.append(frameDict)
# imgs, features = inference_image(im0, tracks)
# TrackerFeats = np.concatenate([TrackerFeats, features], axis=0)
'''================== 2. 提取手势位置 ==================='''
for *xyxy, id, conf, cls, fid, bid in reversed(tracks):
@ -314,11 +313,8 @@ def yolo_resnet_tracker(
# Print time (inference-only)
LOGGER.info(f"{s}{'' if len(det) else '(no detections), '}{dt[1].dt * 1E3:.1f}ms")
## track_boxes: Array, [x1, y1, x2, y2, track_id, score, cls, frame_index, box_id]
TracksDict.update({"TrackBoxes": track_boxes})
return TracksDict
return yoloResnetTracker

View File

@ -394,21 +394,24 @@ class Track:
class doTracks:
def __init__(self, bboxes, TracksDict):
'''fundamental property'''
def __init__(self, bboxes, trackefeats):
'''fundamental property
trackefeats: dict, key 格式 "fid_bid"
'''
self.bboxes = bboxes
# self.TracksDict = TracksDict
self.frameID = np.unique(bboxes[:, 7].astype(int))
self.trackID = np.unique(bboxes[:, 4].astype(int))
self.lboxes = self.array2list()
self.lfeats = self.getfeats(TracksDict)
self.lfeats = self.getfeats(trackefeats)
'''对 self.tracks 中的元素进行分类,将 track 归入相应列表中'''
self.Hands = []
self.Kids = []
self.Static = []
self.Residual = []
self.Confirmed = []
self.DownWard = [] # subset of self.Residual
self.UpWard = [] # subset of self.Residual
self.FreeMove = [] # subset of self.Residual
@ -435,16 +438,23 @@ class doTracks:
return lboxes
def getfeats(self, TracksDict):
def getfeats(self, trackefeats):
lboxes = self.lboxes
lfeats = []
for boxes in lboxes:
afeat = readDict(boxes, TracksDict)
lfeats.append(afeat)
feats = []
for i in range(boxes.shape[0]):
fid, bid = int(boxes[i, 7]), int(boxes[i, 8])
key = f"{int(fid)}_{int(bid)}"
if key in trackefeats:
feats.append(trackefeats[key])
feats = np.asarray(feats, dtype=np.float32)
lfeats.append(feats)
return lfeats
def similarity(self):
nt = len(self.tracks)
similar_dict = {}

View File

@ -6,6 +6,7 @@ Created on Mon Mar 4 18:36:31 2024
"""
import numpy as np
import cv2
import copy
from tracking.utils.mergetrack import track_equal_track
from scipy.spatial.distance import cdist
from pathlib import Path
@ -19,9 +20,9 @@ from .track_back import backTrack
class doBackTracks(doTracks):
def __init__(self, bboxes, TracksDict):
def __init__(self, bboxes, trackefeats):
super().__init__(bboxes, TracksDict)
super().__init__(bboxes, trackefeats)
self.tracks = [backTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)]
@ -113,6 +114,22 @@ class doBackTracks(doTracks):
# self.merge_based_hands(htrack)
self.Residual = tracks
self.Confirmed = self.confirm_track()
def confirm_track(self):
Confirmed = None
mindist = 0
for track in self.Residual:
md = min(track.trajrects_wh)
if md > mindist:
mindist = copy.deepcopy(md)
Confirmed = copy.deepcopy(track)
if Confirmed is not None:
return [Confirmed]
return []
# def merge_based_hands(self, htrack):
# gtracks = htrack.Goods
@ -122,6 +139,8 @@ class doBackTracks(doTracks):
# btrack, bfious = gtracks[1]
def associate_with_hand(self, htrack, gtrack):
'''
迁移至基类:

View File

@ -5,6 +5,7 @@ Created on Mon Mar 4 18:38:20 2024
@author: ym
"""
import cv2
import copy
import numpy as np
from pathlib import Path
@ -16,8 +17,8 @@ from .dotracks import doTracks
from .track_front import frontTrack
class doFrontTracks(doTracks):
def __init__(self, bboxes, TracksDict):
super().__init__(bboxes, TracksDict)
def __init__(self, bboxes, frameDictList):
super().__init__(bboxes, frameDictList)
# self.tracks = [frontTrack(b) for b in self.lboxes]
self.tracks = [frontTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)]
@ -84,11 +85,24 @@ class doFrontTracks(doTracks):
tracks = self.sub_tracks(tracks, static_tracks)
freemoved_tracks = [t for t in tracks if t.is_free_move()]
tracks = self.sub_tracks(tracks, freemoved_tracks)
self.Residual = tracks
self.Confirmed = self.confirm_track()
def confirm_track(self):
Confirmed = None
mindist = 0
for track in self.Residual:
md = min(track.trajrects_wh)
if md > mindist:
mindist = copy.deepcopy(md)
Confirmed = copy.deepcopy(track)
if Confirmed is not None:
return [Confirmed]
return []
def associate_with_hand(self, htrack, gtrack):
'''

View File

@ -34,10 +34,12 @@ def find_samebox_in_array(arr, target):
return -1
def extract_data(datapath):
'''
0/1_track.data 数据读取
对于特征,需要构造两个对象:
(1) tracking输出 boxes依据 (fid, bid) 找到对应的 feats, tracker_feat_dict 实现较为方便
(2) frameDictList 中元素为 frameDict输出同一接口
'''
bboxes, ffeats = [], []
@ -45,9 +47,7 @@ def extract_data(datapath):
trackerfeats = np.empty((0, 256), dtype=np.float64)
boxes, feats, tboxes, tfeats = [], [], [], []
timestamps, frameIds = [], []
with open(datapath, 'r', encoding='utf-8') as lines:
for line in lines:
line = line.strip() # 去除行尾的换行符和可能的空白字符
@ -102,16 +102,17 @@ def extract_data(datapath):
assert(len(bboxes)==len(ffeats)), "Error at Yolo output!"
assert(len(trackerboxes)==len(trackerfeats)), "Error at tracker output!"
tracker_feat_dict = {}
tracker_feat_dict["timestamps"] = timestamps
tracker_feat_dict["frameIds"] = frameIds
for i in range(len(trackerboxes)):
tid, fid, bid = int(trackerboxes[i, 4]), int(trackerboxes[i, 7]), int(trackerboxes[i, 8])
if f"frame_{fid}" not in tracker_feat_dict:
tracker_feat_dict[f"frame_{fid}"]= {"feats": {}}
tracker_feat_dict[f"frame_{fid}"]["feats"].update({bid: trackerfeats[i, :]})
## 生成帧为单位的特征列表
tracker_feats = {}
frmIDs = np.sort(np.unique(trackerboxes[:, 7].astype(int)))
for fid in frmIDs:
idx = np.where(trackerboxes[:, 7] == fid)[0]
boxes = trackerboxes[idx, :]
feats = trackerfeats[idx, :]
for i in range(len(boxes)):
f, b = int(boxes[i, 7]), int(boxes[i, 8])
tracker_feats.update({f"{f}_{b}": feats[i, :]})
boxes, trackingboxes= [], []
tracking_flag = False
@ -137,18 +138,41 @@ def extract_data(datapath):
if len(boxes):
trackingboxes.append(np.array(boxes))
tracking_feat_dict = {}
# tracking_feat_dict = {}
# try:
# for i, boxes in enumerate(trackingboxes):
# for box in boxes:
# tid, fid, bid = int(box[4]), int(box[7]), int(box[8])
# if f"track_{tid}" not in tracking_feat_dict:
# tracking_feat_dict[f"track_{tid}"]= {"feats": {}}
# tracking_feat_dict[f"track_{tid}"]["feats"].update({f"{fid}_{bid}": tracker_feat_dict[f"frame_{fid}"]["feats"][bid]})
# except Exception as e:
# print(f'Path: {datapath}, tracking_feat_dict can not be structured correcttly, Error: {e}')
# tracker_feat_dict = {}
# tracker_feat_dict["timestamps"] = timestamps
# tracker_feat_dict["frameIds"] = frameIds
# for i in range(len(trackerboxes)):
# fid, bid = int(trackerboxes[i, 7]), int(trackerboxes[i, 8])
# if f"frame_{fid}" not in tracker_feat_dict:
# tracker_feat_dict[f"frame_{fid}"]= {"feats": {}}
# tracker_feat_dict[f"frame_{fid}"]["feats"].update({bid: trackerfeats[i, :]})
trackingfeats = []
try:
for i, boxes in enumerate(trackingboxes):
feats = []
for box in boxes:
tid, fid, bid = int(box[4]), int(box[7]), int(box[8])
if f"track_{tid}" not in tracking_feat_dict:
tracking_feat_dict[f"track_{tid}"]= {"feats": {}}
tracking_feat_dict[f"track_{tid}"]["feats"].update({f"{fid}_{bid}": tracker_feat_dict[f"frame_{fid}"]["feats"][bid]})
fid, bid = int(box[7]), int(box[8])
feat = tracker_feats[f"{fid}_{bid}"]
feats.append(feat)
trackingfeats.append(np.array(feats))
except Exception as e:
print(f'Path: {datapath}, tracking_feat_dict can not be structured correcttly, Error: {e}')
print(f'Path: {datapath}, trackingfeats can not be structured correcttly, Error: {e}')
return bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict
# return bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, trackingfeats
return bboxes, ffeats, trackerboxes, tracker_feats, trackingboxes, trackingfeats
def read_tracking_output(filepath):
'''
@ -236,8 +260,6 @@ def read_returnGoods_file(filePath):
lines = f.readlines()
clean_lines = [line.strip().replace("'", '').replace('"', '') for line in lines]
all_list = []
split_flag, dict = False, {}
barcode_list, similarity_list = [], []
@ -318,14 +340,15 @@ def read_seneor(filepath):
def read_similar(filePath):
SimiDict = {}
SimiDict['one2one'] = []
SimiDict['one2SN'] = []
SimiDict['one2n'] = []
with open(filePath, 'r', encoding='utf-8') as f:
lines = f.readlines()
clean_lines = [line.strip().replace("'", '').replace('"', '') for line in lines]
one2one_list, one2n_list = [], []
one2one_list, one2SN_list, one2n_list = [], [], []
Flag_1to1, Flag_1ton = False, False
Flag_1to1, Flag_1toSN, Flag_1ton = False, False, False
for i, line in enumerate(clean_lines):
line = line.strip()
if line.endswith(','):
@ -334,18 +357,26 @@ def read_similar(filePath):
if not line:
if len(one2one_list): SimiDict['one2one'] = one2one_list
if len(one2SN_list): SimiDict['one2SN'] = one2SN_list
if len(one2n_list): SimiDict['one2n'] = one2n_list
one2one_list, one2n_list = [], []
Flag_1to1, Flag_1ton = False, False
one2one_list, one2SN_list, one2n_list = [], [], []
Flag_1to1, Flag_1toSN, Flag_1ton = False, False, False
continue
if line.find('oneToOne')>=0:
Flag_1to1, Flag_1ton = True, False
Flag_1to1, Flag_1toSN, Flag_1ton = True, False,False
continue
if line.find('oneToSN')>=0:
Flag_1to1, Flag_1toSN, Flag_1ton = False, True, False
continue
if line.find('oneTon')>=0:
Flag_1to1, Flag_1ton = False, True
Flag_1to1, Flag_1toSN, Flag_1ton = False, False, True
continue
if Flag_1to1:
barcode = line.split(',')[0].strip()
value = line.split(',')[1].split(':')[1].strip()
@ -354,6 +385,14 @@ def read_similar(filePath):
one2one_list.append(Dict)
continue
if Flag_1toSN:
barcode = line.split(',')[0].strip()
value = line.split(',')[1].split(':')[1].strip()
Dict['barcode'] = barcode
Dict['similar'] = float(value)
one2SN_list.append(Dict)
continue
if Flag_1ton:
label = line.split(':')[0].strip()
value = line.split(':')[1].strip()