Determine Orientation of a Sketched Arrow with OpenCV - c++

I've got a bunch of arrow sketches and I want to determine their orientation, the starting point coordinates, and the ending point coordinates.
I'm using goodFeaturesToTrack but I'm really clueless as to what to do next.
This is what I've got
There is no restriction on the shape of the arrows, they can be as windy as you want them or they could be composed of straight lines and right angles.
I'd really appreciate any ideas because I really am lost. The project is about transforming a sketch of an Finite State Machine into a VHDL code and I've got the circles and characters covered so this is the last component but I have no idea how to approach the problem.

Instead of using goodFeaturesToTrack you can use HoughLines which will give you all lines in an image so I suggest that you do some segmentation first to get each arrow separately. HoughLines gives you all lines in polar coordinates which is perfect for you case as you can know the orientation of the lines. You can read more here: https://docs.opencv.org/3.4.0/d9/db0/tutorial_hough_lines.html
For straight lines your task is easy you need to find 3 line segments that intersect in one point (http://answers.opencv.org/question/92164/how-to-find-coordinates-of-intersection-of-lines-after-using-houghlines/). This will be the end point of your arrow, you can find the start point using the equation of the middle line.
For curved lines, it is a bit more tricky as you may get several hough lines for the curved segment or none at all. So in this case I suggest you get the intersection of the the 2 lines as your end point and then use goodFeaturesToTrack then starting from the closest point to your end point start moving to the next closer until you reach the end and pick that as the starting point.
I do not know if this would be the best solution and I did not try it myself but I hope it helps you or give you some direction.

Related

Project a line segment onto a mesh

What are the graphic/mathematical algorithms I have to look for in order to achieve the red line in the following image?
Explaining it better: I need to plot two points on the mesh and then generate a straight line segment from one point to the next. This line segment would be formed by new vertices created on every single edge in its way.
I'm currently working with CGAL and Libigl, but none of them seem to have the solution. I have tried CGAL::Surface_mesh_shortest_path but it adds too much overhead (code runs very slowly) and the line would not be guaranteed to be straight depending on the mesh deformation.
Ignoring whatever you mean as "straight", here is one simple algorithm I can think of that would produce images to the one similar shown in the question. There is no guarantee of what is produced being the shortest path. I'm just spitballing here with no knowledge on the topic, there are probably better ways.
Pick 4 variables:
The starting point
The ending point
The line's normal
A marching constant
Let's calculate a few constants from the variables:
Direction = ending point - starting point
Increment vector = normalize(Direction) * marching constant.
Begin from the starting point and march towards your ending point by some constant, checking above and below your current position for where you are on the mesh. You use the line's normal to understand the "up" and "down" directions in order to perform intersection tests.
On each intersection test, if you do not intersect for both the up and down directions, then the normal you chose will not work for the given two points and mesh, and you'll have to try a different normal. If you do end up intersecting from one of the directions, you will need to add 2 points to your final line: a point on the calculated direction line closest to the start that lies on the triangle, and a point on the calculated direction line farthest from the start that lies on the triangle. If there's both an intersection on the up and down directions, choose the up direction to work with.

C++ How to calculate an arc between two 3D points

I read through the forum and as I am sure this question has been asked before, but I couldn't really find what I was looking for.
My problem is the following:
I have an AI-Character moving along a spline. Should that path be blocked, the character should move in an arc around it and then continue on it's path.
For arguments sake lets assume that the spline has a length of 7000 units.
Therefore, I have two 3D (x,y,z) vectors. The first vector is the current position of the AI-bot and the second vector the position past the obstacle. For the time being lets just say: current spline position + 400 units; later on I could do a line trace to get the dimension of the obstacle etc. but for now I don't care about it.
Now I would like to compute an alternative path to avoid aforementioned obstacle - hence compute the arc between these two points - How do I do this?
I am really terrible at maths but looked at projectile trajectory because I thought that it would be sort of the same, just was unable to really understand it :<
It doesn't have to be an arc. You can solve this problem recursively in a very simple way.
Consider you're at position A, and the obstacle is at position B. You can do the following moves:
From current position to A+V(B[x]+height(B),0,0)
From current position to A+V(0,B[y]+width(B),0)
From current position to A+V(B[x]-height(B),0,0)
where V is a vector with components V(x,y,z), width(B) is the width of the obstacle and B[x] is the x component of the position of B. This way you moved around it along a rectangle. You can now smoothen the path by subdividing that rectangle in halves. 3 subdivisions are enough to make this smooth enough. To subdivide, take the middle point the first path, and draw a line to the middle of the second path. The same you do from the second path to the third one, and now your rectangle becomes an octagon. If that's not smooth enough, do a few more steps. This will create a new spline that you can use.
I would look at a combination of splines and the EQS system. The spline defines the ideal path to follow. The EQS system finds locations near or on the path, while still doing obstacle avoidance. EQS can return all valid destinations so you can manually order them by custom critera.
Actors set on a spline do work, but there's a whole bunch o' mess when making them stop following a spline, creating a new one at the correct point, attaching the actor the new spline, and so on.
I arrived at this conclusion yesterday after exactly going the messy way of adding spline points etc. The only problem i see is that I find the EQS system very difficult to understand. Not following the examples as such, but modifying it in the way I need it. Lets see, i keep you posted.

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

Simple Algorithm For Line Curving

I'm looking for a simple algorithm for line curving (much like fireworks freeform tool).
In my C++ program, a line is a set of ordered points, each point is of (x,y) form.
Assume I have straight line of 5 (just for simplicity) ordered points (the line isn't necessarily parallel to any axis). I pinch the 3rd point and drag it up. I'm expecting to have a new, gaussian-like, curved line. It doesn't really matter how I implement the "Points" and "Lines", but keep in mind I should add more points to the new expected line so it'll be curved, refined and flowing (and not with line breaks).
I thought of using a gaussian function but I need the ability of moving the curved part (see picture below).
Thanks in advance!
You need a B-spline or a Bezier curve to approximate your shape.
There is a nice interactive demo of Bezier splines so you can play with to see the effect. A sample screenshot below:
Depending on your OS and development environment, there are probably already a number of tools or APIs available.

Fit a curve in angle line?

I have two lines that start and end at random locations on a screen and create an angle. I then have an object follow these two lines. However at the intersection between the first and second line, the object rapidly rotates to go down the second line. And I don't want this.
So what I want to do is be able to create a curved version of this line that would have a more of a U at the intersection rather then a hard turn. I looked into curve fitting papers and can't seem to find that that would allow me to create a U out of a V.
Sorry for the terrible images... I want to take the one of the left, and generate the one on the right (same start, end, and intersection points). Another example, http://en.wikipedia.org/wiki/Curve_fitting
Any ideas?
You should take a look at http://en.wikipedia.org/wiki/Bezier_curve
Or just http://upload.wikimedia.org/wikipedia/commons/thumb/2/2d/Bezier_2_big.gif/240px-Bezier_2_big.gif
If the coordinates of the start/end points of the two lines are known, you can simply calculate an bezier curve follows the methods in the link above.
If not (for example with an bitmap like what you post), you can do Hough Transform first to extract the coordinates