I need to implement a "geometric median"-type algorithm that would apply to rigid bodies, meaning it would not only find a point minimizing the distance from a set of points, but would also take into account the orientation of the body. I haven't found a solution for this type of problem anywhere, while for the geometric median (or Weber or Fermat-Torricelli problem, or facilities location problem), there is a lot of information available, including the Weiszfeld algorithm (and modern improvements). I'm hoping someone will have references to possible solutions. I would have thought this to be a relatively common problem in registration, but maybe I just haven't found the right words to search for...
My problem could be formulated as follows: Say I have a "reference" rigid body with 3 non-colinear points (a triangle), and I measure the coordinates of the 3 points a bunch of times (with some error, or the object was moving a bit). I want to find a good "central location", that would minimize the sum of distances (not square distances) between each measured point and its corresponding centrally-located-object point. This is equivalent to the "multi-facility location problem" but with extra contstraints of fixed distances between the "facilities" and with each point pre-assigned to a facility (not necessarily the closest one).
Actually, I'm thinking instead of minimizing the sum for all the points, I'd only keep the max distance out of the 3 points for each measurement. (is that what's called "minimax"?) But I don't think that would make a big difference in the type of algorithm I'd have to use.
A possible difficulty compared to the geometric median could be that with the added freedom of rotations, the quantity to minimize is no longer convex (not 100% sure, but I think). I'm hoping I can still use a similar algorithm as Weiszfeld's (which is a subgradient method), and hopefully this has been investigated previously. Thanks for any help!
P.S. I'll be doing this in Matlab.
I can't find any research on this subject. The first thing I would do is to use Weiszfeld's algorithm without rigidity constraints to find geometric medians of individual points, define lagrange multipliers corresponding to deviations of edges of the object from expected values, and use gradient descent to find a constrained local minimum. I can't prove that it will always work, but, intuitively, it should as long as deviations are sufficiently small.
Related
Note: I'm very much from a programming background, not a mathematics background. This will become obvious very quickly.
Assume I have a bounded n-dimensional space - for example here I'll use n=2. In that space, I have a set of pre-defined points. (As it happens, I'm doing something questionable with genetic algorithms for finding minima in non-mathematically-solvable equations, but that's not directly relevant).
Next, I have defined a new point within that 2D space. I want to know which three (n+1) points form the smallest (or possibly nearest?) triangle that contains that point. Illustration here:
Now, as that illustration shows, I'm not entirely sure what I'm doing, in that I've failed to adequately describe the criteria by which the candidate triangles are judged - points 10, 5, and 8 would enclose the point within a triangle of smaller area, for example. This is because those specifics are somewhat flexible. What I really care about is:
Computational efficiency: I could potentially end up scaling this algorithm up to thousands of points in a hundred dimensions. As such, I need a solution that's better than exhaustively testing every potential convex hull against a specific equation, and ideally one with a decent big-O notation. Presumably I'm going to need a more intelligent structure that a big unordered list to do this.
If I had a preferred criteria, it's proximity of the hull vertices to the test point. However, if it's easier to build an algorithm which judges by area/volume or something else, I can live with that.
I need to be able to handle edge-cases, where the test-point is, for example, on the edge between two vertices.
Where do I even start with this? Some cursory googling suggests Voronoi diagrams might be a step in the right direction, is that correct? What are the right tools for this job? Any help would be greatly appreciated.
The Problem:
I have an image that I downloaded from google's static map api. I use this image to basically create a "magic wand" type feature where a user clicks. For those interested I am using the graph cut algorithm to find the shape that the user clicked. I then find all the points that represent the border of this shape (borderPoints) using contour tracing.
My Goal:
Straighten out the lines (if possible) and minimize the amount of borderPoints (as much as possible). My current use case are the roofs of houses so in the majority of cases I would hope that I could find the corners and just use those as the borderPoints instead of all the varying points in between. But I am having trouble figuring out how to find those corners because of the bumpy pixel lines.
My Attempts at a Solution:
One simple technique is to loop over the points checking the point before, the current point, and the point after. If the point before and the point after have the same x or the same y then the current point can be removed. This trims the number of points down a little but not as much as I would like.
I also tried looking at the before and after point to see if the current point could be removed if it wasn't within a certain slope range but had little success because occasionally a key corner point was removed because the image was kind of fuzzy and the corner had slightly rounded points.
My Question:
Are there any algorithms for doing this type of thing? If so, what is it (they) called? If not, any thoughts on how to progamatically approach this problem?
This sounds similar to the Ramer–Douglas–Peucker algorithm. You may be able to do better by exploiting the fact that all your points lie on a grid.
Seems to me like you are looking for a polynomial approximation of degree 1.
For a quick answer to your question, you may want to read this: http://en.wikipedia.org/wiki/Simple_regression. The Numerical example section shows you concretely how the equation for your line can be computed.
Polynomial approximations allow you to approach a function, curve, group of point, however you want to call it with a polynomial function of the form an.x^n + ... + a1.x^1 + a0
In your case, you want a line, so you want a function a1.x + a0 where a1 and a0 will be calculated to minimize the error with the set of points you have.
There are various ways of computing your error (called a norm) and minimizing it. You may be interested for example in finding the line that minimizes the distance to any of the points you have (minimizing the max), or in minimizing the distance to the set of points as a whole (minimizing the sum of absolute differences, or the sum of squares of differences, etc.)
In terms of algorithms, you may want to look at Chebyshev approximations and Remez algorithms specifically. All of these solve the approximation of a function with a polynomial of any degree but in your case you will only care about degree 1.
Here is the problem:
I have many sets of points, and want to come up with a function that can take one set and rank matches based on their similarity to the first. Scaling, translation, and rotation do not matter, and some points may be missing from any of the sets of points. The best match is the one that if scaled and translated in the ideal way has the least mean square error between points (maybe with a cap on penalty, or considering only the best fraction of points to handle missing points).
I am trying to come up with a good way to do this, and am wondering if there are any well known algorithms that can handle this type of problem? Just the name of something would be awesome! I lack a formal CSCI or math education, and am doing the best to teach myself.
A few things I have tried
The first thing that comes to mind is to normalize the points somehow, but I dont think that this is helpful because the missing points may throw things off.
The best way I can think of is to estimate a starting point by translating to match their centroids, scaling so that the largest distances from the centroid of the sets match. From there, do an A* search, scaling, rotating, and translating until I reach a maximum, and then compare the two sets. (I hope I am using the term A* correctly, I mean trying small translations and scalings and selecting the move giving the best match) I think this will find the global maximum most of the time, but is not guaranteed to. I am looking for a better way that will always be correct.
Thanks a ton for the help! It has been fun and interesting trying to figure this out so far, so I hope it is for you as well.
There's a very clever algorithm for identifying starfields. You find 4 points in a diamond shape and then using the two stars farthest apart you define a coordinate system locating the other two stars. This is scale and rotation invariant because the locations are relative to the first two stars. This forms a hash. You generate several of these hashes and use those to generate candidates. Once you have the candidates you look for ones where multiple hashes have the correct relationships.
This is described in a paper and a presentation on http://astrometry.net/ .
This paper may be useful: Shape Matching and Object Recognition Using Shape Contexts
Edit:
There is a couple of relatively simple methods to solve the problem:
To combine all possible pairs of points (one for each set) to nodes, connect these nodes where distances in both sets match, then solve the maximal clique problem for this graph. Since the maximal clique problem is NP-complete, the complexity is probably O(exp(n^2)), so if you have too many points, don't use this algorithm directly, use some approximation.
Use Generalised Hough transform to match two sets of points. This approach has less complexity (O(n^4)). But it is more complicated, so I cannot explain it here.
You can find the details in computer vision books, for example "Machine vision: theory, algorithms, practicalities" by E. R. Davies (2005).
I'm asking this questions out of curiostity, since my quick and dirty implementation seems to be good enough. However I'm curious what a better implementation would be.
I have a graph of real world data. There are no duplicate X values and the X value increments at a consistant rate across the graph, but Y data is based off of real world output. I want to find the nearest point on the graph from an arbitrary given point P programmatically. I'm trying to find an efficient (ie fast) algorithm for doing this. I don't need the the exact closest point, I can settle for a point that is 'nearly' the closest point.
The obvious lazy solution is to increment through every single point in the graph, calculate the distance, and then find the minimum of the distance. This however could theoretically be slow for large graphs; too slow for what I want.
Since I only need an approximate closest point I imagine the ideal fastest equation would involve generating a best fit line and using that line to calculate where the point should be in real time; but that sounds like a potential mathematical headache I'm not about to take on.
My solution is a hack which works only because I assume my point P isn't arbitrary, namely I assume that P will usually be close to my graph line and when that happens I can cross out the distant X values from consideration. I calculating how close the point on the line that shares the X coordinate with P is and use the distance between that point and P to calculate the largest/smallest X value that could possible be closer points.
I can't help but feel there should be a faster algorithm then my solution (which is only useful because I assume 99% of the time my point P will be a point close to the line already). I tried googling for better algorithms but found so many algorithms that didn't quite fit that it was hard to find what I was looking for amongst all the clutter of inappropriate algorithms. So, does anyone here have a suggested algorithm that would be more efficient? Keep in mind I don't need a full algorithm since what I have works for my needs, I'm just curious what the proper solution would have been.
If you store the [x,y] points in a quadtree you'll be able to find the closest one quickly (something like O(log n)). I think that's the best you can do without making assumptions about where the point is going to be. Rather than repeat the algorithm here have a look at this link.
Your solution is pretty good, by examining how the points vary in y couldn't you calculate a bound for the number of points along the x axis you need to examine instead of using an arbitrary one.
Let's say your point P=(x,y) and your real-world data is a function y=f(x)
Step 1: Calculate r=|f(x)-y|.
Step 2: Find points in the interval I=(x-r,x+r)
Step 3: Find the closest point in I to P.
If you can use a data structure, some common data structures for spacial searching (including nearest neighbour) are...
quad-tree (and octree etc).
kd-tree
bsp tree (only practical for a static set of points).
r-tree
The r-tree comes in a number of variants. It's very closely related to the B+ tree, but with (depending on the variant) different orderings on the items (points) in the leaf nodes.
The Hilbert R tree uses a strict ordering of points based on the Hilbert curve. The Hilbert curve (or rather a generalization of it) is very good at ordering multi-dimensional data so that nearby points in space are usually nearby in the linear ordering.
In principle, the Hilbert ordering could be applied by sorting a simple array of points. The natural clustering in this would mean that a search would usually only need to search a few fairly-short spans in the array - with the complication being that you need to work out which spans they are.
I used to have a link for a good paper on doing the Hilbert curve ordering calculations, but I've lost it. An ordering based on Gray codes would be simpler, but not quite as efficient at clustering. In fact, there's a deep connection between Gray codes and Hilbert curves - that paper I've lost uses Gray code related functions quite a bit.
EDIT - I found that link - http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.133.7490
I need to evaluate if two sets of 3d points are the same (ignoring translations and rotations) by finding and comparing a proper geometric hash. I did some paper research on geometric hashing techniques, and I found a couple of algorithms, that however tend to be complicated by "vision requirements" (eg. 2d to 3d, occlusions, shadows, etc).
Moreover, I would love that, if the two geometries are slightly different, the hashes are also not very different.
Does anybody know some algorithm that fits my need, and can provide some link for further study?
Thanks
Your first thought may be trying to find the rotation that maps one object to another but this a very very complex topic... and is not actually necessary! You're not asking how to best match the two, you're just asking if they are the same or not.
Characterize your model by a list of all interpoint distances. Sort the list by that distance. Now compare the list for each object. They should be identical, since interpoint distances are not affected by translation or rotation.
Three issues:
1) What if the number of points is large, that's a large list of pairs (N*(N-1)/2). In this case you may elect to keep only the longest ones, or even better, keep the 1 or 2 longest ones for each vertex so that every part of your model has some contribution. Dropping information like this however changes the problem to be probabilistic and not deterministic.
2) This only uses vertices to define the shape, not edges. This may be fine (and in practice will be) but if you expect to have figures with identical vertices but different connecting edges. If so, test for the vertex-similarity first. If that passes, then assign a unique labeling to each vertex by using that sorted distance. The longest edge has two vertices. For each of THOSE vertices, find the vertex with the longest (remaining) edge. Label the first vertex 0 and the next vertex 1. Repeat for other vertices in order, and you'll have assigned tags which are shift and rotation independent. Now you can compare edge topologies exactly (check that for every edge in object 1 between two vertices, there's a corresponding edge between the same two vertices in object 2) Note: this starts getting really complex if you have multiple identical interpoint distances and therefore you need tiebreaker comparisons to make the assignments stable and unique.
3) There's a possibility that two figures have identical edge length populations but they aren't identical.. this is true when one object is the mirror image of the other. This is quite annoying to detect! One way to do it is to use four non-coplanar points (perhaps the ones labeled 0 to 3 from the previous step) and compare the "handedness" of the coordinate system they define. If the handedness doesn't match, the objects are mirror images.
Note the list-of-distances gives you easy rejection of non-identical objects. It also allows you to add "fuzzy" acceptance by allowing a certain amount of error in the orderings. Perhaps taking the root-mean-squared difference between the two lists as a "similarity measure" would work well.
Edit: Looks like your problem is a point cloud with no edges. Then the annoying problem of edge correspondence (#2) doesn't even apply and can be ignored! You still have to be careful of the mirror-image problem #3 though.
There a bunch of SIGGRAPH publications which may prove helpful to you.
e.g. "Global Non-Rigid Alignment of 3-D Scans" by Brown and Rusinkiewicz:
http://portal.acm.org/citation.cfm?id=1276404
A general search that can get you started:
http://scholar.google.com/scholar?q=siggraph+point+cloud+registration
spin images are one way to go about it.
Seems like a numerical optimisation problem to me. You want to find the parameters of the transform which transforms one set of points to as close as possible by the other. Define some sort of residual or "energy" which is minimised when the points are coincident, and chuck it at some least-squares optimiser or similar. If it manages to optimise the score to zero (or as near as can be expected given floating point error) then the points are the same.
Googling
least squares rotation translation
turns up quite a few papers building on this technique (e.g "Least-Squares Estimation of Transformation Parameters Between Two Point Patterns").
Update following comment below: If a one-to-one correspondence between the points isn't known (as assumed by the paper above), then you just need to make sure the score being minimised is independent of point ordering. For example, if you treat the points as small masses (finite radius spheres to avoid zero-distance blowup) and set out to minimise the total gravitational energy of the system by optimising the translation & rotation parameters, that should work.
If you want to estimate the rigid
transform between two similar
point clouds you can use the
well-established
Iterative Closest Point method. This method starts with a rough
estimate of the transformation and
then iteratively optimizes for the
transformation, by computing nearest
neighbors and minimizing an
associated cost function. It can be
efficiently implemented (even
realtime) and there are available
implementations available for
matlab, c++... This method has been
extended and has several variants,
including estimating non-rigid
deformations, if you are interested
in extensions you should look at
Computer graphics papers solving
scan registration problem, where
your problem is a crucial step. For
a starting point see the Wikipedia
page on Iterative Closest Point
which has several good external
links. Just a teaser image from a matlab implementation which was designed to match to point clouds:
(source: mathworks.com)
After aligning you could the final
error measure to say how similar the
two point clouds are, but this is
very much an adhoc solution, there
should be better one.
Using shape descriptors one can
compute fingerprints of shapes which
are often invariant under
translations/rotations. In most cases they are defined for meshes, and not point clouds, nevertheless there is a multitude of shape descriptors, so depending on your input and requirements you might find something useful. For this, you would want to look into the field of shape analysis, and probably this 2004 SIGGRAPH course presentation can give a feel of what people do to compute shape descriptors.
This is how I would do it:
Position the sets at the center of mass
Compute the inertia tensor. This gives you three coordinate axes. Rotate to them. [*]
Write down the list of points in a given order (for example, top to bottom, left to right) with your required precision.
Apply any algorithm you'd like for a resulting array.
To compare two sets, unless you need to store the hash results in advance, just apply your favorite comparison algorithm to the sets of points of step 3. This could be, for example, computing a distance between two sets.
I'm not sure if I can recommend you the algorithm for the step 4 since it appears that your requirements are contradictory. Anything called hashing usually has the property that a small change in input results in very different output. Anyway, now I've reduced the problem to an array of numbers, so you should be able to figure things out.
[*] If two or three of your axis coincide select coordinates by some other means, e.g. as the longest distance. But this is extremely rare for random points.
Maybe you should also read up on the RANSAC algorithm. It's commonly used for stitching together panorama images, which seems to be a bit similar to your problem, only in 2 dimensions. Just google for RANSAC, panorama and/or stitching to get a starting point.