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 tracking.utils.plotting import Annotator, colors
from feat_extract.config import config as conf from feat_extract.config import config as conf
from feat_extract.inference import FeatsInterface from feat_extract.inference import FeatsInterface
from utils.event import Event from utils.event import ShoppingEvent
from genfeats import gen_bcd_features 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_ 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): def plot_save_image(event, savepath):
cameras = ('front', 'back') cameras = ('front', 'back')
@ -286,9 +144,6 @@ def save_event_subimg(event, savepath):
else: else:
boxes = event.back_boxes boxes = event.back_boxes
imgpaths = event.back_imgpaths imgpaths = event.back_imgpaths
for i, box in enumerate(boxes): for i, box in enumerate(boxes):
x1, y1, x2, y2, tid, score, cls, fid, bid = box x1, y1, x2, y2, tid, score, cls, fid, bid = box
@ -491,8 +346,8 @@ def one2one_simi():
##============================================ float32 ##============================================ float32
stdfeat = stdDict[stdbcd]["feats_ft32"] stdfeat = stdDict[stdbcd]["feats_ft32"]
evtfeat = event.feats_compose
evtfeat = event.feats_compose
if len(evtfeat)==0: continue if len(evtfeat)==0: continue
matrix = 1 - cdist(stdfeat, evtfeat, 'cosine') matrix = 1 - cdist(stdfeat, evtfeat, 'cosine')
@ -585,28 +440,9 @@ def gen_eventdict(sourcePath, saveimg=True):
pickpath = os.path.join(eventDataPath, f"{bname}.pickle") pickpath = os.path.join(eventDataPath, f"{bname}.pickle")
if os.path.isfile(pickpath): continue 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: try:
event = Event(source_path) event = ShoppingEvent(source_path, stype="data")
eventList.append(event) eventList.append(event)
with open(pickpath, 'wb') as f: with open(pickpath, 'wb') as f:
pickle.dump(event, f) pickle.dump(event, f)
@ -624,9 +460,7 @@ def gen_eventdict(sourcePath, saveimg=True):
for line in errEvents: for line in errEvents:
f.write(line + '\n') f.write(line + '\n')
def test_one2one(): def test_one2one():
bcdList, event_spath = [], [] bcdList, event_spath = [], []

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 @author: ym
""" """
import os import os
import pickle
import numpy as np import numpy as np
from pathlib import Path 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'] IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png']
VID_FORMAT = ['.mp4', '.avi'] VID_FORMAT = ['.mp4', '.avi']
class Event: class ShoppingEvent:
def __init__(self, eventpath, stype="data"): def __init__(self, eventpath, stype="data"):
'''stype: str, 'video', 'image', 'data', ''' '''stype: str, 'pickle', 'data', '''
self.eventpath = eventpath self.eventpath = eventpath
self.evtname = str(Path(eventpath).stem) self.evtname = str(Path(eventpath).stem)
@ -35,37 +36,115 @@ class Event:
self.one2n = None self.one2n = None
'''=========== 0/1_track.data =============================''' '''=========== 0/1_track.data ============================='''
self.back_yolobboxes = np.empty((0, 6), dtype=np.float64) self.back_yolobboxes = []
self.back_yolofeats = np.empty((0, 256), dtype=np.float64) self.back_yolofeats = []
self.back_trackerboxes = np.empty((0, 9), dtype=np.float64) self.back_trackerboxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
self.back_trackerfeats = np.empty((0, 256), dtype=np.float64) self.back_trackerfeats = {}
self.back_trackingboxes = np.empty((0, 9), dtype=np.float64) self.back_trackingboxes = []
self.back_trackingfeats = np.empty((0, 256), dtype=np.float64) self.back_trackingfeats = []
self.front_yolobboxes = np.empty((0, 6), dtype=np.float64) self.front_yolobboxes = []
self.front_yolofeats = np.empty((0, 256), dtype=np.float64) self.front_yolofeats = []
self.front_trackerboxes = np.empty((0, 9), dtype=np.float64) self.front_trackerboxes = np.empty((0, 9), dtype=np.float64) ##和类doTracks兼容
self.front_trackerfeats = np.empty((0, 256), dtype=np.float64) self.front_trackerfeats = {}
self.front_trackingboxes = np.empty((0, 9), dtype=np.float64) self.front_trackingboxes = []
self.front_trackingfeats = np.empty((0, 256), dtype=np.float64) self.front_trackingfeats = []
'''=========== 0/1_tracking_output.data ===================''' '''=========== 0/1_tracking_output.data ==================='''
self.back_boxes = np.empty((0, 9), dtype=np.float64) self.back_boxes = []
self.front_boxes = np.empty((0, 9), dtype=np.float64) self.back_feats = []
self.back_feats = np.empty((0, 256), dtype=np.float64) self.front_boxes = []
self.front_feats = np.empty((0, 256), dtype=np.float64) self.front_feats = []
self.feats_compose = np.empty((0, 256), dtype=np.float64)
self.feats_select = np.empty((0, 256), dtype=np.float64)
if stype=="data": if stype=="data":
self.from_datafile(eventpath) self.from_datafile(eventpath)
if stype=="pickle":
self.from_pklfile(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"])
if stype=="video": tboxes = frameDict["tboxes"]
self.from_video(eventpath) 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):
if stype=="image": with open(eventpath, 'rb') as f:
self.from_image(eventpath) 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]
def from_datafile(self, eventpath): def from_datafile(self, eventpath):
evtList = self.evtname.split('_') evtList = self.evtname.split('_')
if len(evtList)>=2 and len(evtList[-1])>=10 and evtList[-1].isdigit(): if len(evtList)>=2 and len(evtList[-1])>=10 and evtList[-1].isdigit():
@ -127,21 +206,21 @@ class Event:
'''========== 0/1_track.data ==========''' '''========== 0/1_track.data =========='''
if dataname.find("_track.data")>0: 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': if CamerType == '0':
self.back_yolobboxes = bboxes self.back_yolobboxes = bboxes
self.back_yolofeats = ffeats self.back_yolofeats = ffeats
self.back_trackerboxes = trackerboxes self.back_trackerboxes = trackerboxes
self.back_trackerfeats = tracker_feat_dict self.back_trackerfeats = trackerfeats
self.back_trackingboxes = trackingboxes self.back_trackingboxes = trackingboxes
self.back_trackingfeats = tracking_feat_dict self.back_trackingfeats = trackingfeats
if CamerType == '1': if CamerType == '1':
self.front_yolobboxes = bboxes self.front_yolobboxes = bboxes
self.front_yolofeats = ffeats self.front_yolofeats = ffeats
self.front_trackerboxes = trackerboxes self.front_trackerboxes = trackerboxes
self.front_trackerfeats = tracker_feat_dict self.front_trackerfeats = trackerfeats
self.front_trackingboxes = trackingboxes self.front_trackingboxes = trackingboxes
self.front_trackingfeats = tracking_feat_dict self.front_trackingfeats = trackingfeats
'''========== 0/1_tracking_output.data ==========''' '''========== 0/1_tracking_output.data =========='''
if dataname.find("_tracking_output.data")>0: if dataname.find("_tracking_output.data")>0:
@ -152,26 +231,37 @@ class Event:
elif CamerType == '1': elif CamerType == '1':
self.front_boxes = tracking_output_boxes self.front_boxes = tracking_output_boxes
self.front_feats = tracking_output_feats self.front_feats = tracking_output_feats
self.select_feat()
self.compose_feats()
def compose_feats(self): def compose_feats(self):
'''事件的特征集成''' '''事件的特征集成'''
feats_compose = np.empty((0, 256), dtype=np.float64) feats_compose = np.empty((0, 256), dtype=np.float64)
if len(self.front_feats): 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): 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 self.feats_compose = feats_compose
def select_feats(self): def select_feats(self):
'''事件的特征选择''' '''事件的特征选择'''
self.feats_select = []
if len(self.front_feats): if len(self.front_feats):
self.feats_select = self.front_feats self.feats_select = self.front_feats
else: elif len(self.back_feats):
self.feats_select = 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( def pipeline(
eventpath, eventpath,
savepath, savepath = '',
SourceType = "image", # video SourceType = "image", # video
stdfeat_path = None stdfeat_path = None
): ):
@ -53,47 +53,120 @@ def pipeline(
vpaths = get_video_pairs(eventpath) vpaths = get_video_pairs(eventpath)
elif SourceType == "image": elif SourceType == "image":
vpaths = get_image_pairs(eventpath) vpaths = get_image_pairs(eventpath)
'''
eventpath: 单个事件的存储路径
'''
'''======== 函数 yolo_resnet_tracker() 的参数字典 ========''' '''======== 函数 yolo_resnet_tracker() 的参数字典 ========'''
opt = parse_opt() opt = parse_opt()
optdict = vars(opt) optdict = vars(opt)
optdict["weights"] = r'D:\DetectTracking\ckpts\best_cls10_0906.pt'
optdict["is_save_img"] = True optdict["is_save_img"] = True
optdict["is_save_video"] = True optdict["is_save_video"] = True
event_tracks = [] 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: 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): if isinstance(vpath, list):
save_dir_video = save_dir_event / Path("images") 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: else:
save_dir_video = save_dir_event / Path(str(Path(vpath).stem)) save_dir_video = save_dir_event / Path(str(Path(vpath).stem))
if not save_dir_video.exists(): if not save_dir_video.exists():
save_dir_video.mkdir(parents=True, exist_ok=True) save_dir_video.mkdir(parents=True, exist_ok=True)
'''Yolo + Resnet + Tracker''' '''Yolo + Resnet + Tracker'''
optdict["source"] = vpath optdict["source"] = vpath
optdict["save_dir"] = save_dir_video 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) # bboxes = np.empty((0, 9), dtype = np.float32)
if bname.split('_')[0] == "0" or bname.find('back')>=0: # for frameDict in yrtOut:
vts = doBackTracks(bboxes, tracksdict) # bboxes = np.concatenate([bboxes, frameDict["tboxes"]], axis=0)
vts.classify()
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)) event_tracks.append(("back", vts))
if bname.split('_')[0] == "1" or bname.find('front')>=0: CameraEvent["tracking"] = vts
vts = doFrontTracks(bboxes, tracksdict) ShoppingDict["backCamera"] = CameraEvent
if CameraEvent["cameraType"] == "front":
vts = doFrontTracks(trackerboxes, trackefeats)
vts.classify() vts.classify()
event_tracks.append(("front", vts)) 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] illus = [None, None]
for CamerType, vts in event_tracks: for CamerType, vts in event_tracks:
@ -182,14 +255,39 @@ def main():
''' '''
函数pipeline(),遍历事件文件夹,选择类型 image 或 video, 函数pipeline(),遍历事件文件夹,选择类型 image 或 video,
''' '''
parmDict = {} evtdir = r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\比对测试\1209永辉超市测试"
parmDict["eventpath"] = r"\\192.168.1.28\share\测试视频数据以及日志\各模块测试记录\展厅测试\1120_展厅模型v801测试\扫A放A\20241121-144855-dce94b09-1100-43f1-92e8-33a1b538b159_6924743915848_6924743915848" evtdir = Path(evtdir)
parmDict["savepath"] = r"D:\contrast\detect" parmDict = {}
parmDict["savepath"] = r"D:\contrast\detect\pipeline"
parmDict["SourceType"] = "image" # video, image parmDict["SourceType"] = "image" # video, image
parmDict["stdfeat_path"] = None parmDict["stdfeat_path"] = None
pipeline(**parmDict) 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__": if __name__ == "__main__":

