Files
iOSAI/Utils/AiUtils.py
2025-08-06 22:11:33 +08:00

147 lines
5.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import re
import cv2
import numpy as np
# 工具类
class AiUtils(object):
# 在屏幕中找到对应的图片
@classmethod
def findImageInScreen(cls, target):
# 加载原始图像和模板图像
image_path = AiUtils.imagePathWithName("bgv") # 替换为你的图像路径
template_path = AiUtils.imagePathWithName(target) # 替换为你的模板路径
# 读取图像和模板,确保它们都是单通道灰度图
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
template = cv2.imread(template_path, cv2.IMREAD_GRAYSCALE)
if image is None:
raise ValueError("背景图无法加载")
if template is None:
raise ValueError("模板图无法加载")
# 获取模板的宽度和高度
w, h = template.shape[::-1]
# 使用模板匹配方法
res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.7 # 匹配度阈值,可以根据需要调整
loc = np.where(res >= threshold)
# 检查是否有匹配结果
if loc[0].size > 0:
# 取第一个匹配位置
pt = zip(*loc[::-1]).__next__() # 获取第一个匹配点的坐标
center_x = int(pt[0] + w // 2)
center_y = int(pt[1] + h // 2)
# print(f"第一个匹配到的小心心中心坐标: ({center_x}, {center_y})")
return center_x, center_y
else:
print("未找到匹配的目标")
return -1, -1
# 使用正则查找字符串中的数字
@classmethod
def findNumber(cls, str):
# 使用正则表达式匹配数字
match = re.search(r'\d+', str)
if match:
return int(match.group()) # 将匹配到的数字转换为整数
return None # 如果没有找到数字,返回 None
# 选择截图
@classmethod
def screenshot(cls):
image_path = AiUtils.imagePathWithName("bgv") # 替换为你的图像路径
image = cv2.imread(image_path)
# 如果图像过大,缩小显示
scale_percent = 50 # 缩小比例
width = int(image.shape[1] * scale_percent / 100)
height = int(image.shape[0] * scale_percent / 100)
dim = (width, height)
resized_image = cv2.resize(image, dim, interpolation=cv2.INTER_AREA)
# 创建一个窗口并显示缩小后的图像
cv2.namedWindow("Image")
cv2.imshow("Image", resized_image)
print("请在图像上选择爱心图标区域然后按Enter键确认。")
# 使用selectROI函数手动选择区域
roi = cv2.selectROI("Image", resized_image, showCrosshair=True, fromCenter=False)
# 将ROI坐标按原始图像尺寸放大
x, y, w, h = roi
x = int(x * image.shape[1] / resized_image.shape[1])
y = int(y * image.shape[0] / resized_image.shape[0])
w = int(w * image.shape[1] / resized_image.shape[1])
h = int(h * image.shape[0] / resized_image.shape[0])
# 根据选择的ROI提取爱心图标
if w > 0 and h > 0: # 确保选择的区域有宽度和高度
heart_icon = image[y:y + h, x:x + w]
# 转换为HSV颜色空间
hsv = cv2.cvtColor(heart_icon, cv2.COLOR_BGR2HSV)
# 定义红色的HSV范围
lower_red1 = np.array([0, 120, 70])
upper_red1 = np.array([10, 255, 255])
lower_red2 = np.array([170, 120, 70])
upper_red2 = np.array([180, 255, 255])
# 创建掩模
mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
mask = mask1 + mask2
# 反转掩模,因为我们想要的是爱心图标,而不是背景
mask_inv = cv2.bitwise_not(mask)
# 应用掩模
heart_icon = cv2.bitwise_and(heart_icon, heart_icon, mask=mask_inv)
# 创建一个全透明的背景
height, width, channels = heart_icon.shape
roi = np.zeros((height, width, channels), dtype=np.uint8)
# 将爱心图标粘贴到透明背景上
for c in range(channels):
roi[:, :, c] = np.where(mask_inv == 255, heart_icon[:, :, c], roi[:, :, c])
# 图片名称
imgName = "temp.png"
# 保存结果
cv2.imwrite(imgName, roi)
# 显示结果
cv2.imshow("Heart Icon with Transparent Background", roi)
cv2.waitKey(0)
cv2.destroyAllWindows()
else:
print("未选择有效区域。")
# 根据名称获取图片完整地址
@classmethod
def imagePathWithName(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
# AiUtils.screenshot()