Ask Your Question

Revision history [back]

click to hide/show revision 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 angle between lines should be quite small (less 3 degrees, for example). Use the dot product to calculate angle's cosine.
  • 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

image description