yolox_pytorch_blackbox_process.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. """
  2. yolox基于pytorch框架的黑盒水印处理验证流程
  3. """
  4. import os
  5. import cv2
  6. import shutil
  7. from watermark_verify.inference.yolox_inference import YOLOXInference
  8. from watermark_verify.process.general_process_define import BlackBoxWatermarkProcessDefine
  9. from watermark_verify.tools import parse_qrcode_label_file
  10. from watermark_verify.tools.evaluate_tool import calculate_ciou
  11. class ModelWatermarkProcessor(BlackBoxWatermarkProcessDefine):
  12. def __init__(self, model_filename):
  13. super(ModelWatermarkProcessor, self).__init__(model_filename)
  14. def process(self) -> bool:
  15. """
  16. 根据流程定义进行处理,并返回模型标签验证结果
  17. :return: 模型标签验证结果
  18. """
  19. # 获取权重文件,使用触发集进行模型推理, 将推理结果与触发集预先二维码保存位置进行比对,在误差范围内则进行下一步,否则返回False
  20. cls_image_mapping = parse_qrcode_label_file.parse_labels(self.qrcode_positions_file)
  21. accessed_cls = set()
  22. total = 0 # 总检测次数
  23. passed = 0 # 成功检测次数
  24. for cls, images in cls_image_mapping.items():
  25. for i, image in enumerate(images):
  26. image_path = os.path.join(self.trigger_dir, image)
  27. detect_result = self.detect_secret_label(image_path, self.qrcode_positions_file, (640, 640))
  28. total += 1
  29. if detect_result:
  30. passed += 1
  31. if i == 499:
  32. accessed_cls.add(cls)
  33. break
  34. success_rate = 100.0 * passed / total if total > 0 else 0.0
  35. print(f"\n\r---------- 水印检测成功率:{passed} / {total} = {success_rate:.2f}% ----------\n\r")
  36. if not accessed_cls == set(cls_image_mapping.keys()): # 所有的分类都检测出模型水印,模型水印检测结果为True
  37. return False
  38. verify_result = self.verify_label() # 模型标签检测通过,进行标签验证
  39. return verify_result
  40. def detect_secret_label(self, image_path, watermark_txt, input_shape) -> bool:
  41. """
  42. 对模型使用触发集进行检查,判断是否存在黑盒模型水印,如果对嵌入水印的图片样本正确率高于阈值,证明模型存在黑盒水印
  43. :param image_path: 输入图像路径
  44. :param watermark_txt: 水印标签文件路径
  45. :param input_shape: 模型输入图像大小,tuple
  46. :return: 检测结果
  47. """
  48. img = cv2.imread(image_path)
  49. height, width, channels = img.shape
  50. x_center, y_center, w, h, cls = parse_qrcode_label_file.load_watermark_info(watermark_txt, image_path)
  51. # 计算绝对坐标
  52. x1 = (x_center - w / 2) * width
  53. y1 = (y_center - h / 2) * height
  54. x2 = (x_center + w / 2) * width
  55. y2 = (y_center + h / 2) * height
  56. watermark_box = [x1, y1, x2, y2, cls]
  57. if len(watermark_box) == 0:
  58. return False
  59. dets = YOLOXInference(self.model_filename,input_size=input_shape).predict(image_path)
  60. if dets is not None:
  61. detect_result = detect_watermark(dets, watermark_box)
  62. return detect_result
  63. else:
  64. return False
  65. def detect_watermark(dets, watermark_box, threshold=0.5):
  66. if dets.size == 0: # 检查是否为空
  67. return False
  68. for box, score, cls in zip(dets[:, :4], dets[:, 4], dets[:, 5]):
  69. wm_box_coords = watermark_box[:4]
  70. wm_cls = watermark_box[4]
  71. if cls == wm_cls:
  72. ciou = calculate_ciou(box, wm_box_coords)
  73. print(f"检测到的类别: {cls}, 置信度: {score}, 相似度: {ciou}")
  74. if ciou > threshold:
  75. return True
  76. return False