jjzjj

c++ - 图中的角点和边缘检测

coder 2024-02-12 原文

我目前正在尝试编写一个角和边缘检测方案,它应该能够检测图中的角和边缘。

图数据结构是从一个二维字符数组构建的,它看起来像这个例子的大小是 10 行和 9 列。 (空白填补了其余的缺失,我无法在边界处添加空白......?)

      ...
 ..Y.....
 ..Y   .
  ZYZ.Z.Z
  .Y ....
  .M
  ..

为节点中的每个字符创建一个节点,并将完整的图形存储为 vector<Node> graph .

每个节点都被定义为
struct Node
{
    char character;
    pair<int,int> position;
    bool lock;
    vector<Vertex> adjacent;
};

struct Vertex
{
   Node *current;
   Node *nextTo;

};

所以..我有很多节点,但其中一些在我的用例中是多余的,每个节点都有一个 bool lock => 告诉系统应该忽略这些节点。

我想忽略的节点是那些具有字符 . 的节点, 在 map 中并放置在一个角落位置(节点本身有 2 个邻居(大小 vector 邻居 == 2)),或带有字符 . 的节点这是两个角之间。如果两个角之间出现其他字符,则仅将角设置为锁定。在遍历角的相邻节点时(寻找第二个角),并且一个节点有4个相邻节点,只会将看到的第一个角设置为锁定。

所以..我把它写成一些代码,最终看起来像这样。
 for(auto graph_it = begin(graph); graph_it != end(graph); graph_it++)
    {
        if(graph_it->adjacent.size() == 2 && graph_it->character == '.')
        {
            vector<Node*> trace;
            cout << "corner found " <<"("<< graph_it->position.first <<","<< graph_it->position.second << ")" << endl;
            graph_it->lock = true;

            for (Vertex edge : graph_it->adjacent)
            {
                cout << "Check neighbour direction" << endl;
                int changeX = 0;
                int changeY = 0;

                changeX = graph_it->position.first - edge.nextTo->position.first;
                changeY = graph_it->position.second - edge.nextTo->position.second;

                cout << "neighbour direction is first: " << changeX << changeY << endl;
                auto start_position = edge.nextTo;
                vector<Node*> trace;
                bool endIsCorner = false;
                bool conditionMet = false;
                cout << endl;
                while((start_position->adjacent.size() != 2|| start_position->adjacent.size() != 4) /*&& start_position->character =='.'*/)
                {
                    for(Vertex traversing_edge : start_position->adjacent)
                    {
                        cout <<"position before: " << graph_it->position.first << graph_it->position.second << " now position: "<< start_position->position.first << start_position->position.second <<  " change is: " << (start_position->position.first - traversing_edge.nextTo->position.first) <<  " " << start_position->position.second - traversing_edge.nextTo->position.second  << " character is: " << traversing_edge.nextTo->character << endl;
                        if (traversing_edge.nextTo->adjacent.size() == 2)
                        {
                            cout << "error found case 1" << endl;
                            cout << "position: " << traversing_edge.nextTo->character << traversing_edge.nextTo->position.first << traversing_edge.nextTo->position.second << endl;
                            start_position = traversing_edge.nextTo;
                            start_position->lock =true;
                            trace.push_back(start_position);
                            endIsCorner = true;
                            conditionMet = true;
                            break;
                        }
                        else if(traversing_edge.nextTo->adjacent.size() == 4)
                        {
                            cout << "error found case 2" << endl;
                            cout << "position: " << traversing_edge.nextTo->character << traversing_edge.nextTo->position.first << traversing_edge.nextTo->position.second << endl;
                            conditionMet = true;
                            break;
                        }

                        if (start_position->position.first - traversing_edge.nextTo->position.first  == changeX && start_position->position.second - traversing_edge.nextTo->position.second == changeY)
                        {
                            if (traversing_edge.nextTo->adjacent.size() == 3 )
                            {
                                start_position = traversing_edge.nextTo;
                                cout << "traversed to position: " << start_position->position.first << start_position->position.second <<" character: "<<start_position->character<< endl;
                                trace.push_back(start_position);
                            }

                            if (traversing_edge.nextTo->adjacent.size() == 2)
                            {
                                edge.nextTo->lock = true;
                                start_position = traversing_edge.nextTo;
                                cout << "traversed to position being corner: " << start_position->position.first << start_position->position.second <<" character: "<<start_position->character<< endl;
                                trace.push_back(start_position);
                                endIsCorner = true;
                            }

                            if (traversing_edge.nextTo->adjacent.size() == 4)
                            {
                                cout << "traversed something else: " << start_position->position.first << start_position->position.second <<" character: "<<start_position->character<< endl;
                                start_position = traversing_edge.nextTo;
                            }
                        }
                        cout << endl;
                    }
                    if (conditionMet)
                    {
                        break;/* code */
                    }

                }
                if (endIsCorner == true)
                {
                    for(auto traced: trace)
                    {
                        cout << "Traced for locking position: " <<traced->position.first << traced->position.second << traced->character<< endl;
                        if (traced->character == '.')
                        {
                            cout << "locking position: " <<traced->position.first << traced->position.second << traced->character<< endl;
                            traced->lock = true;
                        }
                    }
                }
                else
                {
                    trace.empty();
                    endIsCorner = false;
                }
                cout<<endl;
            }

        }
        cout << endl;
    }

  cout << "Locks detected" << endl;

