I'm trying to implement Edge drawing algorithm. I obtained lines of the image, the next step is fitting lines with a given treshold, my problem is that given a matrix of 1 and 0, (1 part of the lines) go through all the pixels and start fitting lines.
The idea is to generate a minimal length initial line segment by the least squares line fitting method, and then extend this line segment by adding more pixels to it. After the detection of a minimal length initial line segment, we should walk over the remaining pixels of the chain and compute the distance of each pixel to the currently fitted line. pixels are added to the current line as long as the pixels are within a certain distance from the current line. we continue adding pixels to the current line segment
until we turn a corner and the direction of the line changes. At that point, we output the current line segment. The remaining pixels of the chain are then processed recursively to extract further line segments.
My problem is that I don't know how to start going over the pixels...and if there is a specific direction I should first take...
I agree with flawr. Without more info like input image and wanted result example is very hard to answer. I guess you got incomplete contours of some object and want to regress/extrapolate the gaps in 2D space. In that case I would:
obtain the visible contour lines
You already have this.
sort the lines by its direction angle
If line(i) endpoints are A(i),B(i) then:
ang(i)=atan2(B(i).y-A(i).y,B(i).x-A(i).x)
merge lines
merge all lines that has:
similar angle
are not too far
have small perpendicular distance (as if were parallel)
the merged line is not intersecting any other line
close the gaps
After merging just find all the contours edge points. These points are connected to just single line. Now you can apply the extrapolation you propose in OP but I would try to connect the closest such points to each other with simple line instead (if the connection do not cross any line).
Related
I have a line and a polygon . The line can be partially inside and partially outside the polygon . The line can intersect the polygon at a single point or at multiple points. The example lines are shown as below
Please refer the picture . For horizontal red colored line I would like to get list of line segments . The desired output is (A-B) (C-D) (E-F) and for vertical line I want to get line segments 1-2 .
I went through how to detemine if a line segment is inside of a polygon? and other questions of stack overflow .
but could not get most optimized algorithm to get a list of line segments inside the polygon.
I went through the following link also
https://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm but my question is there more optimized algorithm to find line segments within the polygon ?
I am answering in the case that no preprocessing is allowed, i.e. you have a single line segment (or a few) to process for a given polygon. The polygon is general (and can be with holes).
Rotate the line to make it horizontal, and simultaneously rotate the polygon vertices.
Then a side of the polygon intersects the supporting line of the segment if the endpoints have ordinates of a different sign. In this case, you can compute the location of the intersection.
The subsegments inside the polygon are made from the ordered intersection points found between the segment endpoints.
I need a good (robust) algorithm for splitting a polygon into two sets(left/right) by a line segment. My polygon representation is simply a list of integer coordinates(ordered clock wise, never self intersecting) and the line segment is represented by a start and end point. The line always starts and ends outside the polygon, i.e. intersects the polygon an even number of times.
Here is an example:
The output of the algorithm should be the two sets(travelling clock wise):
Left: HABCH, FGDEF
Right: HCDGH, BAB, FEF
I can identify the points A-H by iterating the polygon and checking if a polygon segment crosses the line, taking care to respect border cases. I can also determine which side each multi-line belongs to. I cannot though, for the life of me, decide how to string these segment together.
Before you suggest a general purpose clipping library: I am using boost polygon which is very good at clipping polygons against each other, but I haven't found any library which let's you clip a polygon against a line segment and it is not possible in general to turn the line segment into a polygon which I could clip with.
EDIT: I had missed FEF and the fact that a polygon can have parts on both sides of the line segment.
Ok, here is a rather simple recipe of how to arrive at the answer:
Start with the set of intersection points ordered by traveling the contour clockwise:
ABCDEFGH
Sort them according to distance from the start of line:
HCFEDGBA
We also need to remember for each point if it is a left-to-right or right-to-left intersection.
Start with any point. Let's say G. Follow the contour clockwise and add GH
to the current polygon.
Now we need to travel along the line. The
direction depends on which side of the line we are. We are on the
right side, so we need to pick the value to the right of H in the
sorted set: C. Add HC to the current polygon.
Follow the contour clockwise and add CD to the current polygon.
We are on the right side, so we need to pick the value to the right of D in the sorted set: G. Add DG to the current polygon.
We have now reached the
starting point, so let's save the polygon(GHCDG) and remove used
points from the list.
Start over with another point.
For each intersection of the polygon border with the line segment:
Add a new point to the polygon.
Remember the new points in a new-point set.
Add the original polygon to the polygon set.
For each pair of points in the new-point set:
For each polygon in the current polygon set:
If the line segment between the points is completely inside the polygon.
Replace the polygon in the polygon set with two polygons
generated by dividing the original polygon along the line
segment between the points.
For each polygon in the polygon set:
Add it to the Left result set or the Right result set.
(Note this may not be possible.
Consider your example of the segment starting between C and F:
You will end up with a polygon (GABCFG) that touches both
sides of the dividing segment. Is that a Left or a Right?
I've solved something similar once and I gave up trying to be clever.
Run round all the vertices making them into connected line segments,
starting a new segment with a new point every time you intersect the
cutting line.
Find all segments which share an end point and join them back up into one longer one.
Connect all the open ends.
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.
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
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