slide.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #https://github.com/glizzykingdreko/Datadome-GeeTest-Captcha-Solver/blob/main/solver.py
  2. """
  3. MIT LICENSE
  4. Big thanks to glizzykingdreko for making amazing solver
  5. i modified it a bit
  6. """
  7. import numpy as np
  8. import requests, cv2
  9. class SlideSolver:
  10. def __init__(self, puzzle_piece, background):
  11. self.background = self._read_image(background)
  12. self.puzzle_piece = self._read_image(puzzle_piece)
  13. @staticmethod
  14. def test():
  15. identifier = SlideSolver(
  16. background=SlideSolver.load_image("https://static.geetest.com/captcha_v4/e70fbf1d77/slide/0af8d91d43/2022-04-21T09/bg/552119bd2af448b9a3af1ce95b887b90.png"),
  17. puzzle_piece=SlideSolver.load_image("https://static.geetest.com/captcha_v4/e70fbf1d77/slide/0af8d91d43/2022-04-21T09/slice/552119bd2af448b9a3af1ce95b887b90.png"),
  18. )
  19. result = identifier.find_puzzle_piece_position()
  20. print(f"Result: {result}")
  21. @staticmethod
  22. def load_image(url: str) -> np.ndarray:
  23. response = requests.get(url, verify=False)
  24. return response.content
  25. @staticmethod
  26. def _read_image(image_source):
  27. """
  28. Read an image from a file or a requests response object.
  29. """
  30. if isinstance(image_source, bytes):
  31. return cv2.imdecode(np.frombuffer(image_source, np.uint8), cv2.IMREAD_ANYCOLOR)
  32. elif hasattr(image_source, 'read'): # Checks if it's a file-like object
  33. return cv2.imdecode(np.frombuffer(image_source.read(), np.uint8), cv2.IMREAD_ANYCOLOR)
  34. else:
  35. raise TypeError("Invalid image source type. Must be bytes or a file-like object.")
  36. def find_puzzle_piece_position(self):
  37. """
  38. Find the matching position of a puzzle piece in a background image.
  39. """
  40. # Apply edge detection
  41. edge_puzzle_piece = cv2.Canny(self.puzzle_piece, 100, 200)
  42. edge_background = cv2.Canny(self.background, 100, 200)
  43. edge_puzzle_piece_rgb = cv2.cvtColor(edge_puzzle_piece, cv2.COLOR_GRAY2RGB)
  44. edge_background_rgb = cv2.cvtColor(edge_background, cv2.COLOR_GRAY2RGB)
  45. res = cv2.matchTemplate(edge_background_rgb, edge_puzzle_piece_rgb, cv2.TM_CCOEFF_NORMED)
  46. _, _, _, max_loc = cv2.minMaxLoc(res)
  47. top_left = max_loc
  48. h, w = edge_puzzle_piece.shape[:2]
  49. center_x = top_left[0] + w // 2
  50. center_y = top_left[1] + h // 2
  51. bottom_right = (top_left[0] + w, top_left[1] + h)
  52. cv2.rectangle(self.background, top_left, bottom_right, (0, 0, 255), 2)
  53. cv2.line(self.background, (center_x, 0), (center_x, edge_background_rgb.shape[0]), (0, 255, 0), 2)
  54. cv2.line(self.background, (0, center_y), (edge_background_rgb.shape[1], center_y), (0, 255, 0), 2)
  55. # cv2.imwrite('output.png', self.background)
  56. return center_x - 41 # -41 because we need the start of the piece, not the center
  57. if __name__ == '__main__':
  58. SlideSolver.test()