OpenCV Merge point clusters, remove outliners - c++

I want to determine the point where most lines from the image cross. Obviously, there can be more than one such point, but for simplicity I'm trying with just one point for. I was trying with OpenCV built in Kmeans clustering, but this algorithm assumes every point must be clustered, so I get something like this:
Obviously it gets much worse when more lines are present as every intersection will offset the center of the cluster
What I want to accomplish is removal of all the outliners that come as a result of accidental line crossing here and there which is especially problematic in complex scenes.
I was thinking of DBSCAN but it appears I'd need to implement it myself from scratch since it's not present in OpenCV - I'd prefer not to spend extra time on something that's not a core part of my project and focus on the topic instead of making tools. Is there a library that can do what I need? Alternatively I was considering brutal force in form
for each point in list
find nearest neighbor
if distance > threshold
label as bad
if point already has label AND neighbor already has label
two sets collided, merge them
else if neighbor already has label
assign point.label = neighbor.label
else
point.label = new Label
neighbor.label = point.label
find mass center of each labeled set and replace set with it's center.

You can use Sklearn library in python. It has many other algorithms
http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html

Related

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.

Plot a curved trajectory on a 2D coordinate system

I have a few ordered points (less than 10) in 2D coordinates system.
I have an agent moving in the system and I want to find the shortest path between those points following their order.
For background the agent can be given a position to go to with a thrust, and my objective is to plot the fastest course given the fact that the agent has a maximum thrust and maximum angular velocity.
After some research I realized that I may be looking for a curve fitting algorithm, but I don't know the underlying function since the points are randomly distributed in the coordinates system.
Please, help me find a solution to this problem.
I am open to any suggestion, my prefered programming language being C++.
I'm sure there is a pure mathematical solution such as spacecraft trajectory optimization for example, but here is how I would consider approaching it from a programming/annealing perspective.
Even though you need a continuous path, you might start the path search with discreet steps and a tolerance for getting close enough to each point as a start.
Assign a certain amount of time to each step and vary applied angular force and thrust at each step.
Calculate resulting angular momentum and position for the start of the next step.
Select the parameters for the next step either with a random search, or iterate through each to find the closest to the next target point (quantize the selection of angles and thrust to begin with). Repeat steps until you are close enough to the next target point. Then repeat to get to the next point.
Once you have a rough path you can start refining it (perhaps use the rough point from the previous run as target points in the new one) by reducing the time/size of the steps and tolerance to target points.
When evaluating the parameters' fitness at each step you might want to consider that once you reach a target point you also want to perhaps have momentum in the direction of the next point. This should be an emergent property if multiple paths are considered and the fitness function considers shortest total time.
c++ could help here if you use the std::priority_queue and std::map for example to keep track of the potential paths.

Finding the middle point of 2 parallel contours

Couldn't find this with search but I'm not sure how to describe this anyway, which is one reason the problems been so hard to find the right approach for. Sorry if its already been asked or if the problem description is to vague.
The problem: I am detecting the contours of a curving, painted physical path of consistent width from an image using opencv's findcontours. I need to map a vector of points in the middle of those 2 edges along the length of the path so as to trace the painted path with a single vector.
I was wondering if there is a way to find points within a certain pixel distance in the imagespace, in various other contours. I can iterate through them all, and find the closest ones that way, but thats time intensive.
If there was I could search the other contour vectors for points about the right width away and use the 2 points to estimate a mid point and add that to the growing middle vector.
Or if theres a better approach to converting the detected path into a single, workable vector that would work to.
Sounds like you're looking for the "skeleton" - it helps if you know the terms.
If you can transform the image into a black&white image that still shows the path, it's trivial: iterate the erosion procedure until no more points are eroded.
Another approach is to realize that the operation is expensive once, but once you've found one pair of points, the next pair is easily found in the respective 3x3 neighborhoods.

'Stable' multi-dimensional scaling algorithm

