How to display clear result after Hough Transformation? - java

I have the following image acquired after a Canny edge detection:
After Hough transformation is applied to it and I get this result:
This is very good result but I need just one line from each bundle so I can display that the object from the first picture resembles a triangle. My first decision was to calculate some sort of "average" line for each bundle. Each line is defined by an angle and a raduis. My way of finding the "average" line for each bundle is to calculate the average of the angles using this formula:
avgTheta = arctan(sum of sines of all thetas/sum of cosines of all theta)
I calculate the average raduis in the simplest way:
avgRadius = sum of all raduises / number of raduises
However the lines I get are not in the center of their bundles.
Can someone please advise for a better solution?
I am using this implementation of the Hough Transformation: Hough Transform
There is always the option to take one line of each bundle randomly, but I don't like it.
If my question is not clear please tell me in order to try to explain the problem better.
Thanks in advance.

You could try this:
Take the average angle without any cosine, sine or arctan function. Just make sure that you handle the wrap. Based on the implementation you linked to it seems to me that you wrap at pi (180 degrees). In your image the bundle of almost vertical lines on the right side of the "island(?)" will be a good example of lines that are on both sides of the wrap.
Also you probably get the best result if you have weighted lines based on how many points they include from the Canny edge detection picture, and then use this weight in the average calculations. Maybe this is already done by having multiple lines with the same properties, I could not tell from your image or the linked code.

Related

Convert Latitude and Longitude values to a custom sized grid

I am making a java program that classifies a set of lat/lng coordinates to a specific rectangle of a custom size, so in effect, map the surface of the earth into a custom grid and be able to identify what rectangle/ polygon a point lies in.
The way to do this I am looking into is by using a map projection (possibly Mercator).
For example, assuming I want to classify a long/lat into 'squares' of 100m x 100m,
44.727549, 10.419704 and 44.727572, 10.420460 would classify to area X
and
44.732496, 10.528092 and 44.732999, 10.529465 would classify to area Y as they are within 100m apart.
(this assumes they lie within the same boundary of course)
Im not too worried about distortion as I will not need to display the map, but I do need to be able to tell what polygon a set of coordinates belong to.
Is this possible? Any suggestions welcome. Thanks.
Edit
Omitting projection of the poles is also an acceptable loss
Here is my final solution (in PHP), creates a bin for every square 100m :
function get_static_pointer_table_id($lat, $lng)
{
$earth_circumference = 40000; // km
$lat_bin = round($lat / 0.0009);
$lng_length = $earth_circumference * cos(deg2rad($lat));
$number_of_bins_on_lng = $lng_length * 10;
$lng_bin = round($number_of_bins_on_lng * $lng / 360);
//the 'bin' unique identifier
return $lat_bin . "_" . $lng_bin;
}
If I understand correctly, you are looking for
a way to divide the surface of the earth into approximately 100m x 100m squares
a way to find the square in which a point lies
Question 1 is mission impossible with squares but much less so with polygons. A very simple way to create the polygons would to use the coordinates themselves. If each polygon is 0.0009° in latitude and longitude, you will have approximately square 100m x 100m grid on the equator, put the slices will become very thin close to the poles.
Question 2 depends on the approximation used to solve the challenge outlined above. If you use the very simple method above, then placing each coordinate into a bin is just a division by 0.0009 (and rounding down to the closest integer).
So, first you will have to decide what you can compromise. Is it important to have equal area in the polygons, equal longitudinal distance, equal latitude distance, etc.? Is it important to have four corners in the polygon? Is it important to have similar or almost similar polygons close to the poles and close to the equator? Once you know the limitations set by your application, choosing the projection becomes easier.
What you are trying to do here is a projection onto a flat surface of an ellipsoid. So as long as your points are close together, and, well, you don't mind getting the answer slightly wrong you can assume that your projection plane intersects in the centre of your collection of points, and, each degree of lat and lon are a constant number of metres. Then the problem is a simple planar calculation.
This is wrong, of course. I would actually recommend that you look into map projections, pick one that makes sense, and go for that. Remember that you can move the centre of the projection to the centre to your set of points which will reduce distortion.
I suspect that PROJ.4 might help you in terms of libraries. There also must be a good Java one but that is not my speciality.
Finally you can could assume that the earth is a sphere and do your calculations on the sphere. Or, if you really want to get it right you can pick a standard earth ellipsoid and do the calculations on that.