View File

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

View File

@ -394,21 +394,24 @@ class Track:
class doTracks: class doTracks:
def __init__(self, bboxes, TracksDict): def __init__(self, bboxes, trackefeats):
'''fundamental property''' '''fundamental property
trackefeats: dict, key 格式 "fid_bid"
'''
self.bboxes = bboxes self.bboxes = bboxes
# self.TracksDict = TracksDict # self.TracksDict = TracksDict
self.frameID = np.unique(bboxes[:, 7].astype(int)) self.frameID = np.unique(bboxes[:, 7].astype(int))
self.trackID = np.unique(bboxes[:, 4].astype(int)) self.trackID = np.unique(bboxes[:, 4].astype(int))
self.lboxes = self.array2list() self.lboxes = self.array2list()
self.lfeats = self.getfeats(TracksDict) self.lfeats = self.getfeats(trackefeats)
'''对 self.tracks 中的元素进行分类,将 track 归入相应列表中''' '''对 self.tracks 中的元素进行分类,将 track 归入相应列表中'''
self.Hands = [] self.Hands = []
self.Kids = [] self.Kids = []
self.Static = [] self.Static = []
self.Residual = [] self.Residual = []
self.Confirmed = []
self.DownWard = [] # subset of self.Residual self.DownWard = [] # subset of self.Residual
self.UpWard = [] # subset of self.Residual self.UpWard = [] # subset of self.Residual
self.FreeMove = [] # subset of self.Residual self.FreeMove = [] # subset of self.Residual
@ -435,15 +438,22 @@ class doTracks:
return lboxes return lboxes
def getfeats(self, TracksDict): def getfeats(self, trackefeats):
lboxes = self.lboxes lboxes = self.lboxes
lfeats = [] lfeats = []
for boxes in lboxes: for boxes in lboxes:
afeat = readDict(boxes, TracksDict) feats = []
lfeats.append(afeat) 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 return lfeats
def similarity(self): def similarity(self):
nt = len(self.tracks) nt = len(self.tracks)

