-2

只是想知道是否可以在图片中找出迷宫的入口和出口点?

为了说明目的,我用红色和蓝色突出显示了这两个点,但它们在原始图片中不存在,所以请不要指望它们。

入口和出口的位置可以变化,例如它们可以在边缘的中间,但不限于角落或中间的位置。

我注意到有 2 个黑色箭头指向 2 个位置,但是如何在没有这 2 个箭头的帮助的情况下找到这 2 个位置?

在此处输入图像描述

更新 1

我应该在这里上传处理后的图像:

在此处输入图像描述

在应用了一些图像处理程序后,我得到了提取的迷宫。但这不是我要问的,让我们回到主题,提取的迷宫图像应该是这个问题的起点。

4

1 回答 1

3

我从你提取的迷宫图像开始。首先要做的是找到迷宫的四个角落。我们可以通过寻找四个最极端(最靠近图像角落)的点来找到它们。我们可以将这四个角连接起来,形成一个(某种)矩形来包围我们的迷宫。

在此处输入图像描述

这个想法是找到垂直于矩形边缘的最长的非占用(白色)点线。为了简化数学,我们可以纠正图像,因为我们知道四个角。

穿过边缘并“投射”直到我们撞到墙,这里有一些沿着每条边缘找到的每条线的长度的图表。

顶边

在此处输入图像描述

左边缘

在此处输入图像描述

底边

在此处输入图像描述

右边缘

在此处输入图像描述

现在我们可以为每条边找到最长的线,取最高的两条,这就是我们进入迷宫的入口。

在此处输入图像描述

import cv2
import numpy as np
import matplotlib.pyplot as plt

# tuplifies a point for opencv
def tup(p):
    return (int(p[0]), int(p[1]));

# load image
img = cv2.imread("maze.png");

# resize
scale = 0.5;
h, w = img.shape[:2];
h = int(h*scale);
w = int(w*scale);
img = cv2.resize(img, (w,h));
copy = np.copy(img);

# mask image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
mask = cv2.inRange(gray, 100, 255);

# find corners
corners = [[[0,0], 0] for a in range(4)];
for y in range(h):
    # progress check
    print(str(y) + " of " + str(h));
    for x in range(w):
        # check pixel
        if mask[y][x] == 0:
            # scores
            scores = [];
            scores.append((h - y) + (w - x)); # top-left
            scores.append((h - y) + x); # top-right
            scores.append(y + x); # bottom-right
            scores.append(y + (w - x)); # bottom-left
            
            # check corners
            for a in range(len(scores)):
                if scores[a] > corners[a][1]:
                    corners[a][1] = scores[a];
                    corners[a][0] = [x, y];

# draw connecting lines
for a in range(len(corners)):
    prev = corners[a-1][0];
    curr = corners[a][0];
    cv2.line(img, tup(prev), tup(curr), (0,200,0), 2);

# draw corners
for corner in corners:
    cv2.circle(img, tup(corner[0]), 4, (255,255,0), -1);

# re-orient to make the math easier
rectify = np.array([[0,0], [w,0], [w,h], [0,h]]);
numped_corners = [corner[0] for corner in corners];
numped_corners = np.array(numped_corners);
hmat, _ = cv2.findHomography(numped_corners, rectify);
rect = cv2.warpPerspective(copy, hmat, (w,h));

# redo mask
gray = cv2.cvtColor(rect, cv2.COLOR_BGR2GRAY);
mask = cv2.inRange(gray, 100, 255); 

# dilate
kernel = np.ones((3,3), np.uint8);
mask = cv2.erode(mask, kernel, iterations = 5);

# find entrances
top = []; # [score, point]
# top side
for x in range(w):
    y = 0;
    while mask[y][x] == 255:
        y += 1;
    top.append([y, [x,0]]);
# left side
left = [];
for y in range(h):
    x = 0;
    while mask[y][x] == 255:
        x += 1;
    left.append([x, [0,y]]);
# bottom side
bottom = [];
for x in range(w):
    y = h-1;
    while mask[y][x] == 255:
        y -= 1;
    bottom.append([(h - y) - 1, [x, h-1]]);
# right side
right = [];
for y in range(h):
    x = w-1;
    while mask[y][x] == 255:
        x -= 1;
    right.append([(w - x) - 1, [w-1,y]]);

# combine
scores = [top, left, bottom, right];

# plot
for side in scores:
    fig = plt.figure();
    ax = plt.axes();
    y = [score[0] for score in side];
    x = [a for a in range(len(y))];
    ax.plot(x, y);
    plt.show();

# get the top score for each side
highscores = []; # [score, [x, y]];
for side in scores:
    top_score = -1;
    top_point = [-1, -1];
    for score in side:
        if score[0] > top_score:
            top_score = score[0];
            top_point = score[1];
    highscores.append([top_score, top_point]);

# get the top two (assuming that there are two entrances to the maze)
one = [0, [0,0]];
two = [0, [0,0]];
for side in highscores:
    if side[0] > one[0]:
        two = one[:];
        one = side[:];
    elif side[0] > two[0]:
        two = side[:];

# draw the entrances
cv2.circle(rect, tup(one[1]), 5, (0,0,255), -1);
cv2.circle(rect, tup(two[1]), 5, (0,0,255), -1);

# show
cv2.imshow("Image", img);
cv2.imshow("Rect", rect);
cv2.waitKey(0);
于 2021-04-30T14:47:13.083 回答