I have an image such as this:
and I need to calculate the orientation of it. In this case the shape is pointing towards the top left of the screen. Accuracy isn't hugely important as long as 3 or 4 calculations average out to within 5 degrees or so of the actual orientation (it will be moving slightly).
Can anyone point me towards an algorithm to do this? I don't mind if the orientation is returned as a double or as a vector.
If the image is always T-shaped, you can simply get the furthest pair of pixels, then find the furthest pair from either both of those (the edges of the T), find which is further from the other two, draw a line from that one to the middle point of those two.
You can further refine it by then finding the base of the T by comparing the middle line with the edges of the base, and adjusting the angle and offset until it is actually in the middle.
The definitive solution is impossible I guess, since requires image recognition. I would project the 2D image onto axis, i.e. obtain the width and height of the image and get direction vector from these values taking them as components.
First, a couple of assumptions:
The center and centroid are "close"
The descending bar of the T is longer than the cross-bar
First, determine the bounding rectangle of the image and find the points of the image that lie along this rectangle. For points that lie along the line and are a certain distance from one another (say 5 pixels to pick a value) you'll need to only take 1 point from that cluster. At the end of this you should have 3 points, i.e. a triangle. The shortest side of the triangle should be the cross-bar (from assumption 2), i.e. find the two points closest to each other. The line that is perpendicular to the line crossing those two points is then your orientation line, i.e. find the angle between it and the horizontal axis.
I would try morphological skeletonization to simplify the image, followed by some straightforward algorithm to determine the orientation of the longer leg of the skeleton.
The solution in the end was to use a Convex Hull Algorithm, which finds the minimum number of points needed to enclose a shape with a bound.
Related
Following is the problem statement.
You have been given k number of equilateral triangles (There is a upper cap on
k, lets say k=<15). The triangles can be overlapping.
Now you have to find a parallelogram enclosing all the triangles and has the
minimum area. It is given that two opposite edges of the four edges are
parallel to either X axis or Y axis(That is your choice).
My Approach:
Let's say two of them are parallel to Y axis.
Then the leftmost point and the rightmost point of the set of triangles
will lie in two opposite edges of the parallelogram. Now I will draw two straight lines which pass through these points and are parallel to the Y axis.
This way I have found two edges its not so difficult.
Now I am stuck and don't know how to find other two.
I thought a lot but since I was unable to make it out I am posting it here.
Any help will be appreciated!!!!!!!
Build convex hull around all triangles vertices.
Then use rotating calipers to get a pair of parallel lines with the smallest vertical distance between them (parallelogram area is defined by height (here horizontal) - it is already fixed, and by vertical base length - choose minimum)
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.
I've been searching a lot on this problem, but I couldn't really find an answer that would fit.
I need to rotate a cylinder around a given point (eg, 0,0,0), but the pivot of the cylinder is given by default. How do i change that?
I found this topic, and it's quite what I would want to do, but I don't know how to do it with java.
To explain better what I would like to do, I'll show 3 images.(v)
imageshack.us/photo/my-images/259/aintgood.jpg
imageshack.us/photo/my-images/840/whatineed.jpg
imageshack.us/photo/my-images/705/nogoodn.jpg
So, the first image shows my basic problem, the cylinder should be positioned with the end at the center of the sphere, let's say (0,0,0). The user gives two angles. The first one is for a rotX command, the second one for a rotZ one. The pivot of the cylinder is at its center, so, as image 3 shows, even if i translate the cylinder so its end is at the center of the sphere, when it rotates, the whole thing ruins.
Image 2 shows what the cylinder-sphere group should look like, regardless the given angles.
The image is not obtained based on an algorithm, but based on calculus, and mouserotated.
The general procedure for rotation about an arbitrary point P is:
Translate by -P (so P is at (0, 0, 0))
Rotate around the origin
Translate by P (to bring the origin back to the original location of P)
The easiest way to do this is to represent everything in homogeneous coordinates and represent translations and rotations by matrices. Composing the above three transformations (translate-rotate-translate) is done by matrix multiplication. If the rotation is composed of two or more simpler rotations, then the rotation matrix itself is a product of the matrices for the simpler rotations.
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.
To get right to it: Say I've got two specific pixels a & b, as well as a list of random others. I now want to check all pixels in that list if they are on the line which passes through a & b (but which is NOT restricted to have a & b as endpoints!)
I looked at Bresenham's line algorithm, but that seems to only find the points between a & b?
I've also had a look at linear equations in general but I'm kind of stuck on how to properly discretize the continuous line into pixels...
(I'm trying to implement a random sampling algorithm in java, which tries to find the line with the most pixels on it, if that matters).
Thanks a lot for any help with this :)
I strongly suggest that you compute the distance between the point and the line.
If you use one pixel as unit of measurement (which you will if you work in a pixel coordinate system), you can simply check if the distance from the point to the line is < 1.
Here's how to compute the distance between a point and a line:
Minimum Distance between a Point and a Line
Wolfram: Point-Line Distance--2-Dimensional
You could search not between a and b, but between the points that are on the same line, but out of the borders of image. You can get them simply putting vector (b-a) necessary amount of times to the a side and to the b side. And the use your Bresenham's line algorithm.
As for more concrete answers, define the question better, please. Do you consider pixels as points or squares or circles? What is "pixel is on the line" in your terms? What width has your line? You are looking for the line with max number of pixels on the cm length or in the rectangle borders? Among what lines do you search?