Polygon "Fixing" Algorithm

I bring you a maybe complex question which i would love your help with. Allow me to go straight to the point:
I desire an algorithm or logic in which i draw a shape using my mouse (for example a square) and it becomes a perfect square, with all the 4 sides in straight lines and perfectly regular. A human-drawn square is hardly perfect, but i wish that after it goes through the "filter" of this algorithm ,it becomes such.
A fine example of what i wish is in the game Trine, where the Wizard works by a similar principle: You draw a shape in the screen and it becomes the closest shape, that is, if you draw something similar to a square it becomes a perfect square box, but if you draw a triangle it becomes a perfect triangular box. Its like it detects what kind of shape it is and then draws a better version of it.
I want this for a game, just so you know what is the goal of all this.
Please help me figure out either the algorithm or logic behind this, or at least tell me what is the name of this kind of action (:
P.S. i added a simple image so it becomes even more clear what i intend =)
If I had to implement this task, I would store the recognizable patterns, and would try to make a match for them.
Take the minX, maxX, minY, maxY values form the user-drawn points, that will help you to scale the pattern. Choose the scaling so that the aspect ratio for the pattern would be the average of the X and Y aspect ratios.
The patterns can consist of certain number of straight lines. The pattern matches if
There are no points outside of the threshold
There is at least one user-drawn point close to each key points in the pattern
If you have the pattern matched, you will have the key points for your pattern (calculating the center of your pattern, and the size/aspect ratio). Then you can replace the user-drawn points with your image - that may be totally different from the pattern used to match (imagine a circle).
There are many ways to do this. One way that you could do it is to create a neural net that recognizes these shapes. I would generate variations of circles, squares, lines, and triangles with random perturbations to replicate "hand-drawn" versions. Then you would want to represent this as a two-dimensional array (where locations that have been drawn on would be 1's and locations that haven't been drawn on, would contain 0's). You can then convert this two-dimensional array into an input vector of n x n elements. The output of the neural net would be a vector with four elements, each one representing either a line, circle, square, or triangle. You would then train this neural net using your randomly-perturbed images until you end up with a neural net that recognizes the input with an error that is under some error-threshold. This is actually quite similar to recognizing handwritten digits.
Other ways include:
Shape contexts.
k-means clustering
Support vector machines
You don't have just an arbitrary shape, you also have the shape's path. So try counting corners. Decide on a angle threshold that will represent a corner. For each point, sample the next consecutive x number of points. Measure the angle between the first half and second half. If the angle surpasses your threshold, consider it a corner. (Obviously select the point that give you the best angle with the least amount of error, not just the first one that surpasses the threshold.) Mark the location of the corners and draw your shape to match.
Ellipses & lines: if no angles are detected, sample a few segments. Measure the orientation. If they are very similar, then line. If very different, then ellipse. If ellipse, find the bounding box and draw inside.

Calculating a point in 3D space

I am trying to locate a point in 3D space relative to the origin (0,0,0). I have 3 values to calculate this point with: a rotation in degrees about both the x and y axis as well as a "view distance". Using these values, how can I locate a point in 3D space relative to the origin? I have tried using basic trigonometric functions, but the results seem to be random. The image below gives a visual as to what needs to be done.
'vd' being the "view distance"
'c' being a value holder
'(x,y,z)' being the coordinate I am trying to find
What I am trying to do is find the point a player is looking at a certain distance away (find a point in the direct line of sight of the player out a certain distance). Keep in mind, the rotations about the x and y axis are constantly changing, but the view distance remains the same. If anyone has any suggestions, methods of how to do this, or needs clarification, please comment/answer below.
I am doing this in LWJGL, and the code I am using is as follows:
float c = (float)(Math.cos(Math.toRadians(A00.rot.y)) * view_distance);
locate.y = (float)(Math.sin(Math.toRadians(rot.y)) * view_distance);
locate.x = (float)(Math.cos(Math.toRadians(rot.x)) * c);
locate.z = (float)(Math.sin(Math.toRadians(rot.x)) * c);
EDIT:
My issue is that this current setup does NOT work for some reason. The math seems legitimate to me, but I must have something wrong somewhere in the actual setup of the graph..
I suggest looking up quaternions. No need to fully understand how they work. You can find ready made classes for java available on the internet as well. Quaternions allow you to represent a rotation in 3D space.
What I would then do, is to start with a vector representing the direction pointing forwards from the origin, and apply the same rotation that the player currently has to it. Now it is pointing in the same direction as the player. Now if you take the player's current point, and the direction vector we now have a ray describing where the player is looking at.
I suggest this link for further information on quaternions. They may look complex but, as I said, you don't need to fully understand how and why they work to be able to use them. Just copy the formulae and learn how they are used. Once you figure out how to use them, they make 3d rotations really easy.
http://content.gpwiki.org/index.php/OpenGL:Tutorials:Using_Quaternions_to_represent_rotation

How to detect a quadrilateral shape in an image in Java?

I want to detect a quadrilateral shape in an image in Java. I can use the HoughLinesP method in OpenCV (using javaCV for opencv java binding) to detect line segments. But I can't figure out how to detect a quadrilateral shape - is there another method for that or some way to use the hough lines? Also once the corners of the quadrilateral are detected, I want it to return a rectangle just like this class does - http://www.aforgenet.com/framework/docs/html/7039a71d-a87d-47ef-7907-ad873118e374.htm - is there an equivalent library in openCV?
How do your input images look like? If you detect lots of line segments with the Hough transformation, you could maybe try using RANSAC to generate a number of quadrilateral shape hypothesis, find a way to rate their fitness and return the best hypothesis.
One hypothesis could be generated like this:
choose four random line segments from the detected line segment set
find the four corners by looking for intersections of the lines the chosen line segments lie on
rate the fitness of the quadrilateral shape defined by these four points
The fitness could maybe be the area of the hypothetical quadrilateral (see the Bretschneider's formula for calculating the area of a convex quadrilateral), the distance of the quadrilateral edges from the other line segments in the detected set, or something that better fits your application.
This is just an idea, I haven't tried using this approach yet (but I'm planing on implementing something similar). Let me know if you think this could work, or why it won't! :)
Your algorithm could be something like this
Process the image to find edges (Canny filter)
Apply Hough Transformation to find lines
Detect pairs of lines that intersect with an angle of 90 deg (aprox)
If you use OpenCV library than you definitely should try FindChessboardCorners function. And also here's a good tutorial.

Calculating geospatial bounding box without map data

I am looking for an algorithm that would let me find an enclosing bounding box for a lat/long without using map data. Essentially I want to be able to define grids for the planar world map given a set size and then plot which grid a lat/long falls in.
Does anyone know of previous work that might have been done in this? Are there standard ways of doing this over home grown solutions where I create a hash map (or the like) of my own bounding boxes for the world and do lookups etc.
I dont want to utilize actual cartography for this. Just looking for some math that would return a fixed bounding box for all the lat/longs that fall under it
Thanks for your help!
I guess you mean that you want to do something like cover the surface of the Earth with squares (or rectangles) of a fixed size, perhaps 100km square, and figure out a way of mapping from any (lat,long) coordinate pair to the square in which it sits ? Well, forget about that, it can't be done, there is simply no way to cover the surface of a sphere (ignore the slight non-sphericity of the Earth for this discussion) with squares of the same size.
You might be interested in Universal Transverse Mercator which is close to what you want to do but it will require you to engage with some of the mathematics of map projections. I see no way around this.
I exclude from consideration that you would be satisfied with 'squares' of equal angular measure, I mean (for example) something like 'squares' of 2 degrees of lat or long on each side. The maths for that would be trivial and you wouldn't have asked here on SO for guidance.

Categories