View File

@ -6,6 +6,7 @@ Created on Mon Mar 4 18:36:31 2024
""" """
import numpy as np import numpy as np
import cv2 import cv2
import copy
from tracking.utils.mergetrack import track_equal_track from tracking.utils.mergetrack import track_equal_track
from scipy.spatial.distance import cdist from scipy.spatial.distance import cdist
from pathlib import Path from pathlib import Path
@ -19,9 +20,9 @@ from .track_back import backTrack
class doBackTracks(doTracks): 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)] 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.merge_based_hands(htrack)
self.Residual = 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 merge_based_hands(self, htrack): # def merge_based_hands(self, htrack):
# gtracks = htrack.Goods # gtracks = htrack.Goods
@ -122,6 +139,8 @@ class doBackTracks(doTracks):
# btrack, bfious = gtracks[1] # btrack, bfious = gtracks[1]
def associate_with_hand(self, htrack, gtrack): def associate_with_hand(self, htrack, gtrack):
''' '''
迁移至基类: 迁移至基类:

View File

@ -5,6 +5,7 @@ Created on Mon Mar 4 18:38:20 2024
@author: ym @author: ym
""" """
import cv2 import cv2
import copy
import numpy as np import numpy as np
from pathlib import Path from pathlib import Path
@ -16,8 +17,8 @@ from .dotracks import doTracks
from .track_front import frontTrack from .track_front import frontTrack
class doFrontTracks(doTracks): class doFrontTracks(doTracks):
def __init__(self, bboxes, TracksDict): def __init__(self, bboxes, frameDictList):
super().__init__(bboxes, TracksDict) super().__init__(bboxes, frameDictList)
# self.tracks = [frontTrack(b) for b in self.lboxes] # self.tracks = [frontTrack(b) for b in self.lboxes]
self.tracks = [frontTrack(b, f) for b, f in zip(self.lboxes, self.lfeats)] 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) tracks = self.sub_tracks(tracks, static_tracks)
freemoved_tracks = [t for t in tracks if t.is_free_move()] freemoved_tracks = [t for t in tracks if t.is_free_move()]
tracks = self.sub_tracks(tracks, freemoved_tracks) tracks = self.sub_tracks(tracks, freemoved_tracks)
self.Residual = 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): def associate_with_hand(self, htrack, gtrack):
''' '''

View File

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