如何使用opencv python解决theta迷宫?

2023-12-28

This is a sample theta mazeI have to find shortest path from the center of the maze to the outermost circle. I have to solve this problem using opencv and python


I'm out!

您可以将图像中的每个白色像素视为无向加权图的节点。每个像素(节点)都与其白色邻居相连。连接两个节点的边的权重在水平和垂直方向上均为1,并且sqrt(2)(或者简单地1.414)沿对角线方向。

然后,既然你知道起点和终点,你就可以运行迪杰斯特拉算法 https://en.wikipedia.org/wiki/Dijkstra's_algorithm找到起点和终点之间的最短路径。

I used 罗塞塔代码 https://rosettacode.org/wiki/Dijkstra%27s_algorithmDijkstra算法的实现:

这是代码(没有真正完善,但可以工作)。代码是 C++ 语言,但应该很容易转换为 Python,特别是如果你能找到 Dijkstra 算法的良好实现:

#include <opencv2/opencv.hpp>


#include <iostream>
#include <vector>
#include <string>
#include <list>

#include <limits> // for numeric_limits

#include <vector>
#include <set>
#include <utility> // for pair
#include <algorithm>
#include <iterator>

using namespace cv;
using namespace std;

typedef int vertex_t;
typedef double weight_t;

const weight_t max_weight = std::numeric_limits<double>::infinity();

struct neighbor {
    vertex_t target;
    weight_t weight;
    neighbor(vertex_t arg_target, weight_t arg_weight)
        : target(arg_target), weight(arg_weight) { }

    bool operator == (const neighbor& other) const {
        return target == other.target;
    }
};

typedef std::vector<std::vector<neighbor> > adjacency_list_t;


void DijkstraComputePaths(vertex_t source,
    const adjacency_list_t &adjacency_list,
    std::vector<weight_t> &min_distance,
    std::vector<vertex_t> &previous)
{
    int n = adjacency_list.size();
    min_distance.clear();
    min_distance.resize(n, max_weight);
    min_distance[source] = 0;
    previous.clear();
    previous.resize(n, -1);
    std::set<std::pair<weight_t, vertex_t> > vertex_queue;
    vertex_queue.insert(std::make_pair(min_distance[source], source));

    while (!vertex_queue.empty())
    {
        weight_t dist = vertex_queue.begin()->first;
        vertex_t u = vertex_queue.begin()->second;
        vertex_queue.erase(vertex_queue.begin());

        // Visit each edge exiting u
        const std::vector<neighbor> &neighbors = adjacency_list[u];
        for (std::vector<neighbor>::const_iterator neighbor_iter = neighbors.begin();
            neighbor_iter != neighbors.end();
            neighbor_iter++)
        {
            vertex_t v = neighbor_iter->target;
            weight_t weight = neighbor_iter->weight;
            weight_t distance_through_u = dist + weight;
            if (distance_through_u < min_distance[v]) {
                vertex_queue.erase(std::make_pair(min_distance[v], v));

                min_distance[v] = distance_through_u;
                previous[v] = u;
                vertex_queue.insert(std::make_pair(min_distance[v], v));

            }

        }
    }
}


std::list<vertex_t> DijkstraGetShortestPathTo(
    vertex_t vertex, const std::vector<vertex_t> &previous)
{
    std::list<vertex_t> path;
    for (; vertex != -1; vertex = previous[vertex])
        path.push_front(vertex);
    return path;
}

struct lessPoints
{
    bool operator() (const Point& lhs, const Point& rhs) const {
        return (lhs.x != rhs.x) ? (lhs.x < rhs.x) : (lhs.y < rhs.y);
    }
};

