Java基于OpenCV实现走迷宫(图片+路线展示)

Java基于OpenCV实现走迷宫(图片+路线展示)

由于疫情,待在家中,太过无聊。同学发了我张迷宫图片,让我走迷宫来缓解暴躁,于是乎就码了一个程序出来。特此记录。

原图:

这张图,由于不是非常清晰,所以我们要进行处理。首先转换为灰度图:

public static Mat RGB2Gray(Mat image) {
  // Gray = R*0.299 + G*0.587 + B*0.114
  Mat gray = new Mat();
  Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);
  return gray;
}

主要思路:

  • 转换为灰度图
  • 设置Threshold来区分黑白点,转换为黑白图
  • 规定起点、终点
  • 处理图像,封住边框,这样就不会从外边框走
  • 使用bfs算法来求解走迷宫的最短路径,并通过记录上一个节点嵌套的方式记录下路径
  • 渲染在图片上,输出

代码:

package edu.sfls.Jeff.JavaDev.Maze;

import edu.sfls.Jeff.JavaDev.CVLib.SmartConverter;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;

import java.util.LinkedList;
import java.util.Queue;

public class SolveMaze {

    public static void main(String[] args) throws InterruptedException {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
        Mat src_maze = Imgcodecs.imread("src/IMG_2679.JPG");
        HighGui.imshow("src_maze", src_maze);
        Mat pre_maze = SmartConverter.RGB2Gray(src_maze);
        Mat color_maze = src_maze.clone();
        for (int i = 0; i < pre_maze.rows(); i ++)
            for (int j = 0; j < pre_maze.cols(); j ++)
                if (pre_maze.get(i, j)[0] < 100)
                    color_maze.put(i, j, 0, 0, 0);
                else
                    color_maze.put(i, j, 255, 255, 255);
        for (int i = 0; i < pre_maze.rows(); i ++)
            for (int j = 0; j < 32; j ++)
                color_maze.put(i, color_maze.cols() - j - 1, 0, 255, 0);
        Point startPoint = new Point(color_maze.cols() - 32 - 1 - 2, 347 + 5 - 1);
        Point endPoint = new Point(17, 351);
        color_maze.put(startPoint.y, startPoint.x, 0, 0, 255);

        boolean[][] vis = new boolean[1078][702];
        for (int i = 0; i < 1078; i ++)
            for (int j = 0; j < 702; j ++)
                vis[i][j] = false;
        vis[startPoint.x][startPoint.y] = true;

        Point successPoint = new Point(17, 351);

        Queue<Point> queue = new LinkedList<>();
        queue.offer(startPoint);
        while (!queue.isEmpty()) {
            Point p = queue.poll();
            System.out.println(p.x + " " + p.y);
            vis[p.x][p.y] = true;
            if (p.x == endPoint.x && p.y == endPoint.y) {
                System.out.println("success");
                successPoint = p;
                break;
            }
            if (p.x - 1 >= 0)
                if (!vis[p.x - 1][p.y] && color_maze.get(p.y, p.x - 1)[0] == 255) {
                    queue.offer(new Point(p.x - 1, p.y, p));
                    vis[p.x - 1][p.y] = true;
                }
            if (p.y - 1 >= 0)
                if (!vis[p.x][p.y - 1] && color_maze.get(p.y - 1, p.x)[0] == 255) {
                    queue.offer(new Point(p.x, p.y - 1, p));
                    vis[p.x][p.y - 1] = true;
                }
            if (p.x + 1 < 1078)
                if (!vis[p.x + 1][p.y] && color_maze.get(p.y, p.x + 1)[0] == 255) {
                    queue.offer(new Point(p.x + 1, p.y, p));
                    vis[p.x + 1][p.y] = true;
                }
            if (p.y + 1 < 702)
                if (!vis[p.x][p.y + 1] && color_maze.get(p.y + 1, p.x)[0] == 255) {
                    queue.offer(new Point(p.x, p.y + 1, p));
                    vis[p.x][p.y + 1] = true;
                }
        }

        System.out.println("out");

        Point pre = successPoint.pre;
        color_maze.put(pre.y, pre.x, 0, 0, 255);
        while (pre.pre != null) {
            pre = pre.pre;
            color_maze.put(pre.y, pre.x, 0, 0, 255);
        }

        HighGui.imshow("color", color_maze);
        HighGui.waitKey(0);
    }

}

class Point {

    int x, y;

    Point pre;

    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    Point(int x, int y, Point pre) {
        this.x = x;
        this.y = y;
        this.pre = pre;
    }
}

结果:

原文地址:https://www.cnblogs.com/jeffersonqin/p/12266591.html