I have a wireless mesh network of nodes, each of which is capable of reporting its 'distance' to its neighbors, measured in (simplified) signal strength to them. The nodes are geographically in 3d space but because of radio interference, the distance between nodes need not be trigonometrically (trigonomically?) consistent. I.e., given nodes A, B and C, the distance between A and B might be 10, between A and C also 10, yet between B and C 100.
What I want to do is visualize the logical network layout in terms of connectness of nodes, i.e. include the logical distance between nodes in the visual.
So far my research has shown the multidimensional scaling (MDS) is designed for exactly this sort of thing. Given that my data can be directly expressed as a 2d distance matrix, it's even a simpler form of the more general MDS.
Now, there seem to be many MDS algorithms, see e.g. http://homepage.tudelft.nl/19j49/Matlab_Toolbox_for_Dimensionality_Reduction.html and http://tapkee.lisitsyn.me/ . I need to do this in C++ and I'm hoping I can use a ready-made component, i.e. not have to re-implement an algo from a paper. So, I thought this: https://sites.google.com/site/simpmatrix/ would be the ticket. And it works, but:
The layout is not stable, i.e. every time the algorithm is re-run, the position of the nodes changes (see differences between image 1 and 2 below - this is from having been run twice, without any further changes). This is due to the initialization matrix (which contains the initial location of each node, which the algorithm then iteratively corrects) that is passed to this algorithm - I pass an empty one and then the implementation derives a random one. In general, the layout does approach the layout I expected from the given input data. Furthermore, between different runs, the direction of nodes (clockwise or counterclockwise) can change. See image 3 below.
The 'solution' I thought was obvious, was to pass a stable default initialization matrix. But when I put all nodes initially in the same place, they're not moved at all; when I put them on one axis (node 0 at 0,0 ; node 1 at 1,0 ; node 2 at 2,0 etc.), they are moved along that axis only. (see image 4 below). The relative distances between them are OK, though.
So it seems like this algorithm only changes distance between nodes, but doesn't change their location.
Thanks for reading this far - my questions are (I'd be happy to get just one or a few of them answered as each of them might give me a clue as to what direction to continue in):
Where can I find more information on the properties of each of the many MDS algorithms?
Is there an algorithm that derives the complete location of each node in a network, without having to pass an initial position for each node?
Is there a solid way to estimate the location of each point so that the algorithm can then correctly scale the distance between them? I have no geographic location of each of these nodes, that is the whole point of this exercise.
Are there any algorithms to keep the 'angle' at which the network is derived constant between runs?
If all else fails, my next option is going to be to use the algorithm I mentioned above, increase the number of iterations to keep the variability between runs at around a few pixels (I'd have to experiment with how many iterations that would take), then 'rotate' each node around node 0 to, for example, align nodes 0 and 1 on a horizontal line from left to right; that way, I would 'correct' the location of the points after their relative distances have been determined by the MDS algorithm. I would have to correct for the order of connected nodes (clockwise or counterclockwise) around each node as well. This might become hairy quite quickly.
Obviously I'd prefer a stable algorithmic solution - increasing iterations to smooth out the randomness is not very reliable.
Thanks.
EDIT: I was referred to cs.stackexchange.com and some comments have been made there; for algorithmic suggestions, please see https://cs.stackexchange.com/questions/18439/stable-multi-dimensional-scaling-algorithm .
Image 1 - with random initialization matrix:
Image 2 - after running with same input data, rotated when compared to 1:
Image 3 - same as previous 2, but nodes 1-3 are in another direction:
Image 4 - with the initial layout of the nodes on one line, their position on the y axis isn't changed:
Most scaling algorithms effectively set "springs" between nodes, where the resting length of the spring is the desired length of the edge. They then attempt to minimize the energy of the system of springs. When you initialize all the nodes on top of each other though, the amount of energy released when any one node is moved is the same in every direction. So the gradient of energy with respect to each node's position is zero, so the algorithm leaves the node where it is. Similarly if you start them all in a straight line, the gradient is always along that line, so the nodes are only ever moved along it.
(That's a flawed explanation in many respects, but it works for an intuition)
Try initializing the nodes to lie on the unit circle, on a grid or in any other fashion such that they aren't all co-linear. Assuming the library algorithm's update scheme is deterministic, that should give you reproducible visualizations and avoid degeneracy conditions.
If the library is non-deterministic, either find another library which is deterministic, or open up the source code and replace the randomness generator with a PRNG initialized with a fixed seed. I'd recommend the former option though, as other, more advanced libraries should allow you to set edges you want to "ignore" too.
I have read the codes of the "SimpleMatrix" MDS library and found that it use a random permutation matrix to decide the order of points. After fix the permutation order (just use srand(12345) instead of srand(time(0))), the result of the same data is unchanged.
Obviously there's no exact solution in general to this problem; with just 4 nodes ABCD and distances AB=BC=AC=AD=BD=1 CD=10 you cannot clearly draw a suitable 2D diagram (and not even a 3D one).
What those algorithms do is just placing springs between the nodes and then simulate a repulsion/attraction (depending on if the spring is shorter or longer than prescribed distance) probably also adding spatial friction to avoid resonance and explosion.
To keep a "stable" diagram just build a solution and then only update the distances, re-using the current position from previous solution as starting point. Picking two fixed nodes and aligning them seems a good idea to prevent a slow drift but I'd say that spring forces never end up creating a rotational momentum and thus I'd expect that just scaling and centering the solution should be enough anyway.

Simulating a car moving along a track

For Operating Systems class I'm going to write a scheduling simulator entitled "Jurrasic Park".
The ultimate goal is for me to have a series of cars following a set path and passengers waiting in line at a set location for those cars to return to so they can be picked up and be taken on the tour. This will be a simple 2d, top-down view of the track and the cars moving along it.
While I can code this easily without having to visually display anything I'm not quite sure what the best way would be to implement a car moving along a fixed track.
To start out, I'm going to simply use OpenGL to draw my cars as rectangles but I'm still a little confused about how to approach updating the car's position and ensuring it is moving along the set path for the simulated theme park.
Should I store vertices of the track in a list and have each call to update() move the cars a step closer to the next vertex?
If you want curved track, you can use splines, which are mathematically defined curves specified by two vector endpoints. You plop down the endpoints, and then solve for a nice curve between them. A search should reveal source code or math that you can derive into source code. The nice thing about this is that you can solve for the heading of your vehicle exactly, as well as get the next location on your path by doing a percentage calculation. The difficult thing is that you have to do a curve length calculation if you don't want the same number of steps between each set of endpoints.
An alternate approach is to use a hidden bitmap with the path drawn on it as a single pixel wide curve. You can find the next location in the path by matching the pixels surrounding your current location to a direction-of-travel vector, and then updating the vector with a delta function at each step. We used this approach for a path traveling prototype where a "vehicle" was being "driven" along various paths using a joystick, and it works okay until you have some intersections that confuse your vector calculations. But if it's a unidirectional closed loop, this would work just fine, and it's dead simple to implement. You can smooth out the heading angle of your vehicle by averaging the last few deltas. Also, each pixel becomes one "step", so your velocity control is easy.
In the former case, you can have specially tagged endpoints for start/stop locations or points of interest. In the latter, just use a different color pixel on the path for special nodes. In either case, what you display will probably not be the underlying path data, but some prettied up representation of your "park".
Just pick whatever is easiest, and write a tick() function that steps to the next path location and updates your vehicle heading whenever the car is in motion. If you're really clever, you can do some radius based collision handling so that cars will automatically stop when a car in front of them on the track has halted.
I would keep it simple:
Run a timer (every 100msec), and on each timer draw each ones of the cars in the new location. The location is read from a file, which contains the 2D coordinates of the car (each car?).
If you design the road to be very long (lets say, 30 seconds) writing 30*10 points would be... hard. So how about storing at the file the location at every full second? Then between those 2 intervals you will have 9 blind spots, just move the car in constant speed (x += dx/9, y+= dy/9).
I would like to hear a better approach :)
Well you could use some path as you describe, ether a fixed point path or spline. Then move as a fixed 'velocity' on this path. This may look stiff, if the car moves at the same spend on the straight as cornering.
So you could then have speeds for each path section, but you would need many speed set points, or blend the speeds, otherwise you'll get jerky speed changes.
Or you could go for full car simulation, and use an A* to build the optimal path. That's over kill but very cool.
If there is only going forward and backward, and you know that you want to go forward, you could just look at the cells around you, find the ones that are the color of the road and move so you stay in the center of the road.
If you assume that you won't have abrupt curves then you can assume that the road is directly in front of you and just scan to the left and right to see if the road curves a bit, to stay in the center, to cut down on processing.
There are other approaches that could work, but this one is simple, IMO, and allows you to have gentle curves in your road.
Another approach is just to have it be tile-based, so you just look at the tile before you, and have different tiles for changes in road direction an so you know how to turn the car to stay on the tile.
This wouldn't be as smooth but is also easy to do.