opencv-python 将图像迷宫转为迷宫数组

起因是我想做个自动走迷宫的外挂(其实是想做点实践),所以我需要在游戏中捕捉画面并自动寻路,然后再控制自动移动,此为第一部分:捕捉画面。

一.思路

1.取得图像迷宫

2.处理图像

3.图像分割

4.生成数组

二.代码

首先我们得捕捉屏幕画面,即获得迷宫图像,这里我是在steam上面找了一个迷宫小游戏作为捕捉对象

在这里插入图片描述

然后写个捕捉屏幕画面的函数

def VideoCapture():
    imm = ImageGrab.grab()  # 获得当前屏幕
    imm = cv2.cvtColor(np.array(imm), cv2.COLOR_RGB2GRAY)  # 转为opencv的灰度图
    imm = imm[35:1040, 450:1470]  # 1080*1100 裁剪图像,这是根据游戏画面调整的数值 
    imm = cv2.resize(imm, (250, 250))  # 19 * 19 缩小图像
    return imm

然后如果显示图像就能看到:

在这里插入图片描述

接着我们需要对图像进行处理,我们可以看到这个迷宫有三个对象:从上到下依次是巢,心,球。而我们是要操控球吃完所有的心再返回巢。所以 巢和心的是需要搜索路径的终点,球是起点,但是在此之前,我们需要一个完整的迷宫地图,所以我们要先找到这三个对象并涂白:

所以我们要进行模板匹配:

def match(target, template, color):
    global object
    # 获得模板图片的高宽尺寸
    theight, twidth = template.shape[:2]
    # 执行模板匹配,采用的匹配方式cv2.TM_SQDIFF_NORMED
    result = cv2.matchTemplate(target, template, cv2.TM_SQDIFF_NORMED)
    # 归一化处理
    cv2.normalize(result, result, 0, 1, cv2.NORM_MINMAX, -1)
    # 寻找矩阵(一维数组当做向量,用Mat定义)中的最大值和最小值的匹配结果及其位置
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    # 匹配值转换为字符串
    # 对于cv2.TM_SQDIFF及cv2.TM_SQDIFF_NORMED方法min_val越趋近与0匹配度越好,匹配位置取min_loc
    # 对于其他方法max_val越趋近于1匹配度越好,匹配位置取max_loc
    strmin_val = str(min_val)
    # 绘制矩形边框,将匹配区域涂成白色
    # min_loc:矩形定点
    # (min_loc[0]+twidth,min_loc[1]+theight):矩形的宽高
    # color:矩形的边框颜色;2:矩形边框宽度
    cv2.rectangle(target, min_loc, (min_loc[0] + twidth, min_loc[1] + theight), color, -1)
    # 返回操作后图像,以及对象的四点坐标
    return [target, (int(min_loc[0]), int(min_loc[1]), int(min_loc[0] + twidth), int(min_loc[1] + theight))]

执行后效果如图所示:

在这里插入图片描述

然后我们要把图像转化为标准的迷宫图像,黑白块的大小要相等,这样才方便转化成数组形式,所以我们对图像进行二值化后白色为可走趋于,黑色为障碍,接着通过腐蚀操作增大黑色趋于使之与白色块大小接近。

def pic(imm):
    ret, binary = cv2.threshold(imm, 200, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)# 二值化
    k = np.ones((7, 7), np.uint8)#定义核
    binary = cv2.erode(binary, k)# 腐蚀
    return binary

在这里插入图片描述

然后大致数出可以划分为19*19的色块,计算出单个色块的长度,然后定义每个色块的近中心点(因为坐标只能整数而计算中心点会有小数,一般略微靠近左上角比较准确),取其近中心点的颜色为整个色块的颜色转化为数组中:

def getBoard(imm):
    board = [[0 for w in range(19)] for h in range(19)]#创建数组
    for h in range(19):
        for w in range(19):
            if imm[13 * h + 5, 13 * w + 5] == np.uint8(255):#坐标转换
                board[h][w] = 255
    return board

然后我们把得到的数组以图像的形式打印出来看看:

在这里插入图片描述

对比一下原图像,已经实现了我们的目的。

最后我们再把其他信息获取一下,比如对象位置转化为数组坐标:

def getBoardIndex(cor):
    index = (int((cor[1] - 5) / 13), int((cor[0] - 5) / 13))
    return index

然后我们也方便日后的寻路算法应用(这么小,很快!)

最后的最后给个运行代码:

startFlag = False
while True:
    imm = VideoCapture()
    if startFlag:
        imm, ball = match(imm, cv2.imread("ball.png", 0), (255, 255, 255))
        imm, home = match(imm, cv2.imread("home.png", 0), (255, 255, 255))
        imm, heart = match(imm, cv2.imread("heart.png", 0), (255, 255, 255))
        imm = pic(imm)
        board = getBoard(imm)
        cv2.imwrite("board.png", np.array(board, dtype=np.uint8))
        ball = getBoardIndex(getPointCor(ball))
        heart = getBoardIndex(getPointCor(heart))
        home = getBoardIndex(getPointCor(home))
        print(ball, heart, home)
    key = cv2.waitKey(1)
    if key == ord('q'):
        break
    elif key == ord('g'):
        startFlag = True
    cv2.imshow("im", imm)
 key = cv2.waitKey(1)
    if key == ord('q'):
        break
    elif key == ord('g'):
        startFlag = True
    cv2.imshow("im", imm)
  • 7
    点赞
  • 118
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要使用OpenCV和Python来解决迷宫问题,可以使用图像处理和路径搜索算法。以下是一个基本的实现示例: 1. 导入必要的库: ```python import cv2 import numpy as np ``` 2. 加载迷宫图像并进行预处理: ```python maze = cv2.imread('maze_image.jpg', 0) ret, thresh = cv2.threshold(maze, 127, 255, cv2.THRESH_BINARY) ``` 3. 定义起点和终点坐标: ```python start = (50, 50) # 起点坐标 end = (400, 400) # 终点坐标 ``` 4. 定义可行走方向和移动步长: ```python directions = [(-1, 0), (1, 0), (0, -1), (0, 1)] # 上下左右四个方向 step_size = 10 # 移动步长 ``` 5. 创建路径搜索函数: ```python def search_path(current_pos): if current_pos == end: return True for direction in directions: next_pos = (current_pos[0] + direction[0] * step_size, current_pos[1] + direction[1] * step_size) if is_valid_move(next_pos): if search_path(next_pos): return True return False ``` 6. 创建检查移动是否有效的函数: ```python def is_valid_move(pos): if pos[0] < 0 or pos[0] >= maze.shape[0] or pos[1] < 0 or pos[1] >= maze.shape[1]: return False if thresh[pos[0], pos[1]] == 0: return False return True ``` 7. 调用路径搜索函数并显示结果: ```python result = search_path(start) if result: print("找到了最短路径!") else: print("无法找到最短路径!") cv2.imshow("Maze", maze) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这是一个简单的迷宫问题解决示例,它使用OpenCV加载和处理图像,并使用递归路径搜索算法来查找起点到终点的最短路径。根据具体的迷宫图像和需求,可能需要进行适当的调整和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值