我正在尝试合并包含由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”内部的向量表示。(我没有把它们都画出来)
我真的不知道如何解决这个问题。有没有人对如何解决这个问题有任何想法?
编辑
为了使我的意图更明显,我添加了以下图像:
. 我正在尝试对线段进行分组以识别车道。
更新
通过调整确定线条片段是否属于一起的函数,可以明显改善结果。
在这个问题中,设置很重要。我假设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)
(向下弯曲,向上弯曲)您想要连接成一条线而不是两条线。