int main()
{
    Mat1b img = imread("path_to_image", IMREAD_GRAYSCALE);
    resize(img, img, Size(), 0.5, 0.5);

    copyMakeBorder(img, img, 1, 1, 1, 1, BORDER_CONSTANT, Scalar(0));

    Point startPt(150, 150);
    Point endPt(160, 10);

    Mat1b mask = img > 200;

    vector<Point> pts;
    findNonZero(mask, pts);


    map<Point, int, lessPoints> mp;
    for (size_t i = 0; i < pts.size(); ++i) {
        mp[pts[i]] = i;
    }

    adjacency_list_t adj(pts.size());
    for (size_t i = 0; i < pts.size(); ++i) {

        int r = pts[i].y;
        int c = pts[i].x;

        // TODO: Check valid range

        if (mask(r - 1, c - 1)) { // Top Left
            adj[i].push_back(neighbor(mp[Point(c - 1, r - 1)], 1.414));
        }
        if (mask(r - 1, c)) { // Top 
            adj[i].push_back(neighbor(mp[Point(c, r - 1)], 1.0));
        }
        if (mask(r - 1, c + 1)) { // Top Right
            adj[i].push_back(neighbor(mp[Point(c + 1, r - 1)], 1.414));
        }
        if (mask(r, c - 1)) { // Left
            adj[i].push_back(neighbor(mp[Point(c - 1, r)], 1.0));
        }
        if (mask(r, c + 1)) { // Right
            adj[i].push_back(neighbor(mp[Point(c + 1, r)], 1.0));
        }
        if (mask(r + 1, c - 1)) { // Bottom Left
            adj[i].push_back(neighbor(mp[Point(c - 1, r + 1)], 1.414));
        }
        if (mask(r + 1, c)) { // Bottom
            adj[i].push_back(neighbor(mp[Point(c, r + 1)], 1.0));
        }
        if (mask(r + 1, c + 1)) { // Bottom Right
            adj[i].push_back(neighbor(mp[Point(c + 1, r + 1)], 1.414));
        }
    }


    vertex_t start_vertex = mp[startPt];
    vertex_t end_vertex = mp[endPt];

    std::vector<weight_t> min_distance;
    std::vector<vertex_t> previous;
    DijkstraComputePaths(start_vertex, adj, min_distance, previous);

    Mat3b dbg;
    cvtColor(mask, dbg, COLOR_GRAY2BGR);
    circle(dbg, startPt, 3, Scalar(0, 255, 0));
    circle(dbg, endPt, 3, Scalar(0, 0, 255));

    std::list<vertex_t> path = DijkstraGetShortestPathTo(end_vertex, previous);

    for (vertex_t v : path) {
        dbg(pts[int(v)]) = Vec3b(255, 0, 0);
        int vgfd = 0;
    }

    imshow("Solution", dbg);
    waitKey();

    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用opencv python解决theta迷宫? 的相关文章

随机推荐

  • Java 重载和覆盖

    我们总是说方法重载是静态多态 重写是运行时多态 这里的静态到底是什么意思 对方法的调用是否在编译代码时解析 那么普通方法调用和调用final方法有什么区别呢 编译时链接的是哪一个 方法重载意味着根据输入创建函数的多个版本 例如 public
  • .Net Remoting:指示使用哪个本地接口连接到一台服务器

    我们有一个通过 Net 远程处理连接的服务器 The server is on two network the client is on two network The client and the server have only one
  • 从“@Angular”而不是“Angular2”导入{*}

    我对 Angular2 有点困惑 许多例子表明 import Component from angular core 但实际上在node module有angular2目录存在 所以从逻辑上来说应该是 import Component fr
  • 3.0之后如何使用initWithStyle制作自定义TableViewCell

    我正在尝试使用 initWithStyle 自定义 TableViewCell 因为它说 initWithFrame 在 3 0 后已弃用 之前 initWithFrame 一切正常 有可用的教程或示例代码吗 谢谢 我对 UITableVi
  • oracle将数字转换为日期sql

    我正在尝试转换一个数字 yyyymmdd 迄今为止 mm dd yyyy 例如 20150302 gt 03 02 2015 你可以试试这个 select to date 20150302 yyyymmdd from dual or sel
  • 多对多 Spring Data JPA 关系中的额外列,变化最小

    我需要更改项目的模型 现在 我们有两个具有双向多对多关系的类 这意味着在关系表中 现在需要向关系添加额外的信息 我的问题是 唯一的方法是为关系创建一个类 例如 使用与已存在的关系表相同的名称创建一个类 我这么问是因为如果我们需要改变项目中的
  • 有没有办法在 Visual Studio 中自动更新已安装的 NuGet 包?

    正如标题所示 我想知道是否有一种方法可以在包源中出现新版本时自动更新已安装的 NuGet 包 该用例是一个将某些公司策略 代码分析 签名等 应用于我们的项目的包 一旦该包更新 我希望能够为此包配置自动更新 我确实知道 NuGet 有一个包恢
  • Python 列表是否保证其元素保持插入的顺序?

    如果我有以下Python代码 gt gt gt x gt gt gt x x 1 gt gt gt x x 2 gt gt gt x x 3 gt gt gt x 1 2 3 Will x保证永远是 1 2 3 或者临时元素的其他顺序是否可
  • Xpath选择多个标签

    我想要使 用 PHP DOMXPath 查询的多个标签 td 和 th 我该怎么做 您可以使用 联盟 运营商 这是一个例子 doc new DOMDocument doc gt loadHTML table tr th table head
  • 使用自动滚动向面板添加控件 (c#)

    我有一个带有属性的面板AutoScroll true 通过动态地将其他控件添加到面板而不滚动 一切正常 void addControl int top 13 this Controls Count cmdSet Height ucComma
  • 如何定义 R 函数的参数类型?

    我正在编写一个 R 函数 并且我想确保我的 R 函数的参数属于某个类 例如 矩阵 做这个的最好方式是什么 假设我有一个函数 foo 它计算矩阵的逆 foo lt function x I want to make sure x is of
  • 名称冲突的类的构造函数

    我正在使用 clang 使用 c 14 方言编译我的代码 举个例子 class x int i public x int i this gt i i void x void f class x my x Do something here
  • jboss 7.1 xalan 问题?

    我正在尝试在 JBoss7 上创建基于 Apache Jena 的应用程序 Apache Jena 使用 Xalan 2 11 0 JBoss 7 附带 2 7 1 当我尝试调用该应用程序时 出现异常 其根源是 org apache xer
  • 记录函数闭包

    例如 假设我的包中有一个函数闭包 f function x x x g function y x lt lt y h function x list g g h h l f 5 l g 10 l h 什么是正确的 在官方CRAN http
  • JFactory导入失败

    我正在尝试为 Android 应用程序制作一个登录系统 该系统可与我的 2 5 Joomla 网站一起使用 我试图通过制作一个 Joomla 插件来做到这一点 Android 应用程序将发布数据发送到 php 文件 然后该文件对用户进行身份
  • 减少 Swing 应用程序中耦合的设计模式

    大家好 我目前正在开发 Java Swing 应用程序 并且正在寻找一些指导 该应用程序相当小 但我注意到 随着代码库变得越来越大 我的对象图中存在大量耦合 我对 Swing 比较陌生 但我已经编程了足够长的时间 知道它的发展方向 我遇到的
  • Django 中间件并获取视图名称?

    我正在尝试用 Django 编写我的第一个中间件 class RefreshBalance def process view self request view func view args view kwargs pass 我想检测视图是
  • volatile int 比 AtomicInteger 快吗

    我目前正在做一个示例练习 我发现一个奇怪的观察结果 如果我用易失性程序替换 AutomicInteger 则运行速度会更快 注意 我只进行读操作 code import java util ArrayList import java uti
  • 如何访问 Backbone 视图中的父元素?

    在 Backbone 模型视图中 似乎 this el parent 不起作用 从视图中选择父元素的最佳方法是什么 我正在使用设置 eltagName li 为了景观 默认情况下 Backbone 分配一个空的div到你的视图中 你无法访问
  • 如何使用opencv python解决theta迷宫?

    I have to find shortest path from the center of the maze to the outermost circle I have to solve this problem using open