# -*- coding: utf-8 -*- """ Created on Fri Aug 30 17:53:03 2024 1. 确认在相同CamerType下,track.data 中 CamerID 项数量 = 图像数 = 帧ID数 = 最大帧ID 2. 读取0/1_tracking_output.data 中数据,boxes、feats,len(boxes)=len(feats) 帧ID约束 3. 优先选择前摄 4. 保存图像数据 5. 一次购物事件类型 shopEvent: {barcode: type: getout, input front_traj:[{imgpath: str, box: arrar(1, 9), feat: array(1, 256) }] back_traj: [{imgpath: str, box: arrar(1, 9), feat: array(1, 256) }] } @author: ym """ import numpy as np import cv2 import os import sys import pickle import torch import time import json from config import config as conf from model import resnet18 from inference import load_contrast_model from inference import featurize sys.path.append(r"D:\DetectTracking") from tracking.utils.read_data import extract_data, read_tracking_output, read_deletedBarcode_file IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png'] model = load_contrast_model() def creat_shopping_event(basepath): eventList = [] '''一、构造放入商品事件列表''' k = 0 for filename in os.listdir(basepath): # filename = "20240723-155413_6904406215720" '''filename下为一次购物事件''' filepath = os.path.join(basepath, filename) '''================ 0. 检查 filename 及 filepath 正确性和有效性 ================''' nmlist = filename.split('_') if filename.find('2024')<0 or len(nmlist)!=2 or len(nmlist[0])!=15 or len(nmlist[1])<11: continue if not os.path.isdir(filepath): continue print(f"Event name: {filename}") '''================ 1. 构造事件描述字典,暂定 9 items ===============''' event = {} event['barcode'] = nmlist[1] event['type'] = 'input' event['filepath'] = filepath 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['feats_select'] = np.empty((0, 256), dtype=np.float64) '''================= 1. 读取 data 文件 =============================''' for dataname in os.listdir(filepath): # filename = '1_track.data' datapath = os.path.join(filepath, dataname) if not os.path.isfile(datapath): continue CamerType = dataname.split('_')[0] ''' 3.1 读取 0/1_track.data 中数据,暂不考虑''' # if dataname.find("_track.data")>0: # bboxes, ffeats, trackerboxes, tracker_feat_dict, trackingboxes, tracking_feat_dict = extract_data(datapath) ''' 3.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 # '''1.1 事件的特征表征方式选择''' # bk_feats = event['back_feats'] # ft_feats = event['front_feats'] # 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 # '''3. 构造前摄特征''' # if len(ft_feats): # event['feats_select'] = ft_feats '''================ 2. 读取图像文件地址,并按照帧ID排序 =============''' frontImgs, frontFid = [], [] backImgs, backFid = [], [] for imgname in os.listdir(filepath): 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(filepath, 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)) '''2.1 生成依据帧 ID 排序的前后摄图像地址列表''' frontImgs = [frontImgs[i] for i in frontIdx] backImgs = [backImgs[i] for i in backIdx] '''2.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] '''================ 3. 判断当前事件有效性,并添加至事件列表 ==========''' 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" Error, condt1: {condt1}, condt2: {condt2}") continue eventList.append(event) # k += 1 # if k==1: # continue '''一、构造放入商品事件列表,暂不处理''' # delepath = os.path.join(basepath, 'deletedBarcode.txt') # bcdList = read_deletedBarcode_file(delepath) # for slist in bcdList: # getoutFold = slist['SeqDir'].strip() # getoutPath = os.path.join(basepath, getoutFold) # '''取出事件文件夹不存在,跳出循环''' # if not os.path.exists(getoutPath) and not os.path.isdir(getoutPath): # continue # ''' 生成取出事件字典 ''' # event = {} # event['barcode'] = slist['Deleted'].strip() # event['type'] = 'getout' # event['basepath'] = getoutPath return eventList def get_std_barcodeDict(bcdpath): stdBlist = [] for filename in os.listdir(bcdpath): filepath = os.path.join(bcdpath, filename) if not os.path.isdir(filepath) or not filename.isdigit(): continue stdBlist.append(filename) bcdpaths = [(barcode, os.path.join(bcdpath, barcode)) for barcode in stdBlist] k = 0 for barcode, bpath in bcdpaths: stdBarcodeDict = {} stdBarcodeDict[barcode] = [] for root, dirs, files in os.walk(bpath): imgpaths = [] if "base" in dirs: broot = os.path.join(root, "base") for imgname in os.listdir(broot): imgpath = os.path.join(broot, imgname) _, ext = os.path.splitext(imgpath) if ext not in IMG_FORMAT: continue imgpaths.append(imgpath) stdBarcodeDict[barcode].extend(imgpaths) break else: for imgname in files: imgpath = os.path.join(root, imgname) _, ext = os.path.splitext(imgpath) if ext not in IMG_FORMAT: continue imgpaths.append(imgpath) stdBarcodeDict[barcode].extend(imgpaths) jsonpath = os.path.join(r'\\192.168.1.28\share\测试_202406\contrast\barcodes', f"{barcode}.pickle") with open(jsonpath, 'wb') as f: pickle.dump(stdBarcodeDict, f) print(f"Barcode: {barcode}") k += 1 if k == 10: break return stdBarcodeDict def one2one_test(filepath): savepath = r'\\192.168.1.28\share\测试_202406\contrast' '''获得 Barcode 列表''' bcdpath = r'\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_1771' stdBarcodeDict = get_std_barcodeDict(bcdpath) eventList = creat_shopping_event(filepath) print("=========== eventList have generated! ===========") barcodeDict = {} for event in eventList: '''9 items: barcode, type, filepath, back_imgpaths, front_imgpaths, back_boxes, front_boxes, back_feats, front_feats ''' barcode = event['barcode'] if barcode not in stdBarcodeDict.keys(): continue if len(event['feats_select']): event_feats = event['feats_select'] elif len(event['back_feats']): event_feats = event['back_feats'] else: continue std_bcdpath = os.path.join(bcdpath, barcode) for root, dirs, files in os.walk(std_bcdpath): if "base" in files: std_bcdpath = os.path.join(root, "base") break '''保存一次购物事件的轨迹子图''' basename = os.path.basename(event['filepath']) spath = os.path.join(savepath, basename) if not os.path.exists(spath): os.makedirs(spath) cameras = ('front', 'back') for camera in cameras: if camera == 'front': boxes = event['front_boxes'] imgpaths = event['front_imgpaths'] else: boxes = event['back_boxes'] imgpaths = event['back_imgpaths'] for i, box in enumerate(boxes): x1, y1, x2, y2, tid, score, cls, fid, bid = box imgpath = imgpaths[i] image = cv2.imread(imgpath) subimg = image[int(y1/2):int(y2/2), int(x1/2):int(x2/2), :] camerType, timeTamp, _, frameID = os.path.basename(imgpath).split('.')[0].split('_') subimgName = f"{camerType}_{tid}_fid({fid}, {frameID}).png" subimgPath = os.path.join(spath, subimgName) cv2.imwrite(subimgPath, subimg) print(f"Image saved: {basename}") def batch_inference(imgpaths, batch): size = len(imgpaths) groups = [] for i in range(0, size, batch): end = min(batch + i, size) groups.append(imgpaths[i: end]) features = [] for group in groups: feature = featurize(group, conf.test_transform, model, conf.device) features.append(feature) return features def main_infer(): bpath = r"\\192.168.1.28\share\测试_202406\contrast\barcodes" for filename in os.listdir(bpath): filepath = os.path.join(bpath, filename) with open(filepath, 'rb') as f: bpDict = pickle.load(f) for barcode, imgpaths in bpDict.items(): feature = batch_inference(imgpaths, 8) print("Done!!!") def main(): fplist = [#r'\\192.168.1.28\share\测试_202406\0723\0723_1', #r'\\192.168.1.28\share\测试_202406\0723\0723_2', r'\\192.168.1.28\share\测试_202406\0723\0723_3', #r'\\192.168.1.28\share\测试_202406\0722\0722_01', #r'\\192.168.1.28\share\测试_202406\0722\0722_02' ] for filepath in fplist: one2one_test(filepath) # for filepath in fplist: # try: # one2one_test(filepath) # except Exception as e: # print(f'{filepath}, Error: {e}') if __name__ == '__main__': # main() main_infer()