modify at output data format
This commit is contained in:
Binary file not shown.
@ -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 = [], []
|
||||||
|
Binary file not shown.
155
contrast/utils/dotest.py
Normal file
155
contrast/utils/dotest.py
Normal 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
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
138
pipeline.py
138
pipeline.py
@ -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__":
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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)
|
||||||
|
@ -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):
|
||||||
'''
|
'''
|
||||||
迁移至基类:
|
迁移至基类:
|
||||||
|
@ -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):
|
||||||
'''
|
'''
|
||||||
|
Binary file not shown.
@ -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()
|
||||||
|
Reference in New Issue
Block a user