代码之家  ›  专栏  ›  技术社区  ›  user3919259

合并相邻平行线

  •  0
  • user3919259  · 技术社区  · 11 年前

    有一个图像只有垂直线和水平线。但有些线条是相同的或彼此接近的,但它们只应合并为一条线条。我还写了一个循环来在新列表中添加行,速度很慢。所以我想知道是否有一些有效的方法可以将这些相邻的线组合成一条线。

    以下是代码:

    for (int i = 0; i < RecoverLine_list.Count; i++) {
            for (int j = 0; j < RecoverLine_list.Count; j++) {
                for (int m = 0; m < RecoverLine_list.Count; m++) {
    
                    if (RecoverLine_list[i] != RecoverLine_list[j] 
                     && RecoverLine_list[i] != RecoverLine_list[m] 
                     && RecoverLine_list[j] != RecoverLine_list[m]) {
    
                        if (RecoverLine_list[i].orientation == 0 
                         && RecoverLine_list[j].orientation == 0 
                         && RecoverLine_list[m].orientation == 0) {
    
                            if (Math.Abs(RecoverLine_list[i].P1.Y - RecoverLine_list[j].P1.Y) < 3 
                             && Math.Abs(RecoverLine_list[i].P1.Y - RecoverLine_list[m].P1.Y) < 3 
                             && Math.Abs(RecoverLine_list[j].P1.Y - RecoverLine_list[m].P1.Y) < 3) {
                                // define RecoverLine_list[i] as grid line
                                GridLine_list.Add(RecoverLine_list[i]);
                            }
                        }
                    }
                }
            }
        }
    
    1 回复  |  直到 11 年前
        1
  •  0
  •   firda    11 年前

    (重写) 因此,假设你想以某种方式过滤“相似”的水平线和垂直线,并希望代码和“相似”应具备的良好条件,那么我的想法如下:

    第一次拆分水平线和垂直线:

    List<Line> vert = new List<Line>();
    List<Line> horiz = new List<Line>();
    foreach(Line ln in RecoverLine_list)
        if(ln.orientation == 0) horiz.Add(ln);
        else vert.Add(ln);
    horiz.Sort(x, y => x.P1.Y.CompareTo(y.P1.Y));
    vert.Sort(x, y => x.P1.X.CompareTo(y.P1.X));
    

    或者类似的东西(不完全确定你的方向是什么,我只是猜测包括使用lambdas进行排序的编码)。

    然后,您可以在一次扫描中搜索线条,以提取好的线条:

    List<Line> filtered = new List<Line>();
    for(int i = 0; i < horiz.Count; i++) {
        filtered.Add(ln); // always add, we can skip next:
        if(i+1 >= horiz.Count) break;
        if(Math.Abs(horiz[i].P1.Y - horiz[i+1].P1.Y) <= 3)
        && Math.Abs(horiz[i].P1.X - horiz[i+1].P1.X) <= 3)
        && Math.Abs(horiz[i].P2.X - horiz[i+1].P2.X) <= 3))
            i++; // skip this line for being similar
    }
    

    但这不是最终的解决方案,因为我们可以在一个坐标系中有彼此接近的线,但在另一个坐标中没有。所以我们需要添加内部循环:

    for(int i = 0; i < horiz.Count-1; i++) {
        for(int j = i+1; j < horiz.Count; j++) {
            if((horiz[j].P1.Y - horiz[i].P1.Y) > 3)
               break; // this one is too far, all next will be
            if(Math.Abs(horiz[i].P1.Y - horiz[j].P1.Y) <= 3)
            && Math.Abs(horiz[i].P1.X - horiz[j].P1.X) <= 3)
            && Math.Abs(horiz[i].P2.X - horiz[j].P2.X) <= 3))
                horiz.RemoveAt(j--); // skip this line for being similar
    }}
    

    明白了吗?垂直线也是如此。