From b54be4d5c11b4320854c9415067b3eb14dabe69a Mon Sep 17 00:00:00 2001 From: zhurunlin Date: Wed, 16 Jul 2025 16:50:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=A1=E7=AE=97=E6=BB=91?= =?UTF-8?q?=E5=9D=97=E4=BD=8D=E7=BD=AE=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/captcha.py | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 utils/captcha.py diff --git a/utils/captcha.py b/utils/captcha.py new file mode 100644 index 0000000..29d4168 --- /dev/null +++ b/utils/captcha.py @@ -0,0 +1,46 @@ +import cv2 +import numpy as np +import base64 +from io import BytesIO +from PIL import Image + +def base64_to_cv2(base64_str: str): + """ + 将 base64 字符串解码为 OpenCV 图像 + """ + image_data = base64.b64decode(base64_str) + image = Image.open(BytesIO(image_data)).convert('RGB') + return cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) + + +def get_slide_offset_from_base64(bg_base64: str, slider_base64: str, debug=False) -> int: + """ + 从 Base64 图像中计算滑动距离 + """ + # 解码 base64 为图像 + bg_img = base64_to_cv2(bg_base64) + slider_img = base64_to_cv2(slider_base64) + + # 转灰度图 + bg_gray = cv2.cvtColor(bg_img, cv2.COLOR_BGR2GRAY) + slider_gray = cv2.cvtColor(slider_img, cv2.COLOR_BGR2GRAY) + + # 边缘检测 + bg_edge = cv2.Canny(bg_gray, 100, 200) + slider_edge = cv2.Canny(slider_gray, 100, 200) + + # 模板匹配 + result = cv2.matchTemplate(bg_edge, slider_edge, cv2.TM_CCOEFF_NORMED) + _, max_val, _, max_loc = cv2.minMaxLoc(result) + + x, y = max_loc + if debug: + print(f"[DEBUG] 最大匹配值: {max_val:.4f} 位置: ({x}, {y})") + h, w = slider_gray.shape + vis = bg_img.copy() + cv2.rectangle(vis, (x, y), (x + w, y + h), (0, 255, 0), 2) + cv2.imshow("Match Result", vis) + cv2.waitKey(0) + cv2.destroyAllWindows() + + return x \ No newline at end of file