matching line segments - robust and fast way - c++

I have 2D line segments extracted from a single image data and would like to match with 3D line segments extracted from other source. for that, first I would like to project a 3D line segment to the image space using co-linearity equation (I know exterior orientation parameters). AS both line segments are in same coordinate system now I would like to find the best matching line segment to that line.
I am looking for a fast and robust algorithm to match corresponding line segments in order to update my 3D line segments later.
If any one have an idea on this, please give some suggestions. thanks in advance.

You're looking at a problem similar to line segment intersection. So unsuprisingly, it's solutions are probably similar as well.
The straightforward approach would be to compare each 2D segment to each 3D segment, best match is the one that most closely corresponds to the predicted length and position when compared to the actual. The actual being the 2D segments. That's something like O(AB), where A is the number of 2D segments and B is the number of 3D segments.
You can speed up the method somewhat by sorting the 2D segments lexicographically, then use the same kind of algorithm I asked about in this question to obtain all line segments whose x values are within a certain amount to the expected x value of one or both of the line segments end point*. In the worst case, you could still run into O(AB), but the average time should be closer to O(B log A). Although, it's not clear as to if you can use this method based on what you've said, so this paragraph should be considered more of an outline.
Faster than O(B log A) or O(A log B) is likely to require this to be a well researched problem.
You can probably get away with 1 end point, if you lexicographically sort the 2D endpoints.

Related

Calculate the Signed Distance Transform of arbitrary polygon

How would you calculate the Signed Distance Function of a polygon, described by an arbitrary set of points. The polygon could be concave or convex. Assume that the points are stored in a std::vector with counter-clockwise winding.
Update
Let me be more specific. This is not a sampled function on a grid. I need to be able to detect a sign change along an arbitrary line segment drawn through (not necessarily intersecting) the polygon, without checking individual intersections with each line segment. The problem is, I might have thousands of line segments.
Can anyone think of an efficient way of doing this?
If I can parametrically express the SDF, I can calculate a derivative to accomplish this.
Bad news: in the worst case, a line segment can intersect the polygon in N points, and this can arise for all M line segments. So in the worst case, exhaustive comparison of the segments vs. the sides is unavoidable. This goes in favor of the brute-force approach.
Fortunately, output-sensitive solutions are known for the problem of the intersection of N line segments, using the sweepline approach. The complexity can be lowered to O((N+K) log N) or O(N log N + K) where K is the number of intersections found.
Firstly rotate all the points so the line is parallel with the x axis. Then translate so that the line is the x axis. Then as a test integrate. The area under a straight line x0y0 x1y1 is pretty simple to calculate. You can sum all the expressions to get the indefinite integral, or signed area, which should be independent of axis (because points under the curve subtract). Now to answer the specific question, sort in x to enable you to find the point value at a given x. So create two "events", section start, and section "end" with a pointer or reference back to the start event. Then to get the distance transform at any point, we calculate all the events the cross the x of interest. If you want piecewise functions to each event interval, that's actually slightly easier as you can pass through the queue from start to end.

Polygon Detection from a Set of Lines?

