如果包含重复元素,如何合并多个向量?

Ath*_*ulf 5 c++ opencv vector

我正在尝试合并包含由houghLinesP属于一起提取的行的向量。

到目前为止,我有一个包含线段的 Vector:

vector<Vec4i> lines;
Run Code Online (Sandbox Code Playgroud)

我还有一个算法可以检查线段是否足够相似以被认为属于其他线段(目前仅基于距离和角度):

    vector<vector<Vec4i>> lineClusters;

    for(Vec4i line1: sortedLines){
        Point l1o = Point(line1[0], line1[1]);
        Point l1d = Point(line1[2], line1[3]);
        vector<Vec4i> cluster;
        for(Vec4i line2: sortedLines){
            Point l2o = Point(line2[0], line2[1]);
            Point l2d = Point(line2[2], line2[3]);
            if ((getDistance(l1o, l1d, l2o, l2d) <= 20) and
                (abs(angle(l1o, l1d) - angle(l2o, l2d)) <= 10)) {
                cluster.push_back(line2);
            }
        }
        lineClusters.push_back(cluster);
    }
Run Code Online (Sandbox Code Playgroud)

现在 VectorlineClusters为每个线段包含一个属于该线段的线段向量。

我现在面临的问题是如何合并这些向量。基本上我想合并包含至少一个重复线段的所有向量,以便最后只剩下几个集群。

为了说明,我创建了一个小图像: 可能的线段

在此图像中发现了黑色线段。我想将它们合并成行。我绘制的圆圈表示可能确定属于一起的线段,并由“lineClusters”内部的向量表示。(我没有把它们都画出来)

我真的不知道如何解决这个问题。有没有人对如何解决这个问题有任何想法?

编辑 为了使我的意图更明显,我添加了以下图像: 在此处输入图片说明. 我正在尝试对线段进行分组以识别车道。

更新

遵循 Braaedy 提供的建议会导致以下结果: 在此处输入图片说明

通过调整确定线条片段是否属于一起的函数,可以明显改善结果。

Bra*_*edy 3

在这个问题中,设置很重要。我假设vec4i是一对描述直线段的点(例如(a,b,c,d)=>(x1,y1)->(x2,y2))

构造你的vec4i这样 (x1 < x2) || (x1 == x2 && y1 < y2)。

这允许您对所有线段进行一次从左到右的遍历。创建一个新的构造,将其命名为 Line:

struct Line {
  std::vector<vec4i> segs;
  const vec2i &getEnd() const { *segs.rbegin(); }
};
Run Code Online (Sandbox Code Playgroud)

定义一些新函数,可以确定两个端点是否“足够接近”以进行连接。创建一个 s 列表Line

通用算法伪代码(其中 seg[0] 或 seg[1] 是段端点):

for (seg : Segments) {
  for (line : Lines) {
    if (close(line.getEnd()[1], seg[0])) {
      line.addSegment(seg)
      // break to next *segment*, a segment can only be added to one line.
    }
  }
  // reaching here means we didn't make attach the segment; start a new line.
  Lines.add(Line(seg))
}
Run Code Online (Sandbox Code Playgroud)

这将连接所有从左到右的段。如果有像这样的更复杂的线,您将需要第二遍来连接知道线两端的线:

      \
       \
--------
Run Code Online (Sandbox Code Playgroud)

(水平、对角线)或像图表末尾那样的后曲线

   \
    \
     |
    /
   /
Run Code Online (Sandbox Code Playgroud)

(向下弯曲,向上弯曲)您想要连接成一条线而不是两条线。