# -*- coding: utf-8 -*- """ Created on Wed Oct 16 17:37:07 2024 @author: ym """ # import csv import os # import platform # import sys from pathlib import Path import glob import numpy as np import copy import matplotlib.pyplot as plt from imgs_inference import run_yolo from event_time_specify import devide_motion_state#, state_measure from tracking.utils.read_data import read_seneor # IMG_FORMATS = 'bmp', 'dng', 'jpeg', 'jpg', 'mpo', 'png', 'tif', 'tiff', 'webp', 'pfm' # include image suffixes # VID_FORMATS = 'asf', 'avi', 'gif', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'ts', 'wmv' # include video suffixes def filesort(p): ''' 需将图像文件名标准化 ''' files = [] files.extend(sorted(glob.glob(os.path.join(p, '*.jpg')))) # images = [x for x in files if x.split('.')[-1].lower() in IMG_FORMATS] tamps_0, tamps_1 = [], [] files_0, files_1 = [], [] for file in files: basename = os.path.basename(file) # if basename.find('frameId')<0: continue f, ext = os.path.splitext(basename) _, camer, tamp = f.split('_') if camer == '0': tamps_0.append(int(tamp)) files_0.append(file) if camer == '1': tamps_1.append(int(tamp)) files_1.append(file) idx0 = sorted(range(len(tamps_0)), key=lambda k: tamps_0[k]) files0 = [files_0[i] for i in idx0] idx1 = sorted(range(len(tamps_1)), key=lambda k: tamps_1[k]) files1 = [files_1[i] for i in idx1] return (files0, files1) def rename(filePath, tmin): """ 重命名函数fun1 输入:文件夹路径 功能:对文件夹中的全部文件进行随机命名 """ suffix = '.png' # 设置后缀,筛选特定文件以更改名称 for file in os.listdir(filePath): if file.endswith(suffix): name = file.split('.')[0] tamp = int(name.split('_')[2])-tmin suffix = file.split('.')[1] newname = name +f'_{int(tamp)}.'+suffix os.rename(os.path.join(filePath, file), os.path.join(filePath, newname)) def rerename(filePath=None): """ 重命名函数fun1 输入:文件夹路径 功能:对文件夹中的全部文件进行随机命名 """ suffix = '.png' # 设置后缀,筛选特定文件以更改名称 for file in os.listdir(filePath): if file.endswith(suffix): name = file.split('.')[0] names = name.split('_') if len(names)>=6: newname = "_".join(names[0:5])+'.png' os.rename(os.path.join(filePath, file), os.path.join(filePath, newname)) def state_measure(periods, weights, hands, spath=None): ''' 数据类型 后摄: 0, 前摄: 1, CV综合: 2, 重力: 9 frstate_0/1: 帧ID 时间戳 单摄状态1 单摄状态2 活动轨迹标记 0 1 2 3 4:end time_stream = np.concatenate((tstream, weights)) time_stream: 序列索引号 数据类型 时间戳 单摄状态1/重力值 单摄状态2/重力(t0, t1) CV状态/重力(t0', t1') 综合数据类型 综合状态 0 1 2 3 4 5 6 7 单摄状态1:基于运动轨迹的起止点确定的运动区间 单摄状态2: 基于滑动窗口的起止点(窗口终点)确定的运动区间 重力(t0, t1): 重力波动的精确时间区间,基于重力波动的起止点,而不是仅依赖重力稳定时间 重力(t0', t1'): 根据加退购对重力波动窗口进行扩展,扩展应该涵盖购物事件的发生过程 方案: 前后摄状态进行或运算 CV与重力状态进行与运算 ''' # BackType = 0 # 后摄数据类型 # FrontType = 1 # 前摄数据类型 CameraType = 2 # CV数据综合类型 HandType = 3 # 手部类型 WeightType = 9 # 重力数据类型 WeightStableThresh = 7.5 # 单位:g,重力稳定状态下的最大波动范围 WeightWinWidth = 10 # 单位:重力数据点数,该值和采样间隔关联,重力稳定时间设定为500ms = WeightWinWidth * 采样间隔 CameraTimeInterval = 100 # 单位:ms,前后摄状态进行或运算时的时间间隔阈值 InputFrontNum = 10 # 重力增加(放入)向前延拓的重力数据点数 InputBackNum = 0 # 重力增加(放入)向后延拓的重力数据点数 OutputFrontNum = 2 # 重力减少(取出)向前延拓的重力数据点数 OutputBackNum = 10 # 重力减少(取出)向前延拓的重力数据点数 CompTimeInterval = 150 # 单位:ms,CV状态和重力状态进行与运算时的时间间隔阈值 '''==================== 1.1 Weight 数据综合并排序 =======================''' nw = len(weights) widx = np.array([k for k in range(0, nw)])[:, None] wtype = WeightType * np.ones((nw, 1)) wstate = np.zeros((nw, 4)) weights = np.concatenate((widx, wtype, weights, wstate), axis=1).astype(np.int64) weights[:, 6] = WeightType weights = weights[np.argsort(weights[:, 2]), :] '''=================== 1.2 基确Weight的状态切割 =========================''' w_max = np.max(weights[:, 3]) # i0=0 for i2 in range(0, nw): i1 = max(i2 - WeightWinWidth, 0) wvalue = weights[i1:i2+1, 3] wi2 = weights[i2, 3] wmin = np.min(wvalue) wmax = np.max(wvalue) '''对重力波动区间进行标记,并标记最新一次重力稳定值的索引和相应重力值''' if wmax - wmin > WeightStableThresh: weights[i2, 4] = w_max if i2==0: i0=0 wi0 = weights[i0, 3] elif i2>0 and weights[i2-1, 4]==0: i0 = copy.deepcopy(i2) wi0 = weights[i0, 3] if i2>0 and weights[i2-1, 4]!=0 and weights[i2, 4]==0: # 当前稳定状态下的重力值和前一次重力稳定值的差值,确定放入还是取出 if wi2-wi0 > WeightStableThresh: i00 = max(i0 - InputFrontNum, 0) i22 = min(i2 + InputBackNum, nw) elif wi2-wi0 < -1*WeightStableThresh: i00 = max(i0 - OutputFrontNum, 0) i22 = min(i2 + OutputBackNum, nw) else: i00 = max(i0 - max(InputFrontNum, OutputFrontNum), 0) i22 = min(i2 + max(InputBackNum, OutputBackNum), nw) weights[i00:i22, 5] = w_max + 100 '''===================== 2.1 CV 数据综合并排序 ==========================''' BackType, frstate_0 = periods[0] FrontType, frstate_1 = periods[1] n0, n1 = len(frstate_0), len(frstate_1) idx0 = np.array([i for i in range(0, n0)], dtype=np.int64)[:, None] idx1 = np.array([i for i in range(0, n1)], dtype=np.int64)[:, None] ctype0 = BackType * np.ones((n0, 1), dtype=np.int64) ctype1 = FrontType * np.ones((n1, 1), dtype=np.int64) tstamp0 = frstate_0[:,1][:, None] tstamp1 = frstate_1[:,1][:, None] state0 = frstate_0[:,2][:, None] state00 = frstate_0[:,3][:, None] state1 = frstate_1[:,2][:, None] state11 = frstate_1[:,3][:, None] '''序列索引号, 相机类型,时间戳, 单摄状态1、单摄状态2、CV综合状态、综合数据类型、综合状态 0 1 2 3 4 5 6 7 ''' tstream0 = np.concatenate((idx0, ctype0, tstamp0, state0, state00), axis=1) tstream1 = np.concatenate((idx1, ctype1, tstamp1, state1, state11), axis=1) tstream = np.concatenate((tstream0, tstream1), axis=0) tstream = np.concatenate((tstream, np.zeros((len(tstream), 3), dtype=np.int64)), axis=1) tstream[:, 6] = CameraType tstream = tstream[np.argsort(tstream[:, 2]), :] '''=============== 2.2 基于前后摄运动轨迹起止点确定CV综合状态 ============''' for i in range(0, len(tstream)): idx, ctype, stamp, state = tstream[i, :4] if i==0: tstream[i, 5] = state if i>0: j = i-1 idx0, ctype0, stamp0, state0 = tstream[j, :4] while stamp-stamp0 < CameraTimeInterval and ctype == ctype0 and j>0: j -= 1 idx0, ctype0, stamp0, state0 = tstream[j, :4] '''两摄像头状态的或运算. 由于前后摄图像不同时,如何构造或运算,关键在于选择不同摄像头的对齐点 i时刻摄像头(ctype)状态state,另一摄像头(ctype0 != ctype)距 i 最近最近时刻 j 的状态state0 ''' if ctype != ctype0 and state0==1: tstream[i, 5] = state0 else: tstream[i, 5] = state '''================ 3.1 CV、Wweight 数据综合并排序 ======================''' time_stream = np.concatenate((tstream, weights), axis=0, dtype=np.int64) time_stream = time_stream[np.argsort(time_stream[:, 2]), :] tmin = np.min(time_stream[:, 2]) time_stream[:, 2] = time_stream[:, 2] - tmin '''============== 3.2 基于 CV 和 Weight 确定 Cart 的综合状态 ============''' for i in range(0, len(time_stream)): idx, _, stamp, value, _, state, ctype = time_stream[i, :7] state = min(state, 1) if i==0: time_stream[i, 7] = state if i>0: j = i-1 idx0, _, stamp0, value0, _, state0, ctype0 = time_stream[j, :7] while stamp-stamp0 < CompTimeInterval and ctype == ctype0 and j>0: j -= 1 idx0, _, stamp0, value0, _, state0, ctype0 = time_stream[j, :7] '''CV与Weight的与运算. 由于CV与Weight不同时,如何构造与运算,关键在于选择不同数据源的对齐点 i时数据类型(ctype)状态state,另一数据类型(ctype0 != ctype)距 i 最近最近时刻 j 的状态state0 ''' if ctype != ctype0 and state !=0 and state0 !=0: time_stream[i, 7] = 1 MotionSlice, motion_slice = [], [] t0 = time_stream[0, 7] for i in range(1, len(time_stream)): f0 = time_stream[i-1, 7] f1 = time_stream[i, 7] if f0==0 and f1==1: t0 = time_stream[i, 2] elif f0==1 and f1==0: t1 = time_stream[i, 2] if t1-t0>100: #ms MotionSlice.append((t0+tmin, t1+tmin)) motion_slice.append((t0, t1)) else: print(f"T0: {t0}, T1: {t1}") '''===================== 4. Hands数据综合并排序 ==========================''' BackType, hdstate_0 = hands[0] FrontType, hdstate_1 = hands[1] n0, n1 = len(hdstate_0), len(hdstate_1) idx0 = np.array([i for i in range(0, n0)], dtype=np.int64)[:, None] idx1 = np.array([i for i in range(0, n1)], dtype=np.int64)[:, None] ctype0 = BackType * np.ones((n0, 1), dtype=np.int64) ctype1 = FrontType * np.ones((n1, 1), dtype=np.int64) hstamp0 = hdstate_0[:,1][:, None] hstamp1 = hdstate_1[:,1][:, None] state0 = hdstate_0[:,2][:, None] state1 = hdstate_1[:,2][:, None] '''序列索引号, 相机类型,时间戳, 单摄手部状态、手部综合状态、保留位2、综合数据类型、综合状态 0 1 2 3 4 5 6 7 ''' hstream0 = np.concatenate((idx0, ctype0, hstamp0, state0), axis=1) hstream1 = np.concatenate((idx1, ctype1, hstamp1, state1), axis=1) hstream = np.concatenate((hstream0, hstream1), axis=0) hstream = np.concatenate((hstream, np.zeros((len(hstream), 4), dtype=np.int64)), axis=1) hstream[:, 6] = HandType hstream = hstream[np.argsort(hstream[:, 2]), :] for i in range(0, len(hstream)): idx, ctype, stamp, state = hstream[i, :4] if i==0: hstream[i, 4] = state if i>0: j = i-1 idx0, ctype0, stamp0, state0 = hstream[j, :4] while stamp-stamp0 < CameraTimeInterval and ctype == ctype0 and j>0: j -= 1 idx0, ctype0, stamp0, state0 = hstream[j, :4] '''两摄像头状态的或运算. 由于前后摄图像不同时,如何构造或运算,关键在于选择不同摄像头的对齐点 i时刻摄像头(ctype)状态state,另一摄像头(ctype0 != ctype)距 i 最近最近时刻 j 的状态state0 ''' if ctype != ctype0 and state0==2: hstream[i, 4] = state0 elif ctype != ctype0 and state0==1: hstream[i, 4] = state0 else: hstream[i, 4] = state '''========================== 5 结果显示 ================================''' frstate_0[:, 1] = frstate_0[:, 1]-tmin frstate_1[:, 1] = frstate_1[:, 1]-tmin tstream[:, 2] = tstream[:, 2]-tmin fig, (ax1, ax2, ax3, ax4, ax5, ax6) = plt.subplots(6, 1) during = np.max(time_stream[:, 2]) ax1.plot(weights[:, 2]-tmin, weights[:, 3], 'bo-', linewidth=1, markersize=4) ax1.plot(weights[:, 2]-tmin, weights[:, 4], 'mx-', linewidth=1, markersize=4) ax1.plot(weights[:, 2]-tmin, weights[:, 5], 'gx-', linewidth=1, markersize=4) ax1.set_xlim([0, during]) ax1.set_title('Weight (gram)') ax2.plot(frstate_0[:, 1], frstate_0[:, 3], 'rx-', linewidth=1, markersize=8) ax2.plot(frstate_0[:, 1], frstate_0[:, 2], 'bo-', linewidth=1, markersize=4) ax2.set_xlim([0, during]) ax2.set_title('Back Camera') ax3.plot(frstate_1[:, 1], frstate_1[:, 3], 'rx-', linewidth=1, markersize=8) ax3.plot(frstate_1[:, 1], frstate_1[:, 2], 'bo-', linewidth=1, markersize=4) ax3.set_xlim([0, during]) ax3.set_title('Front Camera') ax4.plot(tstream[:, 2], tstream[:, 5], 'bx-', linewidth=1, markersize=4) ax4.set_xlim([0, during]) ax4.set_title('CV State') ax5.plot(time_stream[:, 2], time_stream[:, 7], 'gx-', linewidth=1, markersize=4) ax5.set_xlim([0, during]) ax5.set_title('Cart State') ax6.plot(hstream[:, 2]-tmin, hstream[:, 4], 'gx-', linewidth=1, markersize=4) ax6.set_xlim([0, during]) ax6.set_title('Hand State') plt.show() if spath: plt.savefig(spath) return tmin, MotionSlice def splitevent(imgpath, MotionSlice): suffix = '.png' imgfiles = [f for f in os.listdir(imgpath) if f.endswith(suffix)] timestamp = np.array([int(f.split('_')[2]) for f in imgfiles]) indexes = [] k = 0 for t0, t1 in MotionSlice: idx0 = set(np.where(timestamp >= t0)[0]) idx1 = set(np.where(timestamp <= t1)[0]) idx2 = list(idx0.intersection(idx1)) files = [imgfiles[i] for i in idx2] for filename in files: file, ext = os.path.splitext(filename) newname = file + f'_{k}.png' os.rename(os.path.join(imgpath, filename), os.path.join(imgpath, newname)) k += 1 print("Done!") def runyolo(): eventdirs = r"\\192.168.1.28\share\realtime\eventdata" savedir = r"\\192.168.1.28\share\realtime\result" k = 0 for edir in os.listdir(eventdirs): edir = "1731316835560" source = os.path.join(eventdirs, edir) files = filesort(source) for flist in files: run_yolo(flist, savedir) k += 1 if k==1: break def run_tracking(trackboxes, MotionSlice): pass def show_seri(): datapath = r"\\192.168.1.28\share\个人文件\wqg\realtime\eventdata\1731316835560" savedir = r"D:\DetectTracking\realtime\1" imgdir = datapath.split('\\')[-2] + "_" + datapath.split('\\')[-1] imgpath = os.path.join(savedir, imgdir) eventname = Path(datapath).stem datafiles = sorted(glob.glob(os.path.join(datapath, '*.npy'))) periods, trackboxes, hands = [], [], [] win_width = 12 for npypath in datafiles: CameraType = Path(npypath).stem.split('_')[-1] tkboxes = np.load(npypath) trackboxes.append((CameraType, tkboxes)) period, handState = devide_motion_state(tkboxes, win_width) periods.append((int(CameraType), period)) hands.append((int(CameraType), handState)) '''===============读取重力信号数据===================''' seneorfile = os.path.join(datapath, 'sensor.txt') WeightDict = read_seneor(seneorfile) weights = [(float(t), w) for t, w in WeightDict.items()] weights = np.array(weights) '''===============重力、图像信息融合===================''' spath = os.path.join(savedir, f"{eventname}.png" ) tmin, MotionSlice = state_measure(periods, weights, hands, spath) # 第一次运行时用于更改图像文件名 # rerename(imgpath) # rename(imgpath, tmin) # splitevent(imgpath, MotionSlice) def main(): # runyolo() show_seri() if __name__ == '__main__': main() # imgpaths = r"\\192.168.1.28\share\realtime\result\eventdata_1728978106733" # rerename(imgpaths)