如何从迷宫图片中找出入口和出口的位置

How to find out the locations of entry and exit from a maze picture

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

为了方便说明,我用红色和蓝色标出了2个点,但是原图中没有,所以请不要指望。

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

我注意到有 2 个黑色箭头指向 2 个位置,但是如果没有这 2 个箭头的帮助,如何定位这 2 个位置?

更新 1

我应该在这里上传处理过的图片:

经过一些图像处理程序,我得到了提取的迷宫。但这不是我要问的,言归正传,提取的迷宫图应该是本题的出发点。

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

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

运行 通过边缘和“光线投射”直到我们撞到墙上,这里有一些图表显示了沿每条边缘找到的每条线的长度。

顶边

左边

底边

右边

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

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);