python实现连连看辅助(图像识别)

  

Python实现连连看辅助(图像识别)攻略

简介

该攻略提供了一种基于图像识别实现的连连看辅助方法,利用Python编程语言中的图像处理库实现,能够自动识别连连看中的道路和障碍物,并计算出可消除的路径。该方法可以有效提高连连看的游戏体验,并辅助玩家通过连连看更高水平。

准备工作

  • 安装Python 3.X版本
  • 安装图像处理库OpenCV (pip install opencv-python)
  • 安装图像识别库pytesseract (pip install pytesseract)
  • 下载并安装Tesseract OCR引擎 下载地址

实现过程

步骤1:截取游戏屏幕

首先需要截取游戏屏幕作为程序的输入。可以使用OpenCV库进行截屏并对屏幕进行处理。下面是代码示例:

import cv2

# 截取游戏窗口
def capture_game_screen():
    # 获取窗口句柄
    handle = win32gui.FindWindow(None, '连连看')
    # 获取窗口位置
    left, top, right, bottom = win32gui.GetWindowRect(handle)
    # 截图
    img = ImageGrab.grab(bbox=(left+8, top+31, right-8, bottom-8))
    # 转为OpenCV格式
    img = cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)
    return img

步骤2:图像处理

截取屏幕后,需要进行图像处理,主要的处理方法包括灰度化、二值化、降噪等。这些处理可以使图像信息更加清晰,便于后续处理。下面是代码示例:

# 图像预处理
def preprocess_image(img):
    # 灰度化
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 二值化
    _, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)
    # 降噪
    kernel = np.ones((3, 3), np.uint8)
    processed_img = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

    return processed_img

步骤3:OCR识别数字

连连看中有的数字需要识别,例如剩余步数、当前关卡等,可以使用OCR技术实现。利用pytesseract库实现OCR识别,下面是代码示例:

import pytesseract

# OCR识别
def recognize_text(img):
    # 转为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 去除背景黑色
    _, thresh = cv2.threshold(gray, 40, 255, cv2.THRESH_BINARY)
    # 图像膨胀
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
    dilated = cv2.dilate(thresh, kernel)
    # 识别文本
    config = '--psm 11 digits'
    text = pytesseract.image_to_string(dilated, lang='eng', config=config)
    # 转换文本格式
    text = text.replace('$', '5')
    text = text.replace('S', '5')

    return text

步骤4:游戏分析

分析游戏截图,识别出道路和障碍物,并建立地图数据结构。地图数据结构可以使用矩阵表示。下面是代码示例:

# 提取连连看地图
def extract_map(img):
    # 找出道路
    road = cv2.inRange(img, (217, 217, 217), (225, 225, 225))
    # 找出障碍物
    obstacles = cv2.inRange(img, (115, 11, 1), (130, 22, 9))
    # 将道路和障碍物合并
    merge = cv2.bitwise_or(road, obstacles)
    # 膨胀操作
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))
    dilated = cv2.dilate(merge, kernel)
    # 寻找连通区域
    _, labels = cv2.connectedComponents(dilated)
    # 将标签图转为矩阵
    img_height, img_width = dilation.shape
    map = np.zeros((img_height, img_width), np.uint8)
    for i in range(img_height):
        for j in range(img_width):
            if labels[i][j] > 0:
                map[i][j] = labels[i][j]

    return map

步骤5:路径搜索

通过图搜索算法搜索两个点之间能否连通,找到消除道路的最短路径。可以使用广度优先搜索(BFS)或者A*算法。下面是代码示例:

# 判断两点是否连通
def is_connect(map, p1, p2):
    if map[p1[0]][p1[1]] == map[p2[0]][p2[1]]:
        return True
    else:
        return False

# BFS搜索路径
def search_path_BFS(map, p1, p2):
    queue = []
    visited = np.zeros_like(map, np.uint8)
    directions = [(0, 1), (1, 0), (-1, 0), (0, -1)]

    queue.append(p1)
    visited[p1[0]][p1[1]] = 1

    while queue:
        node = queue.pop(0)
        if node == p2:
            # 找到路径
            path = []
            path.append(node)
            parent = visited[node[0]][node[1]]
            while parent > 0:
                path.append(parent)
                parent = visited[parent[0]][parent[1]]
            path.reverse()
            return path

        # 搜索周围节点
        for d in directions:
            neighbor = (node[0]+d[0], node[1]+d[1])
            if neighbor[0]<0 or neighbor[0]>=map.shape[0] or neighbor[1]<0 or neighbor[1]>=map.shape[1]:
                continue

            if visited[neighbor[0]][neighbor[1]] > 0:
                continue

            if map[neighbor[0]][neighbor[1]] == 0:
                continue

            visited[neighbor[0]][neighbor[1]] = node
            queue.append(neighbor)

    # 没有路径
    return []

# A*搜索路径
def search_path_A_star(map, p1, p2):
    ...

步骤6:主函数

组合以上步骤实现主函数,不断截屏、分析图像、搜索路径,并模拟鼠标点击来实现连连看辅助效果。下面是伪代码:

img = capture_game_screen()
processed_img = preprocess_image(img)
map = extract_map(processed_img)

# 判断是否需要新的地图
if need_new_map(map):
    click_new_game_button()
    time.sleep(2)
    click_next_level_button()

# 搜索随机2个点
road_points = get_road_points(map)
p1, p2 = get_random_points(road_points)

# 搜索路径
path = search_path_BFS(map, p1, p2)

# 如果没有找到路径,重新搜索
if not path:
    p1, p2 = get_random_points(road_points)
    path = search_path_BFS(map, p1, p2)

# 模拟鼠标点击
click_mouse(p1)
time.sleep(0.5)
click_mouse(p2)

# 重复以上步骤

示例说明

下面提供两个示例说明如何使用该攻略实现连连看辅助功能。

示例1

假设已经打开了连连看游戏,并处于游戏中的状态。此时可以运行上述代码实现辅助功能。

示例2

假设没有打开连连看游戏,则需要将代码嵌入到自动化测试工具中,实现在连连看游戏中自动搜索和消除道路的功能。

相关文章