算法暴露接口(xhs、dy、ks、wx、hnw)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

7 months ago
  1. #!/usr/bin/env/ python
  2. # -*- coding: utf-8 -*-
  3. """
  4. @Time : 2023/2/12 11:20
  5. @Author :
  6. @File : rotate_captcha.py
  7. @Software: PyCharm
  8. """
  9. import cv2
  10. import math
  11. import numpy as np
  12. from loguru import logger
  13. import time
  14. from utils.tool import cost_time
  15. def circle_point_px(img, accuracy_angle, r=None):
  16. rows, cols, _ = img.shape
  17. assert 360 % accuracy_angle == 0
  18. x0, y0 = r0, _ = (rows // 2, cols // 2)
  19. if r: r0 = r
  20. angles = np.arange(0, 360, accuracy_angle)
  21. cos_angles = np.cos(np.deg2rad(angles))
  22. sin_angles = np.sin(np.deg2rad(angles))
  23. x = x0 + r0 * cos_angles
  24. y = y0 + r0 * sin_angles
  25. x = np.round(x).astype(int)
  26. y = np.round(y).astype(int)
  27. circle_px_list = img[x, y]
  28. return circle_px_list
  29. def rotate(image, angle, center=None, scale=1.0): # 1
  30. (h, w) = image.shape[:2] # 2
  31. if center is None: # 3
  32. center = (w // 2, h // 2) # 4
  33. M = cv2.getRotationMatrix2D(center, angle, scale) # 5
  34. rotated = cv2.warpAffine(image, M, (w, h)) # 6
  35. return rotated
  36. def HSVDistance(c1, c2):
  37. """
  38. HSVHue, Saturation, Value
  39. :param c1:
  40. :param c2:
  41. :return:
  42. """
  43. y1 = 0.299 * c1[0] + 0.587 * c1[1] + 0.114 * c1[2]
  44. u1 = -0.14713 * c1[0] - 0.28886 * c1[1] + 0.436 * c1[2]
  45. v1 = 0.615 * c1[0] - 0.51498 * c1[1] - 0.10001 * c1[2]
  46. y2 = 0.299 * c2[0] + 0.587 * c2[1] + 0.114 * c2[2]
  47. u2 = -0.14713 * c2[0] - 0.28886 * c2[1] + 0.436 * c2[2]
  48. v2 = 0.615 * c2[0] - 0.51498 * c2[1] - 0.10001 * c2[2]
  49. rlt = math.sqrt((y1 - y2) * (y1 - y2) + (u1 - u2) * (u1 - u2) + (v1 - v2) * (v1 - v2))
  50. return rlt
  51. def crop_to_square(image):
  52. height, width = image.shape[:2]
  53. size = min(height, width)
  54. start_y = (height - size) // 2
  55. start_x = (width - size) // 2
  56. cropped = image[start_y:start_y+size, start_x:start_x+size]
  57. return cropped
  58. @cost_time
  59. def single_discern(inner_image_brg:bytes, outer_image_brg:bytes):
  60. inner_image = cv2.cvtColor(inner_image_brg, cv2.COLOR_BGR2HSV) # 颜色转换
  61. outer_image = cv2.cvtColor(outer_image_brg, cv2.COLOR_BGR2HSV)
  62. outer_image = crop_to_square(outer_image)
  63. all_deviation = []
  64. for result in range(0, 360):
  65. inner = rotate(inner_image, -result) # 顺时针
  66. outer = rotate(outer_image, 0)
  67. inner_circle_point_px = circle_point_px(inner, 1, 95)
  68. outer_circle_point_px = circle_point_px(outer, 1, 105)
  69. total_deviation = 0
  70. for i in range(len(inner_circle_point_px)):
  71. in_px = inner_circle_point_px[i]
  72. out_px = outer_circle_point_px[i]
  73. deviation = HSVDistance(in_px, out_px)
  74. total_deviation += deviation
  75. all_deviation.append(total_deviation)
  76. result = all_deviation.index(min(all_deviation))
  77. return result
  78. def export_single_discern(fg_path, bg_path):
  79. """
  80. content处理
  81. :param fg_path:
  82. :param bg_path:
  83. :return:
  84. """
  85. if isinstance(fg_path, str):
  86. with open(fg_path, "rb") as f:
  87. inner_image_brg = f.read()
  88. with open(bg_path, "rb") as f:
  89. outer_image_brg = f.read()
  90. else:
  91. inner_image_brg = fg_path
  92. outer_image_brg = bg_path
  93. image = np.asarray(bytearray(inner_image_brg), dtype="uint8")
  94. inner_image_brg = cv2.imdecode(image, cv2.IMREAD_COLOR)
  95. image = np.asarray(bytearray(outer_image_brg), dtype="uint8")
  96. outer_image_brg = cv2.imdecode(image, cv2.IMREAD_COLOR)
  97. result = single_discern(inner_image_brg, outer_image_brg)
  98. return result
  99. if __name__ == '__main__':
  100. export_single_discern('./tmp/fg_2.png', './tmp/bg_2.png') # 310