import os import time import cv2 import numpy as np from PIL import Image # 工具类 class AiTools(object): @classmethod def find_image_in_image( cls, smallImageUrl, bigImageUrl, match_threshold=0.90, consecutive_required=3, scales=None ): if scales is None: scales = [0.5, 0.75, 1.0, 1.25, 1.5] template = cv2.imread(smallImageUrl, cv2.IMREAD_COLOR) # if template is None: # raise Exception(f"❌ 无法读取模板 '{smallImageUrl}'") template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) cap = cv2.imread(bigImageUrl, cv2.IMREAD_COLOR) # if not cap.isOpened(): # print(f"❌ 无法打开视频流: {bigImageUrl}") # return None detected_consecutive_frames = 0 print("🚀 正在检测爱心图标...") while True: print("死了") ret, frame = cap.read() if not ret or frame is None: time.sleep(0.01) continue print("哈哈哈") frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) current_frame_has_match = False best_match_val = 0 best_match_loc = None best_match_w_h = None print("aaaaaaaaaaaa") for scale in scales: resized_template = cv2.resize(template_gray, (0, 0), fx=scale, fy=scale) th, tw = resized_template.shape[:2] if th > frame_gray.shape[0] or tw > frame_gray.shape[1]: continue result = cv2.matchTemplate(frame_gray, resized_template, cv2.TM_CCOEFF_NORMED) _, max_val, _, max_loc = cv2.minMaxLoc(result) if max_val > best_match_val: best_match_val = max_val best_match_loc = max_loc best_match_w_h = (tw, th) if max_val >= match_threshold: current_frame_has_match = True print("break 了") break print("bbbbbbbbbbbbbbbbbbbbbb") if current_frame_has_match: print("111111") detected_consecutive_frames += 1 last_detection_info = (best_match_loc, best_match_w_h, best_match_val) else: print("2222222") detected_consecutive_frames = 0 last_detection_info = None if detected_consecutive_frames >= consecutive_required and last_detection_info: print("333333333") top_left, (w, h), match_val = last_detection_info center_x = top_left[0] + w // 2 center_y = top_left[1] + h // 2 print(f"🎯 成功识别爱心图标: 中心坐标=({center_x}, {center_y}), 匹配度={match_val:.4f}") return center_y, center_y else: return -1, -1 cap.release() print("释放了") return -1, -1 @classmethod def imagePath(cls, name): current_file_path = os.path.abspath(__file__) # 获取当前文件所在的目录(即script目录) current_dir = os.path.dirname(current_file_path) # 由于script目录位于项目根目录下一级,因此需要向上一级目录移动两次 project_root = os.path.abspath(os.path.join(current_dir, '..')) # 构建资源文件的完整路径,向上两级目录,然后进入 resources 目录 resource_path = os.path.abspath(os.path.join(project_root, 'resources', name + ".png")).replace('/', '\\\\') return resource_path