I'm looking for a way to match a list of 2D coordinates (which are in drawing order) to a shape from a list of shapes, or to find if it doesn't match any shape.
I've had a look at this, but I'm not too sure how exactly I'd relate that to things like straight/bent lines.
One idea I've thought of is to determine all the corners of each shape from the list (in order), and then check if the points from the list of coordinates that are found to be corners match one of these shapes (in the same order), using something like this. This might be a bit too strict for what I want to do however, as I want there to be a decent amount of leeway in the detection.
I'm also not sure what exactly I should use to pull corners (or lines etc.) from the list of coordinates - would it be worth turning it into an image or should I just try to detect things straight from the coordinate list?
For example, a possible input could be:
And some shapes to match could be: or or
And in this case, it would match the L shape.
For context, the reason I'm doing this is for a game where you have to draw symbols in the air to cast a spell.
If there aren't too many distinct shapes, here is what I woud try:
turn the curves to a (length, angle) representation; the length can be estimated as the sums of segment lengths, and the angle as the direction of the segments;
to be able to compare two representations, normalize the total length to unit (this will make the comparison size-independent), and sample at regular distances; said differently, obtain a vector of N angles at points equally spaced along the curve;
now to recognize a curve, compute the sum of absolute differences with similar vectors obtained from reference model, and keep the smallest sum.
There is no need for strict accuracy.
Note that this representation is not rotation-invariant, on purpose. It is also sensitive to the drawing order (from one endpoint to the other, or conversely), this can be unwanted. Finally, beware of the closed paths (circles), that people might start anywhere.
Related
I have a collection of java.awt.Shape objects covering a two-dimensional plane with no overlap. These are from a data set of U.S. Counties, at a fairly low resolution. For an (x,y) latitude/longitude point, I want a quick way to identify the shape which county contains that point. What's an optimal way to index this?
Brute force would look like:
for (Shape eachShape : countyShapes) {
if (eachShape.contains(x, y)) {
return eachShape;
}
}
To optimize this, I can store the min/max bounds of the (possibly complex) shapes, and only call contains(x, y) on shapes whose rectangular bounds encompass a given x,y coordinate. What's the best way to build this index? A SortedMultiset would work for indexing on the x minima and maxima, but how to also include the y coordinates in the index?
For this specific implementation, doing a few seconds of up-front work to index the shapes is not a problem.
If possible you could try a bitmap with each shape in a different color. Then simply query the point and the color and lookup the shape.
This question is outside the scope of Stackoverflow but the answer is probably Binary Space Partitioning.
Roughly:
Divide the space in two either on the x coordinate or y coordinate using the mid-point of the range.
Create a list of counties on the two sides of that line (and divided by that line).
On each side of that line divide the collections again by the other dimension.
Continue recursively building a tree dividing alternately by x and y until you reach a satisfactory set of objects to examine by brute force.
The conventional algorithm actually divides the shapes lying across the boundary but that might not be necessary here.
A smart implementation might look for the most efficient line to divide on which is the one where the longest of the two lists is the smallest.
That involves more up front calculation but a more efficient and consistently performing partition.
You could use an existing GIS library like GeoTools and then all the hard work is already done.
Simply load your shapefile of counties and execute queries like
"the_geom" contains 'POINT(x y)
The quickstart tutorial will show you how to load the shapes, and the query tutorial will show you how to query them.
Having min an max values of coordinates of the bounds not guarantee that you can determine if one point is in or out in any situations. If you want achieve this by yourself you should implement some algorithm. There's a good one that is called "radial algorithm", I recommend that uses this, and it isn't so complicated to implement, there are sufficient bibliography and examples.
Hope this help.
I have an array with the coordinates of the center of small circles which have the same radius. I know how to find when the mouse is over a circle, but my array is big and I want the fastest way to calculate this operation.
Is there a way of finding if the mouse is over a circle without looping all the array for each movement of the mouse?
Initially, set up some 'zones' for quicker reference:
Separate the whole surface into a small number of rectangles that don't intersect.
For each of these rectangles, list all circles that are at least partially contained in it. (A circle may end up listed in multiple rectangles, but that's okay.)
Every time you want to check whether the mouse is over a circle, you won't have to go through the whole array of circles. Instead:
Figure out which rectangle you're in.
Check only the circles that are listed under that rectangle.
This looks like a problem of optimizing the boundary check for a large number of items. The approach of going linearly does not scale well for thousands of circles.
This is a good topic to read on the net. But first, without going there, I'll try to explain (as an exercise) what I would explore. I would create a binary tree and partition the space, then instead of using an array I would put the circle points in such a tree. Looking the tree elements that are closer to the actual X,Y location becomes a matter of doing a binary search on the tree. The you have the closest point as a result of that search and can check for collision on it. There is still more to be done to the algorithm, and further optimizations are needed. For example, how to check for more points and not only the final one? Potentially I need a tree for the X coordinate, and another for the Y coordinate, etc... But I would explore these ideas. I will come back to this post and expand my reply with an actual example and a more concrete solution.
What if you check the coordinates that are r(radius) distance from the mouse? Then you could narrow your search down in the array if it is ordered.
Say you have a collection of points with coordinates on a Cartesian coordinate system.
You want to plot another point, and you know its coordinates in the same Cartesian coordinate system.
However, the plot you're drawing on is distorted from the original. Imagine taking the original plane, printing it on a rubber sheet, and stretching it in some places and pinching it in others, in an asymmetrical way (no overlapping or anything complex).
(source)
You know the stretched and unstretched coordinates of each of your set of points, but not the underlying stretch function. You know the unstretched coordinates of a new point.
How can you estimate where to plot the new point in the stretched coordinates based on the stretched positions of nearby points? It doesn't need to be exact, since you can't determine the actual stretch function from a set of remapped points unless you have more information.
other possible keywords: warped distorted grid mesh plane coordinate unwarp
Ok, so this sounds like image warping. This is what you should do:
Create a Delaunay triangulation of your unwarped grid and use your knowledge of the correspondences between the warped and unwarped grid to create the triangulation for the warped grid. Now you know the corresponding triangles in each image and since there is no overlapping, you should be able to perform the next step without much difficulty.
Now, to find the corresponding point A, in the warped image:
Find the triangle A lies in and use the transformation between the triangle in the unwarped grid and the warped grid to figure out the new position.
This is explained explicitly in detail here.
Another (much more complicated) method is the Thin Plate Spline (which is also explained in the slides above).
I understood that you have one-to-one correspondence between the wrapped and unwrapped grid points. And I assume that the deformation is not so extreme that you might have intersecting grid lines (like the image you show).
The strategy is exactly what Jacob suggests: Triangulate the two grids such that there is a one-to-one correspondence between triangles, locate the point to be mapped in the triangulation and then use barycentric coordinates in the corresponding triangle to compute the new point location.
Preprocess
Generate the Delaunay triangulation of the points of the wrapped grid, let's call it WT.
For every triangle in WT add a triangle between the corresponding vertices in the unwrapped grid. This gives a triangulation UWT of the unwrapped points.
Map a point p into the wrapped grid
Find the triangle T(p1,p2,p3) in the UWT which contains p.
Compute the barycentric coordinates (b1,b2,b3) of p in T(p1,p2,p3)
Let Tw(q1,q2,q3) be the triangle in WT corresponding to T(p1,p2,p3). The new position is b1 * q1 + b2 * q2 + b3 * q3.
Remarks
This gives a deformation function as a linear spline. For smoother behavior one could use the same triangulation but do higher order approximation which would lead to a bit more complicated computation instead of the barycentric coordinates.
The other answers are great. The only thing I'd add is that you might want to take a look at Free form deformation as a way of describing the deformations.
If that's useful, then it's quite possible to fit a deformation grid/lattice to your known pairs, and then you have a very fast method of deforming future points.
A lot depends on how many existing points you have. If you have only one, there's not really much you can do with it -- you can offset the second point by the same amount in the same direction, but you don't have enough data to really do any better than that.
If you have a fair number of existing points, you can do a surface fit through those points, and use that to approximate the proper position of the new point. Given N points, you can always get a perfect fit using an order N polynomial, but you rarely want to do that -- instead, you usually guess that the stretch function is a fairly low-order function (e.g. quadratic or cubic) and fit a surface to the points on that basis. You then place your new point based on the function for your fitted surface.
i want to find a circular object(Iris of eye, i have used Haar Cascase with viola Jones algorithm). so i found that hough circle would be the correct way to do it. can anybody explain me how to implement Hough circle in Java or any other easy implementation to find iris with Java.
Thanks,
Duda and Hart (1971) has a pretty clear explanation of the Hough transform and a worked example. It's not difficult to produce an implementation directly from that paper, so it's a good place for you to start.
ImageJ provides a Hough Circle plugin. I've been playing around with it several times in the past.
You could take a look at the source code if you want or need to modify it.
If you want to find an iris you should be straightforward about this. The part of the iris you are after is actually called a limbus. Also note that the contrast of the limbus is much lower than the one of the pupil so if image resolution permits pupil is a better target. Java is not a good option as programming language here since 1. It is slow while processing is intense; 2. Since classic Hough circle requires 3D accumulator and Java probably means using a cell phone the memory requirements will be tough.
What you can do is to use a fact that there is probably a single (or only a few) Limbuses in the image. First thing to do is to reduce the dimensionality of the problem from 3 to 2 by using oriented edges: extract horizontal and vertical edges that together represent edge orientation (they can be considered as horizontal and vertical components of edge vector). The simple idea is that the dominant intersection of edge vectors is the center of your limbus. To find the intersection you only need two oriented edges instead of three points that define a circle. Hence dimensionality reduction from 3 to 2.
You also don’t need to use a classical Hough circle transform with a huge accumulator and numerous calculations to find this intersection. A Randomized Hough will be much faster. Here is how it works (~ to RANSAC): you select a minimum number of oriented edges at random (in your case 2), find the intersection, then find all the edges that intersect at approximately the same location. These are inliers. You just iterate 10-30 times choosing a different random sample of 2 edges to settle in a set with maximum number of inliers. Hopefully, these inliers lie on the limbus. The median of inlier ray intersections will give you the center of the circle and the median distance to the inliers from the center is the radius.
In the picture below bright colors correspond to inliers and orientation is shown with little line segment. The set of original edges is shown in the middle (horizontal only). While original edges lie along an ellipse, Hough edges were transformed by an Affine transform to make those belonging to limbus to lie on a circle. Also note that edge orientations are pretty noisy.
i would like to build a dynamic data structure that can hold a list of polygons and return a list of polygons that overlaps a specified rectangle.
i looked into bst trees (and quad trees) but these dont seem to work too well when the polygons overlap heavily.
any good ideas i should check out before i roll my own nonsense?
edit
lets assume all the polygons are normal non rotated rectangles. im willing to take the hit (point in polygon test) during point tests (i might be doing it anyway), and during a region test getting their bounding boxes is just as good. only a small percentage of them will actually not overlap the region in question.
I would look at 2-d segment delaunay graphs. Look also at Nef polygons. CGAL has a lot of set operations on polygons. Answers to this question may also be of value
Edit If your polygons are non rotated rectangles see R-Trees
Why do you write that yourself? Java offers complex intersection tests. You can convert your polygon data structures and your rectangle to Java.awt.geom.Area and then call the Area.intersect() method which does all the math for you.
It also takes care of all the rarely occurring (but still important) special cases which are really nasty to catch.
i just wrote a regular quadtree, that allowed each leaf node to hold unlimited polys, if the intersection of the bounds of the leaf and the bounds of each poly in the bucket were equivalent. otherwise leaf nodes are limited to 8 polys, before splitting.