- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
最佳答案
您可以将图像中的每个白色像素视为无向加权图的节点。每个像素(节点)都连接到它的白色邻居。连接两个节点的边的权重在水平和垂直方向上均为 1,在对角线方向上为 sqrt(2)
(或简称为 1.414
)。
然后,因为你知道起点和终点,你可以运行 Dijkstra algorithm找到起点和终点之间的最短路径。
我用了Rosetta Code Dijkstra算法的实现:
这是代码(不是很完善,但可以工作)。代码是用 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;
}
关于python - 如何使用 opencv python 解决 theta 迷宫?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41167604/
假设您已经用 Python 编写了一个 m x n 矩阵。矩阵之外的值是不可能的。假设你是在矩阵中移动的东西(就像在迷宫中)并且你不能跨越边界。当您在迷宫中移动时,您会不断考虑您的选择,您可以走哪条路
我正在实现随机鼠标算法来探索迷宫。一段时间后,算法陷入无限循环。我调试了一下,它似乎在一条 channel 之间来回卡住了。 请看一下我的算法实现。 这是我的代码:方向是相对于机器人的。 public
我有一个用 java 编写的工作 ascii 迷宫解算器,使用 char 数组,它将正确路径的每个位置设置为前一个位置 + 1。我使用以下代码来从中获取正确路径,但是它仅适用于垂直运动。任何有关此事的
我有一个生成随机迷宫的程序。迷宫中会显示一个红点,并且迷宫中的每个方 block 都会闪烁红点。迷宫中的所有 block 都是 == 1,如果红点穿过该 block ,它就会递增++。红点朝最小数字的
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我创建了一个从文本文件上传的迷宫,该迷宫当前在运行时完全可见且功能正常。但是,我只想将播放的路线显示为可见,因此仅使起始位置和周围的墙壁/地板在开始时可见。有人知道该怎么做吗? 以下是 Board 类
起初我觉得这很容易,但是当我开始做的时候,我不知道如何继续下去了。我的想法是使用面板,然后绘制粗线,但是绘制墙壁并使我的角色不会超出这些墙壁的正确方法是什么?我无法想象我怎么可能做到这一点。这是一个迷
我从一个文件中得到了一个迷宫,我尝试使用一个程序编写一个类Exercise4,该程序将这样的迷宫文件读入二维 boolean 数组。然后在控制台上显示该数组,每一行一行。使用空白符号和 # 符号表示数
如何通过光栅图像数据找到非线性路径?例如,最低成本算法?起点和终点已知,并给出如下: 起点 = (0,0) 终点 = (12,-5) 例如,通过(灰度)光栅图像提取蜿蜒河流的近似路径。 # fake
在我的游戏中,玩家在迷宫中导航。我不知道如何与墙壁进行正确的碰撞检测。停留在某个区域很容易进行碰撞检测: if (x > rightWallX - playerWidth) x = rightWall
基本上,我一直在按照 Java 教程制作一个基本的迷宫游戏,其中我生成一个随机迷宫,并将其保存到文件中,然后使用 Jpanel 将其打印出来,但是在编译时我不断收到此错误。 Exception in
注意:这是 MSVC,C++17 问题。 免责声明:我知道有人尝试过,是的,我试图找到相关的 SO 答案。 我可以编码 UDL , 以实现将数字文字转换为 std::array,在编译时: /
我目前正在开发一个随机迷宫生成器,它将迷宫存储在一个名为 grid 的二维数组中。这将在稍后用于生成一个真正的 3D 迷宫,用户随后可以穿过该迷宫。 在做了一些研究之后,我尝试使用递归除法算法创建这个
题目地址:https://leetcode-cn.com/problems/the-maze-ii/ 题目描述 There is a ball in a maze with empty space
我正在尝试用 python 编写脚本来解决一种具有多个起点和多个终点的迷宫。正确的路径是从起点沿着直线前进。 例如一个有 4 条路径的迷宫: 起初我想使用左手/右手规则,但由于迷宫的特点,它没有太大意
我正在尝试在 opengl 中创建一个简单的 3D 迷宫。我最初的想法是有一个立方体网格,每个立方体的一些面是透明的(用于走廊)。但是,我在想出一种有效执行此操作的方法时遇到了一些麻烦。我不想为我的迷
我的 DFS 算法在解中缺少节点时遇到问题(检查图片)。每次我的算法遇到死胡同时都会发生这种情况:节点从堆栈中弹出并返回,直到找到可用的移动,并且再也不会重新包含在内。有没有一种简单的方法可以在不重新
所以我正在用 Java 构建 pacman 游戏来自学游戏编程。 我有一个基本的游戏窗口,其中绘制了吃 bean Sprite 和幽灵 Sprite ,吃 bean 使用箭头键移动,不会超出窗口的墙壁
我使用的代码只是取自一个示例,它确实为我的场景建了一堵墙: /** This loop builds a wall out of individual bricks. */ public vo
我正在从事一个包含这些条件的学校元素: 只使用 JS、HTML5 和 CSS 制作迷宫。 在 Angular 色周围制作 torch 效果。你不能穿墙照明。 我开始使用 Canvas 制作这款游戏
我是一名优秀的程序员,十分优秀!