Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用opencv python解决θ迷宫?_Python_Opencv_Numpy_Maze - Fatal编程技术网

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

如何使用opencv python解决θ迷宫?,python,opencv,numpy,maze,Python,Opencv,Numpy,Maze,我必须找到从迷宫中心到最外圆的最短路径。我必须使用opencv和python解决这个问题我退出了! 可以将图像中的每个白色像素视为无向加权图的一个节点。每个像素(节点)都连接到它的白色邻居。连接两个节点的边的重量在水平和垂直方向为1,在对角线方向为sqrt(2)(或简称1.414) 然后,因为您知道起点和终点,所以可以运行以找到起点和终点之间的最短路径 我使用了Dijkstra算法的实现: #include <opencv2/opencv.hpp> #include <i

我必须找到从迷宫中心到最外圆的最短路径。我必须使用opencv和python解决这个问题

我退出了!

可以将图像中的每个白色像素视为无向加权图的一个节点。每个像素(节点)都连接到它的白色邻居。连接两个节点的边的重量在水平和垂直方向为1,在对角线方向为

sqrt(2)
(或简称
1.414

然后,因为您知道起点和终点,所以可以运行以找到起点和终点之间的最短路径

我使用了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;
}
这是代码(不是真正的抛光,但工作)。代码是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;
}
#包括
#包括
#包括
#包括
#包括
#包括//用于数字限制
#包括
#包括
#包括//对
#包括
#包括
使用名称空间cv;
使用名称空间std;
typedef int vertex_t;
typedef双倍重量;
常量重量最大重量=标准::数值限制::无穷大();
结构邻居{
顶点目标;
重量;
邻居(顶点参数目标、权重参数权重)
:target(arg_target),weight(arg_weight){}
布尔运算符==(常量邻居和其他)常量{
返回target==other.target;
}
};
typedef std::向量邻接列表;
void DijkstraComputePaths(顶点源,
常量邻接列表和邻接列表,
标准::向量和最小距离,
标准::向量和上一个)
{
int n=邻接列表.size();
最小距离。清除();
最小距离。调整大小(n,最大重量);
最小距离[源]=0;
previous.clear();
上一个。调整大小(n,-1);
std::设置顶点_队列;
vertex_queue.insert(std::make_pair(最小距离[源],源));
而(!vertex_queue.empty())
{
weight\u t dist=vertex\u queue.begin()->first;
vertex\u t u=vertex\u队列。begin()->秒;
vertex_queue.erase(vertex_queue.begin());
//访问美国的每一个边缘
常数std::向量和邻居=邻接列表[u];
for(std::vector::const_iterator neighbor_iter=neighbors.begin();
邻居!=邻居。结束();
邻居(iter++)
{
顶点=相邻节点->目标;
重量=邻居的重量->重量;
重量-距离-距离=距离+重量;
if(从距离到最小距离[v]){
vertex_queue.erase(标准::生成_对(最小距离[v],v));
最小距离[v]=从距离到距离;
前[v]=u;
插入(std::make_对(最小距离[v],v));
}
}
}
}
std::list DijkstraGetShortestPathTo(
顶点(顶点,常数标准::向量和上一个)
{
std::列表路径;
对于(;顶点!=-1;顶点=上一个[顶点])
路径。向前推(顶点);
返回路径;
}
结构lessPoints
{
布尔运算符()(常量点和左侧、常量点和右侧)常量{
返回(lhs.x!=rhs.x)?(lhs.x200;
向量pts;
findNonZero(屏蔽,pts);
map mp;
对于(大小i=0;i
您可以使用
skimage.graph
轻松实现它

import skimage.graph
### give start (y1,x1) and end (y2,x2) and the binary maze image as input
def shortest_path(start,end,binary):
    costs=np.where(binary,1,1000)
    path, cost = skimage.graph.route_through_array(
        costs, start=start, end=end, fully_connected=True)
    return path,cost

祝你好运。