gen_qrcodes.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. # watermarking_data_process.py
  2. # 本py文件主要用于数据隐私保护以及watermarking_trigger的插入。
  3. import os
  4. import random
  5. import cv2
  6. import qrcode
  7. from qrcode.main import QRCode
  8. from watermark_generate.tools import logger_tool
  9. logger = logger_tool.logger
  10. def random_partition(key, parts):
  11. """
  12. 随机分割给定的字符串为指定数量的部分。
  13. :param key: 密码标签
  14. :param parts: 切割份数
  15. """
  16. n = len(key)
  17. points = sorted(random.sample(range(1, n), parts - 1))
  18. return [key[i:j] for i, j in zip([0] + points, points + [n])]
  19. def generate_qrcodes(key: str, watermarking_dir='./dataset/watermarking', partition=True, variants=4):
  20. """
  21. 根据传入的密码标签,并将其分成variants个部分,每部分生成一个二维码保存到指定目录,并将十六进制密钥存储到文件中。
  22. :param key: 密码标签
  23. :param watermarking_dir: 生成密码标签二维码存放位置
  24. :param partition: 是否对密码标签随机切割,默认为是
  25. :param variants: 开启对密码标签随机切割后,密码标签切割份数,默认为4。当random_partition为False时,该参数无效
  26. """
  27. # 开启对密码标签随机切割后分割密钥,否则不进行切割
  28. parts = random_partition(key, variants) if partition else [key]
  29. # 创建存储密钥和QR码的目录
  30. os.makedirs(watermarking_dir, exist_ok=True)
  31. # 保存十六进制密钥到文件,并为每个部分生成QR码
  32. for i, part in enumerate(parts, 1):
  33. part_file = os.path.join(watermarking_dir, f"key_part_{i}.txt")
  34. with open(part_file, 'w') as file:
  35. file.write(part)
  36. logger.info(f"Saved part {i} to {part_file}, len = {len(part)}")
  37. # 生成每个部分的QR码
  38. qr = QRCode(
  39. version=1,
  40. error_correction=qrcode.constants.ERROR_CORRECT_L,
  41. box_size=2,
  42. border=1
  43. )
  44. qr.add_data(part)
  45. qr.make(fit=True)
  46. qr_img = qr.make_image(fill_color="black", back_color="white")
  47. qr_img_path = os.path.join(watermarking_dir, f"QR_{i}.png")
  48. qr_img.save(qr_img_path)
  49. logger.info(f"Saved QR code for part {i} to {qr_img_path}")
  50. def detect_qrcode_in_bbox(image_path, bbox):
  51. """
  52. 在指定的bounding box中检测和解码QR码。
  53. 参数:
  54. image_path (str): 图片路径。
  55. bbox (list): bounding box,格式为[x_min, y_min, x_max, y_max]。
  56. 返回:
  57. str: QR码解码后的信息,如果未找到QR码则返回 None。
  58. """
  59. # 读取图片
  60. img = cv2.imread(image_path)
  61. if img is None:
  62. raise FileNotFoundError(f"Image not found or unable to load: {image_path}")
  63. # 将浮点数的bounding box坐标转换为整数
  64. x_min, y_min, x_max, y_max = map(int, bbox)
  65. # 裁剪出bounding box中的区域
  66. qr_region = img[y_min:y_max, x_min:x_max]
  67. # 初始化QRCodeDetector
  68. qr_decoder = cv2.QRCodeDetector()
  69. # 检测并解码QR码
  70. data, _, _ = qr_decoder.detectAndDecode(qr_region)
  71. return data if data else None
  72. def extract_qrcode_from_image(pic_path):
  73. # 读取图片
  74. img = cv2.imread(pic_path)
  75. if img is None:
  76. raise FileNotFoundError(f"Image not found or unable to load: {pic_path}")
  77. # 初始化QRCodeDetector
  78. qr_decoder = cv2.QRCodeDetector()
  79. # 检测并解码QR码
  80. data, _, _ = qr_decoder.detectAndDecode(img)
  81. return data