当我意识到代码没有像我想要的那样做时,我开始调试它..

所以我看到的第一个奇怪的事情就是这个。它检测为角的第一个节点是位于第 2 行和第 1 列的节点,这是正确的。

然后它尝试沿第一个 nextTo 节点方向的方向遍历,该方向是它下面的节点(第 3 行,第 2 列),这也是一个角,但不知何故它进入了 while 循环?我不明白。它的相邻 vector 大小是 2,调试器也说了,但不知何故在 while 循环中它检测到大小为 2,并正确退出 while 循环并将其设置为锁定的节点......(可能的问题)

当我完成这一切时,我检查了完整的图表,看看应该锁定的东西是否也被锁定了......事实并非如此。
for(auto node :  graph)
{    
    cout << "node position: " <<"(" << node.position.first << "," << node.position.second << ")" << " " << node.character << endl;   
    if (node.locked)
    {
      cout << node.position.first << node.position.second << endl;
    }
}

我得到这个输出
node position: (2,1) .
21
node position: (3,1) .
31
node position: (2,2) .
node position: (3,2) .
node position: (4,2) Z
node position: (5,2) .
52
node position: (6,2) .
node position: (7,2) .
72
node position: (2,3) Y
node position: (3,3) Y
node position: (4,3) Y
node position: (5,3) Y
node position: (6,3) M
node position: (7,3) .
73
node position: (2,4) .
24
node position: (4,4) Z
node position: (2,5) .
25
node position: (4,5) .
node position: (5,5) .
55
node position: (1,6) .
16
node position: (2,6) .
node position: (4,6) Z
node position: (5,6) .
node position: (1,7) .
node position: (2,7) .
node position: (3,7) .
37
node position: (4,7) .
node position: (5,7) .
57
node position: (1,8) .
18
node position: (2,8) .
28
node position: (4,8) Z
48
node position: (5,8) .
58

这意味着它不仅锁定了我希望它锁定的那些(我放置在指定位置的字符 .),而且锁定了我不想锁定的那些(除 . 之外的字符)。
(5,2) should not be locked
(2,4) should not be locked
(2,5) should not be locked
(1,7) should be locked
(4,7) should be locked

这里出了什么问题..我很确定它一定与我在调试器中发现的问题有关,但我不明白为什么会发生这种情况?

- -更新 -

我似乎发现了另一个问题,如此处所示。
corner found (7,2)
Check neighbour direction
neighbour direction is first: 10

