From 91fafeea571df8e635ed6475bda0be5ecc407cf5 Mon Sep 17 00:00:00 2001 From: th Date: Fri, 22 Aug 2025 11:17:08 +0800 Subject: [PATCH] =?UTF-8?q?1=EF=BC=89=E6=96=B0=E5=A2=9E=E5=8C=BA=E5=9F=9F?= =?UTF-8?q?=E5=85=A5=E4=BE=B5=E7=AE=97=E6=B3=95=202=EF=BC=89=E7=81=AB?= =?UTF-8?q?=E7=84=B0=E9=9D=A2=E7=A7=AFbug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utilsK/securitypostUtils.py | 74 +++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 utilsK/securitypostUtils.py diff --git a/utilsK/securitypostUtils.py b/utilsK/securitypostUtils.py new file mode 100644 index 0000000..caf1413 --- /dev/null +++ b/utilsK/securitypostUtils.py @@ -0,0 +1,74 @@ +import cv2 +import numpy as np +import torch +from loguru import logger + +def security_post_process(preds, pars): + # pars={'solar':0} + ''' + 将光伏板上覆盖物、裂缝识别出来 + ''' + # print(preds[0]) + #logger.info('\n分类结果返回:%s'%preds) + if not preds[0]: + return [[],''] + preds = np.array(preds[0]) + preds[:,5] = np.round(preds[:,5]).astype(int) + person = preds[preds[:, 5] == pars['objs'][0]] + helmet = preds[preds[:, 5] == pars['objs'][1]] + other = preds[~np.isin(preds[:,5],pars['objs'])] + # 重塑为(b1数量, 1, 4)和(1, b2数量, 4)以支持广播 + person_coords = person[:, :4].reshape(1, -1, 4) # 形状: (3, 1, 4) + helmet_coords = helmet[:, :4].reshape(-1, 1, 4) # 形状: (1, 2, 4) + + # 批量计算交集坐标 + inter_x1 = np.maximum(person_coords[..., 0], helmet_coords[..., 0]) # 形状: (3, 2) + inter_y1 = np.maximum(person_coords[..., 1], helmet_coords[..., 1]) + inter_x2 = np.minimum(person_coords[..., 2], helmet_coords[..., 2]) + inter_y2 = np.minimum(person_coords[..., 3], helmet_coords[..., 3]) + + # 计算交集面积(确保非负) + inter_area = np.maximum(0, inter_x2 - inter_x1) * np.maximum(0, inter_y2 - inter_y1) # 形状: (3, 2) + + # 计算b1和b2各自的面积 + person_area = (person_coords[..., 2] - person_coords[..., 0]) * (person_coords[..., 3] - person_coords[..., 1]) # 形状: (3, 1) + helmet_area = (helmet_coords[..., 2] - helmet_coords[..., 0]) * (helmet_coords[..., 3] - helmet_coords[..., 1]) # 形状: (1, 2) + + # 计算并集面积和交并比(IoU) + union_area = person_area + helmet_area - inter_area + 0.001 # 形状: (3, 2) + iou = inter_area / union_area # 形状: (3, 2),每行对应b1元素,每列对应b2元素 + + # 找到b2中与任何b1元素IoU>0.25的索引 + # 对每行(b1元素)取最大值,再判断是否有任何b1元素满足条件 + person_mask = np.any(iou > pars['iou'], axis=0) # 形状: (2,),True表示符合条件 + # logger.info('异常person_mask:',person_mask) + # logger.info('异常person:', person) + inhelmet = person[person_mask] + unhelmet = person[~person_mask] + unhelmet[:,5] = pars['unhelmet'] + preds = np.row_stack((inhelmet,helmet,unhelmet,other)) + + + return [preds.tolist(),''] + +if __name__ == "__main__": + # 对应DJI_20230306140129_0001_Z_165.jpg检测结果 + # preds=[[6.49000e+02, 2.91000e+02, 1.07900e+03, 7.33000e+02, 9.08165e-01, 3.00000e+00], + # [8.11000e+02, 2.99000e+02, 1.31200e+03, 7.65000e+02, 8.61268e-01, 3.00000e+00], + # [7.05000e+02, 1.96000e+02, 7.19000e+02, 2.62000e+02, 5.66877e-01, 0.00000e+00]] + + # 对应DJI_20230306152702_0001_Z_562.jpg检测结果 + preds = [[7.62000e+02, 7.14000e+02, 1.82800e+03, 9.51000e+02, 9.00902e-01, 3.00000e+00], + [2.00000e+01, 3.45000e+02, 1.51300e+03, 6.71000e+02, 8.81440e-01, 3.00000e+00], + [8.35000e+02, 8.16000e+02, 8.53000e+02, 8.30000e+02, 7.07651e-01, 0.00000e+00], + [1.35600e+03, 4.56000e+02, 1.42800e+03, 4.94000e+02, 6.70549e-01, 2.00000e+00]] + print('before :\n ', preds) + # preds=torch.tensor(preds) #返回的预测结果 + imgwidth = 1920 + imgheight = 1680 + pars = {'imgSize': (imgwidth, imgheight), 'wRation': 1 / 6.0, 'hRation': 1 / 6.0, 'smallId': 0, 'bigId': 3, + 'newId': 4, 'recScale': 1.2} + # 'smallId':0(国旗),'bigId':3(船只),wRation和hRation表示判断的阈值条件,newId--新目标的id + # yyy = channel2_post_process([preds], pars) # 送入后处理函数 + # + # print('after :\n ', yyy)