1 | initial version |
@sturkmen I have solved this issue following.
The first I have using FastLineDetector/LineSegmentDetector
Above two class has Implementation of merging line segments by TAVARES and PADILHA
Ptr<FastLineDetector> detector;
vector<Vec4i> lines;
detector->detect(grayscale, lines);
Remove small lie if we want.
vector<Vec4i> linesSmall;
copy_if (lines.begin(), lines.end(), back_inserter(linesWithoutSmall), [](Vec4f line){
float length = sqrtf((Point 1, Point 2);
return length > 50;// replace we want to filter.
});
Split your lines using cv::partition. You need to specify a good predicate function. It really depends on the lines which you extract from an image, but I think it should check the following conditions:
The distance between the centers of segments should be less than half of the maximum length of two segments.
vector<int> labels; int equilavence = partition(linesSmall, labels, {
Extend lines by percentage of line width
float len1 = calculator length of the line using hypot (have in cmath)
float len2 = calculator length of the line using hypot (have in cmath)
Append line if needed using fit line using least-squares problems.
Vec2f lineAfetFit = solve(...)
Vec4i el1 = append line 1;
Vec4i el2 = append line 2;
reject the lines that have wide difference in angles
float a1 = atan(solve(...));
float a2 = atan(solve(...));
if(fabs(a1 - a2) > maxAngleDiff * M_PI / 180.0){
return false;
}
Finds coordinates of perpendicular lines with length d in both line points https://math.stackexchange.com/a/2043065/183923
vector<point2i> boundingLine; after calculating the window around the extended line at least one point needs to inside extended bounding rectangle of other lines.
using https://docs.opencv.org/3.4.3/d3/dc0/group__imgproc__shape.html#ga1a539e8db2135af2566103705d7a5722
pointPolygonTest(boundingLine, ,...,...);
});
Draw original detected lines
for (int i = 0; i < linesSmall.size(); i++){
Vec4i& line = linesSmall[i];
line(img,
Point(line[0], line[1]),
Point(line[2], line[3]), colors[labels[i]], 2);
}
Build point out of each equivalence classes vector<vector<point2i>> pointOut(equilavence);
for (int i = 0; i < linesSmall.size(); i++){
Vec4i& line = linesSmall[i];
pointOut[labels[i]].push_back(Point2i(line[0], line[1]));
pointOut[labels[i]].push_back(Point2i(line[2], line[3]));
}
The fit line to each equivalence class point out Using fitLine() pointOut
vector<Vec4i> fittedLines = fitLine(...);
Finished to draw lines after fitting
for(Vec4i line: fittedLines){
line();
}
Result