position before:  72 now position: 62 change is: 1 0 Element is: .
traversed in right direction . 
traversed to position: 52 Element: .

position before:  72   now position: 52 change is: -2 0 Element is: .
error found case 1
position: .72

这是从while循环输出的。
while((start_position->adjacent.size() != 2|| start_position->adjacent.size() != 4) /*&& start_position->character =='.'*/)
                    {
                        for(Vertex traversing_edge : start_position->adjacent)
                        { .. }

我改变了 start_position 的值内for循环,循环对此有何 react ?.. 在我看来,它应该从头开始,从头开始,而不是继续迭代第一个 start_position vector 。

应该是 while取而代之的是 for ?
Start_position从放置在 (7,2) 的节点开始,然后遍历到右侧的节点 (6,2),这成为新的 start_position .然后它再次向右遍历 (5,2) 和 start_position成为那个节点。但是变量traversing_edge成为放置在 (7,2) 处的节点,从而错误地结束.. traversing_edge成为一个不可能的值,因为与放置在 (5,2) 处的节点相邻的节点只有邻居 (4,2),(6,2) ,(5,3)...所以这里肯定有问题..

- 更新 -
      DDD
 D.Y....D
 D.Y   .
  ZYZ.Z.Z
  .Y DDDD
  .M
  DD

没有节点具有大小为 1 的相邻 vector ,还会创建带有空白字符的节点。 D显示应锁定哪些节点。

--- Lamda 更新 ---

它是一个推箱子图,M 是人,Y 是菱形,Z 是目标。这个想法是 M 将 Y 推向某个方向,但为了防止将菱形移动到无法再次检索的位置,该方案是否会对图形进行预处理,从而忽略这些位置。

最佳答案

所以..我终于设法解决了我的问题,通过重写它..

新版本以不同的方式工作,对于人眼来说似乎更有条理,但与上面发布的版本相比更慢。

我确定我也在上面的代码中发现了错误。
我过度使用基于范围的 for 循环,使得无法在对象的成员值上插入一个值,调试器向我展示了这个值。

解决这个问题和其他一些事情会使它起作用。

我要感谢大家试图帮助解决我的问题,非常感谢您的帮助。我不认为人们会对这么长的帖子使用react,但同时我觉得我必须提供所有给定的信息,这样如果有人敢于查看它,他们就有合理的机会理解它。

谢谢 :)

关于c++ - 图中的角点和边缘检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33826478/

有关c++ - 图中的角点和边缘检测的更多相关文章

  1. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  3. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  4. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  5. arrays - Ruby 数组 += vs 推送 - 2

    我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“

  6. += 的 Ruby 方法 - 2

    有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=

  7. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  8. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

  9. ruby - Sinatra + Heroku + Datamapper 使用 dm-sqlite-adapter 部署问题 - 2

    出于某种原因,heroku尝试要求dm-sqlite-adapter,即使它应该在这里使用Postgres。请注意,这发生在我打开任何URL时-而不是在gitpush本身期间。我构建了一个默认的Facebook应用程序。gem文件:source:gemcuttergem"foreman"gem"sinatra"gem"mogli"gem"json"gem"httparty"gem"thin"gem"data_mapper"gem"heroku"group:productiondogem"pg"gem"dm-postgres-adapter"endgroup:development,:t

  10. ruby - Ruby 中字符串运算符 + 和 << 的区别 - 2

    我是Ruby和这个网站的新手。下面两个函数是不同的,一个在函数外修改变量,一个不修改。defm1(x)x我想确保我理解正确-当调用m1时,对str的引用被复制并传递给将其视为x的函数。运算符当调用m2时,对str的引用被复制并传递给将其视为x的函数。运算符+创建一个新字符串,赋值x=x+"4"只是将x重定向到新字符串,而原始str变量保持不变。对吧?谢谢 最佳答案 String#+::str+other_str→new_strConcatenation—ReturnsanewStringcontainingother_strconc

随机推荐