import cv2
import numpy as np
from collections import deque
def preprocess_maze_image(image_path):
"""预处理迷宫图像:灰度化、二值化、降噪"""
# 读取图像
img = cv2.imread(image_path)
if img is None:
raise ValueError(f"无法读取图像: {image_path}")
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 自适应阈值二值化(处理光照变化)
binary = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY_INV, 11, 2
)
# 形态学操作:去除噪点并填充小孔洞
kernel = np.ones((3, 3), np.uint8)
cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, kernel)
cleaned = cv2.morphologyEx(cleaned, cv2.MORPH_CLOSE, kernel)
return img, cleaned
def detect_maze_structure(binary_img):
"""检测迷宫结构:识别网格、起点和终点"""
# 查找轮廓(墙壁)
contours, _ = cv2.findContours(
binary_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
# 找到最大轮廓(迷宫外边界)
max_contour = max(contours, key=cv2.contourArea)
x, y, w, h = cv2.boundingRect(max_contour)
# 提取迷宫区域
maze_roi = binary_img[y:y+h, x:x+w]
# 使用投影法确定网格行列数
horizontal_projection = np.sum(maze_roi, axis=1) // 255
vertical_projection = np.sum(maze_roi, axis=0) // 255
# 计算行数和列数(根据投影峰值)
rows = np.count_nonzero(horizontal_projection > 0.5 * np.max(horizontal_projection))
cols = np.count_nonzero(vertical_projection > 0.5 * np.max(vertical_projection))
# 计算单元格尺寸
cell_h = h // rows
cell_w = w // cols
# 确定起点(左下角)和终点(右上角)
start_x = x + cell_w // 2
start_y = y + h - cell_h // 2
end_x = x + w - cell_w // 2
end_y = y + cell_h // 2
# 转换为网格坐标
start_cell = (rows - 1, 0)
end_cell = (0, cols - 1)
return {
'roi': (x, y, w, h),
'grid_size': (rows, cols),
'cell_size': (cell_h, cell_w),
'start': (start_x, start_y),
'end': (end_x, end_y),
'start_cell': start_cell,
'end_cell': end_cell
}
def create_maze_grid(binary_img, maze_info):
"""创建迷宫网格矩阵(0=通道,1=墙壁)"""
x, y, w, h = maze_info['roi']
rows, cols = maze_info['grid_size']
cell_h, cell_w = maze_info['cell_size']
# 初始化迷宫网格
grid = np.zeros((rows, cols), dtype=np.uint8)
# 遍历每个单元格,检查中心区域是否为墙壁
for r in range(rows):
for c in range(cols):
# 计算单元格中心区域
cell_y = y + r * cell_h + cell_h // 4
cell_x = x + c * cell_w + cell_w // 4
roi_h = cell_h // 2
roi_w = cell_w // 2
# 检查中心区域是否为墙壁
cell_region = binary_img[
cell_y:cell_y+roi_h,
cell_x:cell_x+roi_w
]
# 如果有超过25%的像素是墙壁,则标记为墙壁
if np.mean(cell_region) > 25:
grid[r, c] = 1
return grid
def bfs_pathfinding(grid, start, end):
"""使用BFS算法寻找最短路径"""
rows, cols = grid.shape
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 右、下、左、上
# 初始化队列和访问矩阵
queue = deque([(start, [start])])
visited = np.zeros_like(grid, dtype=bool)
visited[start] = True
while queue:
(r, c), path = queue.popleft()
# 到达终点
if (r, c) == end:
return path
# 探索四个方向
for dr, dc in directions:
nr, nc = r + dr, c + dc
# 检查是否在网格内且不是墙壁
if (0 <= nr < rows and 0 <= nc < cols and
not visited[nr, nc] and grid[nr, nc] == 0):
visited[nr, nc] = True
queue.append(((nr, nc), path + [(nr, nc)]))
return [] # 未找到路径
def visualize_results(original_img, maze_info, grid, path):
"""可视化结果:在原图上标记路径、起点和终点"""
x, y, w, h = maze_info['roi']
rows, cols = maze_info['grid_size']
cell_h, cell_w = maze_info['cell_size']
# 创建输出图像
result_img = original_img.copy()
# 绘制迷宫边界
cv2.rectangle(result_img, (x, y), (x+w, y+h), (0, 100, 255), 2)
# 绘制起点和终点
cv2.circle(result_img, maze_info['start'], 8, (0, 0, 255), -1) # 红色起点
cv2.circle(result_img, maze_info['end'], 8, (255, 0, 0), -1) # 蓝色终点
# 绘制路径
if path:
for i in range(1, len(path)):
r1, c1 = path[i-1]
r2, c2 = path[i]
# 计算实际像素坐标
y1 = y + r1 * cell_h + cell_h // 2
x1 = x + c1 * cell_w + cell_w // 2
y2 = y + r2 * cell_h + cell_h // 2
x2 = x + c2 * cell_w + cell_w // 2
# 绘制路径线
cv2.line(result_img, (x1, y1), (x2, y2), (0, 255, 0), 2)
return result_img
def process_maze_image(image_path, output_path="output.png"):
"""处理迷宫图像的主函数"""
try:
# 1. 图像预处理
original, binary = preprocess_maze_image(image_path)
# 2. 检测迷宫结构
maze_info = detect_maze_structure(binary)
# 3. 创建迷宫网格
grid = create_maze_grid(binary, maze_info)
# 4. 路径规划
path = bfs_pathfinding(
grid,
maze_info['start_cell'],
maze_info['end_cell']
)
if not path:
print("警告:未找到从起点到终点的路径!")
# 5. 可视化结果
result_img = visualize_results(original, maze_info, grid, path)
# 保存结果
cv2.imwrite(output_path, result_img)
print(f"处理完成!结果已保存至: {output_path}")
return result_img
except Exception as e:
print(f"处理过程中出错: {str(e)}")
return None
# 示例使用
if __name__ == "__main__":
input_image = "maze.png" # 替换为你的迷宫图像路径
output_image = "solved_maze.png"
result = process_maze_image(input_image, output_image)
# 显示结果(可选)
if result is not None:
cv2.namedWindow("Solved Maze",cv2.WINDOW_NORMAL)
cv2.imshow("Solved Maze", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
提高这段代码的识别墙壁精度,完整写出改进后代码。开发基于OpenCV和python语言等的图像处理程序,实现从图像中自动识别迷宫结构、规划最短路径,并可视化结果。预处理:将输入的迷宫图像转换为可分析的二值化结构。结构识别:自动检测迷宫的墙壁、通道、起点和终点。
结果可视化:在原图上标记路径并输出处理后的图像。输入:PNG格式,用imread读入,迷宫墙体为深色,通道为浅色。
输出:在原图上用绿色线条标记路径,线条最好要在路径的中央,起点用红色圆点标记,终点用蓝色圆点标记。用窗口输出结果。利用直线检测识别迷宫图像所在位置。
利用直线检测或其他方式分析迷宫结构。
路径规划推荐使用BFS算法确保最短路径。不使用matplotlib,自动定位起点和终点,误差不超过1个单元格;正确二值化、降噪等,保留完整迷宫结构;找到最短路径,无死胡同或错误转向;清晰标记路径、起点和终点,色彩对比度符合要求
自动识别起点(左下角起点)和终点(右上角):结构清晰,注释完整,异常保护合理,处理时间达标;迷宫外墙注意识别,不可走外墙以外的路径。有些迷宫墙壁较细,可利用腐蚀膨胀来实现高识别精度,注意网格处理的正确性。不要多余线条,不用sys库。将迷宫旋转 15°以内时,能正确矫正图形;背景中出现随机杂物时,仍能正确识别迷宫结构;当摄像头斜视 30°视角偏移时仍能矫正并识别。程序需适应不同尺寸和复杂度的迷宫图像(最小10 × 10单元格,最大
30 × 30单元格)。