I have a set of connected, intersecting line segments. I want to detect all polygons that result from the intersection of these line segments, as follows:
I found a paper that presents an algorithm for solving this problem, but I'm not really a computer science person so I wasn't able to understand it. Here's a link to the paper. At this moment, my plan is to 1) find all intersections, and 2) somehow use these intersections to identify the polygons. I'm able to solve (1) through brute force, but (2) is a bit trickier. I'd prefer a solution in R or C++, but any language will do.
Assuming you have your line segments always as a closed polygonal chain and you have them in some sort of edge list. And, as you said, you have the intersection points already computed (brute force means O(n^2) time, in this case that is optimal as the line segments can intersect n^2 times).
You can insert your intersection points from (1) into this list splitting the intersecting line segments, mark them as intersection points and reference to all intersecting line segments in this point. Furthermore, on every line segment two polygons are incident, thus add respective reference fields to every edge. Then just take the leftmost vertex in you input and walk along the edge list. Add to every edge that is traversed a reference to its left incident polygon (in this case) polygon number one. If you reach an intersection point, put it on some sort of stack for later recovery. Now analyse that point and continue walking on the leftmost path (between the line segment on which you reached the intersection point and all outgoing segments). At some point you reach your starting point and you have the first simple polygon closed.
Now take the first intersection point from the stack. There must be an even number of line segments that start/end there. Find a line segment that has at most one incident polygon referenced (yet) and use it as as starting segment for polygon number two. You can walk along its chain in the same manner as before. (If you reference a line segment`s right incident polygon, take the rightmost turn on an intersection point.) When your stack ist empty your are done.
Edit: After I looked one more time for a solution I found this implementation from Dan Sunday. I assume that is more useful as it is also already implemented.
Alfredo Ferreira developed c++ code for detecting polygons from a set of overlapping lines. You can find the code at his page here: http://3dorus.ist.utl.pt/tools/PolygonDetector.html
Hope this Helps
I just published my implementation which is extremely fast after trying the algo from the paper.
The basic idea is to remove the detected cycles and redo the search (remove the “ears” of the detected cycle).
I am also unsing just the line segments that have connected points to the graph. The overlapping are removed in two steps: by using the area formula, which is pretty much exact and then approximate the intersection points difference in a specific range.
https://github.com/realuptime/PolyDetector

RANSAC line3d fitting by 3d line segments

I am having many 3d line segments. some of them are nearly parallel
and some are oriented in to different direction. I want to avoid
outliers and to get the best line 3d to represent the given 3d line
segments.
I am bit confused how RANSAC method apply for this case...
should i find a random line first or should i consider this as a given 3d point problem.?
can anyone post me the stucture to be followed when implenting this in c++. thanks
RANSAC is a good tool to fit data to a model. If you had a single 3D line in a collection of segments, by running RANSAC and selecting the line that maximized the amount of inliers would be enough. However, since you have many lines in the collection, you should try a different approach (even a non-RANSAC one, as I tell you later).
For example, you can run first RANSAC trying to find the line that matches as many segments as possible. After finding that line, remove the inlier segments from the collection and run RANSAC again.
To create a line, you only need a segment, so building the line model is quite easy.
To decide on whether a segment fits a line, you may compute the angle between both with the dot product (the closer to 0 the better) and the distance from the middle point of the segment to the line.
Also note that you can filter out very small segments at as first step. You could save some iterations later and avoid noisy results.
I can think of a Hough transform approach as well. Since you can create a line from each segment, you can get the parameters of its line (normal or directional vector and distance to origin), quantize them to some acceptable bin-size and add a vote to those parameters in a matrix. Finally, your lines lie in the peaks of the vote matrix.

How to compute overlap between nearly parallel two line segments

I have equally oriented (but not exactly parallel) 2D line segments. I want to find out a line segment which is given maximum overlap with a given line segment.
I think scalars can be used to compute this effectively, but my geometry is too poor to figure out this.
for example, in the below figure; dark line is assumed as the given line and red highlighted line segment is given the maximum coverage (or longest overlap, not sure whether my terminology is correct) when compared to other line segments.
My objective is to find the best line which represents the dark line
from the other line segment sets.
what i want to find is any line which has maximum coverage to a given line. that mean, i want to avoid line segments whose starts and ends are out of the ends of the given line segment. also, when many lines give their maximum coverage for the given line, then i want to avoid shorter line and need a long one. idea is to find another line which we can consider instead of that given line segment
helps are highly appreciated as later i want to implement this in programming environment.
thanks
example 1
example2
to say what i meant 'coverage', i will say
in above figure: the projected blue line completely lay within the dark black line. but it is too short. But, large portion of the red line (projected line) lay within the black line though some part of the red line go out. green line is completely out of the black line. so, i can say red line give maximum coverage with black line..(does my idea correct?)
Project ends of a candidate segment onto the target segment.
Calculate distance between projections.
[optionally] Multiply by cos of angle between the segments.
Note about #1: in this context projection on a segment means the closest point lying on that segment. One of ways is:
project a point on infinite line going through the segment
if the projection is inside of the segment - take it
if the projection is outside of the segment - take the closest segment end
I don't know your question are on graphics processing or computational functions.
But for graphics, this question belongs to computer vision subject, what you want is maybe the Hough Line Transform algorithm.
However, if you question is simpler than this, what you want maybe the SAD algorithm

How to limit search space using 2D rectangular buffer along a 2d line segment

I have 2D line segments extracted from an image. So i know end point coordinates of them. also, i have some reference 2d line segments. Both line segments are now in vector form. comparing to reference and extracted lines,I have huge amount of extracted lines segments.
What i want to do is to find conjugate line segment for each reference line from my extraction. that is I want to match line segments. But, to reduce the search area i wish to limit it in such a way that by defining a buffer zone around a reference line segment.
(1) My first question is how can i implement this buffer case with c++ as i am lacking with geometric theories.
Note: I dont want to use a bounding box and looking for a rectangular buffer which orient along the reference line.
(2) my second question is, if i know the rectangular buffer limits, then which type of concept should i use to avoid unnecessary searches of line segments.
Actually, I am looking a geometric base method
please do not think this as home work and i am really struggling because of my poor mathematics.
thanks in advance.
Please look at the example. if i take bounding box (blue box) unnecessary lines come, if it is a buffer rectangle (red), which is oriented to main reference line (dark black) few lines come.
black line is - reference line and dashed lines are image based extracted lines
First suggestion
Take a look at KD-Tree and R-Tree.
They are for partitioning space to reduce some calculations. And there is many implementations as class library for them, same as libkdtree. I personally used KD-Tree before to reduce comparisons of finding nearest neighborhoods in a 2D space, it wasn't simple but it was effective.
How to best store lines in a kd-tree
enter link description here
Second suggestion
Instead of thinking about oriented rectangle (To testing if a point is inside of it or not), you can think about distance of a point from line segment.
Check if two start-point and end-point of an extracted segment are near enough to reference segment or not, gray area is a good approximate of your oriented rectangle.
Those segments in the gray capsule are suitable to match to reference segment, and you can ignore other segments. (If two points of an extracted segment are in gray area it can be good candidate to match to the reference segment. Otherwise you can ignore that segment.)
A segment has two points as start-point and end-point, and each point has two components as X and Y.
Segment ref(r.start, r.end);
foreach(seg : extracted segments)
{
if (DistancePointSegment(seg.start, ref)<D &&
DistancePointSegment(seg.end , ref)<D )
{
// Mark seg as a search candidate
}
}
To check distance of a point from a segment read this Shortest distance between a point and a line segment