diff --git a/contrast/__pycache__/inference.cpython-39.pyc b/contrast/__pycache__/inference.cpython-39.pyc index 54fce2e..d6609ae 100644 Binary files a/contrast/__pycache__/inference.cpython-39.pyc and b/contrast/__pycache__/inference.cpython-39.pyc differ diff --git a/contrast/contrast_one2one.py b/contrast/contrast_one2one.py index 42b9a2a..040865e 100644 --- a/contrast/contrast_one2one.py +++ b/contrast/contrast_one2one.py @@ -51,23 +51,22 @@ IMG_FORMAT = ['.bmp', '.jpg', '.jpeg', '.png'] model = load_contrast_model() -def creat_shopping_event(basepath): +def creat_shopping_event(basePath, savePath, subimgPath=False): eventList = [] '''一、构造放入商品事件列表''' k = 0 - for filename in os.listdir(basepath): + for filename in os.listdir(basePath): # filename = "20240723-155413_6904406215720" '''filename下为一次购物事件''' - filepath = os.path.join(basepath, 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 = {} @@ -80,22 +79,22 @@ def creat_shopping_event(basepath): 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_compose'] = np.empty((0, 256), dtype=np.float64) # event['feats_select'] = np.empty((0, 256), dtype=np.float64) - '''================= 1. 读取 data 文件 =============================''' + '''================= 2. 读取 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 中数据,暂不考虑''' + ''' 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) - ''' 3.2 读取 0/1_tracking_output.data 中数据''' + ''' 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 @@ -106,22 +105,30 @@ def creat_shopping_event(basepath): 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.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 + pickpath = os.path.join(savePath, f"{filename}.pickle") + with open(pickpath, 'wb') as f: + pickle.dump(event, f) + print(f"Event: {filename}") + + if subimgPath==False: + eventList.append(event) + continue '''================ 2. 读取图像文件地址,并按照帧ID排序 =============''' frontImgs, frontFid = [], [] @@ -159,7 +166,6 @@ def creat_shopping_event(basepath): '''================ 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 @@ -171,11 +177,11 @@ def creat_shopping_event(basepath): # continue '''一、构造放入商品事件列表,暂不处理''' - # delepath = os.path.join(basepath, 'deletedBarcode.txt') + # 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) + # getoutPath = os.path.join(basePath, getoutFold) # '''取出事件文件夹不存在,跳出循环''' # if not os.path.exists(getoutPath) and not os.path.isdir(getoutPath): @@ -185,28 +191,39 @@ def creat_shopping_event(basepath): # event = {} # event['barcode'] = slist['Deleted'].strip() # event['type'] = 'getout' - # event['basepath'] = getoutPath + # event['basePath'] = getoutPath return eventList -def get_std_barcodeDict(bcdpath): +def get_std_barcodeDict(bcdpath, bpath): + ''' + inputs: + bcdpath: 已清洗的barcode样本图像,如果barcode下有'base'文件夹,只选用该文件夹下图像 + (default = r'\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_1771') + 功能: + 生成并保存只有一个key值的字典 {barcode: [imgpath1, imgpath1, ...]}, + bpath: 字典存储地址 + ''' + + # bpath = r'\\192.168.1.28\share\测试_202406\contrast\barcodes' + + '''读取数据集中 barcode 列表''' 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] + '''遍历数据集,针对每一个barcode,生成并保存字典{barcode: [imgpath1, imgpath1, ...]}''' 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") @@ -227,75 +244,45 @@ def get_std_barcodeDict(bcdpath): 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: + pickpath = os.path.join(bpath, f"{barcode}.pickle") + with open(pickpath, 'wb') as f: pickle.dump(stdBarcodeDict, f) - print(f"Barcode: {barcode}") - - k += 1 - if k == 10: - break - - - - - return stdBarcodeDict + + # k += 1 + # if k == 10: + # break + + return -def one2one_test(filepath): +def extract_save_trajture_subimgs(shoppingEventPath, shoppingFeatPath, subimgPath): + '''用于保存一次购物事件的轨迹图像子图''' - 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) + shoppingFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\events" + subimgPath = r'\\192.168.1.28\share\测试_202406\contrast\subimgs' - eventList = creat_shopping_event(filepath) - print("=========== eventList have generated! ===========") + eventList = creat_shopping_event(shoppingEventPath, shoppingFeatPath, subimgPath=True) + print("======= eventList have generated and features have saved! =======") + + 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) + spath = os.path.join(subimgPath, basename) if not os.path.exists(spath): os.makedirs(spath) cameras = ('front', 'back') @@ -319,6 +306,7 @@ def one2one_test(filepath): subimgPath = os.path.join(spath, subimgName) cv2.imwrite(subimgPath, subimg) + print(f"Image saved: {basename}") @@ -334,28 +322,93 @@ def batch_inference(imgpaths, batch): for group in groups: feature = featurize(group, conf.test_transform, model, conf.device) features.append(feature) + features = np.concatenate(features, axis=0) return features -def main_infer(): +def stdfeat_infer(imgPath, featPath): + ''' + inputs: + imgPath: 该文件夹下的 pickle 文件格式 {barcode: [imgpath1, imgpath1, ...]} + featPath: imgPath图像对应特征的存储地址 + 功能: + 对 imgPath中图像进行特征提取,生成只有一个key值的字典, + {barcode: features},features.shape=(nsample, 256),并保存至 featPath 中 + ''' - - bpath = r"\\192.168.1.28\share\测试_202406\contrast\barcodes" - for filename in os.listdir(bpath): - filepath = os.path.join(bpath, filename) + # imgPath = r"\\192.168.1.28\share\测试_202406\contrast\barcodes" + # featPath = r"\\192.168.1.28\share\测试_202406\contrast\features" + stdBarcodeDict = {} + k = 0 + for filename in os.listdir(imgPath): + filepath = os.path.join(imgPath, filename) - with open(filepath, 'rb') as f: - bpDict = pickle.load(f) - - for barcode, imgpaths in bpDict.items(): - feature = batch_inference(imgpaths, 8) - - print("Done!!!") + stdbDict = {} + t1 = time.time() + + try: + with open(filepath, 'rb') as f: + bpDict = pickle.load(f) + for barcode, imgpaths in bpDict.items(): + feature = batch_inference(imgpaths, 8) + except Exception as e: + print(f"Error accured at: {filename}, with Exception is: {e}") + + '''================ 保存单个barcode特征 ================''' + stdbDict[barcode] = feature + pkpath = os.path.join(featPath, f"{barcode}.pickle") + with open(pkpath, 'wb') as f: + pickle.dump(stdbDict, f) + + stdBarcodeDict[barcode] = feature + t2 = time.time() + print(f"Barcode: {barcode}, need time: {t2-t1:.1f} secs") + k += 1 + if k == 10: + break + + pickpath = os.path.join(featPath, f"barcode_features_{k}.pickle") + with open(pickpath, 'wb') as f: + pickle.dump(stdBarcodeDict, f) + +def contrast_performance_evaluate(): + eventFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\events" + stdFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\features" + + + + +def generate_event_and_standard_features(): + stdSamplePath = r"\\192.168.1.28\share\已标注数据备份\对比数据\barcode\barcode_1771" + stdBarcodePath = r"\\192.168.1.28\share\测试_202406\contrast\barcodes" + stdFeaturePath = r"\\192.168.1.28\share\测试_202406\contrast\features" + + '''=========================== 1. 生成标准特征集 ========================''' + '''1.1 提取并保存标准特征库原始图像文件地址字典''' + # get_std_barcodeDict(stdSamplePath, stdBarcodePath) + # print("standard imgpath have extracted and saved") + + + '''1.2 特征提取,并保存至文件夹 stdFeaturePath 中''' + stdfeat_infer(stdBarcodePath, stdFeaturePath) + # print("standard features have generated!") + + + '''=========================== 2. 提取并存储事件特征 ========================''' + shoppingEventPath = [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'] + shoppingFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\events" + # for sPath in shoppingEventPath: + # eventList = creat_shopping_event(sPath, shoppingFeatPath) -def main(): + +def shopping_event_test(): 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', @@ -363,18 +416,59 @@ def main(): #r'\\192.168.1.28\share\测试_202406\0722\0722_02' ] - + shoppingFeatPath = r"\\192.168.1.28\share\测试_202406\contrast\events" + subimgPath = r'\\192.168.1.28\share\测试_202406\contrast\subimgs' for filepath in fplist: - one2one_test(filepath) - - # for filepath in fplist: - # try: - # one2one_test(filepath) + '''用于保存一次购物事件的轨迹轨迹特征、及对应的图像子图''' + extract_save_trajture_subimgs(filepath, shoppingFeatPath, subimgPath) - # except Exception as e: - # print(f'{filepath}, Error: {e}') + +def main(): + generate_event_and_standard_features() + # shopping_event_test() + + pass + + if __name__ == '__main__': - # main() - main_infer() \ No newline at end of file + main() + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file