get the pixel count between two points in a bitmap - c#

I am beginner in C#.NET .I am on a project to process approach maps.this map contains the surrounding area of a runway,where the flight can fly in order to land.
this map is a bitmap image.it contains longitudes and latitudes on the borders of the image!
now the aim of the project is to get the geological coordinates(lats/long) of points on the map,(when clicked or hovered on that point by mouse,) based on the given geological coordinates on the border of the map.so if we give the input for a point with its lats/long coordinates the other points on the map can be interpolated.
suppose there be X pixels between any two longitudes and Y pixels between any two latitudes.if we set a reference point ,then depending on the distance(number of pixels from the reference point in x and y direction individually) of the pixel that is being hovered or clicked by mouse pointer we can get the lats/longitudes of that point in a small window(may be like tool tip or pop up).
the math surrounding the interpolation can be:
new lat= ref lat + [ref lat(only minutes)/Y] *(vertical distance between reference point and new point in pixels)
new long= ref long - [ref long(only minutes)/X] *(horizontal distance between reference point and new point in pixels).
there is a point called mid point on the centre of the run way(at the centre of the graph).i also need to find the angle made by line joining midpoint and new point(where the mouse hovers or clicks) with the verticle of the map.
so any one please give me ideas how to start the project and what are things (tool bar controls,methods) i require to build the gui containing picture window and pop up window(containing information about that point or pixel) where ever i click the mouse .thanks in advance.

The question asked in the headline is answered as follows:
double distance = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
That's the distance between two points on a plane, and hence on a bitmap.
The question asked in the body isn't answered easily at all. If you have a given map, the function defining the distance between two coordinates may not be linear. Here's an article on Map projection that shows some of the different map types. To be able to calculate what you need, you first need to know what kind of map you're actually working on, and hence adjust your formulas accordingly.
If your map is only of small size, this may not make much of a difference. You were talking about a runway at one point, if this is just for one airport, then projection isn't necessarily an issue. If you're working out distances between two runways of different airports, that will be a different matter.

Your question is quite specific to your needs and has a few elements that could be questions in their own right. You might want to break it down into several questions and or research each item independently. e.g.
You'll want to look into WPF or Windows Forms.
You'll need to learn how to calculate the angle between two points.

Related

Compare two sets of XY Coordinates and align them

I have two sets of X,Y co-ordinates as separate lists. Both represent the same irregular polygonal shape, but in different orientations and sizes/scale.
Need to write a program in C#, to compare both the points set, rotate any one of the shape such that it aligns with the another, so that they are in same orientation.
Tried searching for solution, and got to know using concave hull with angles difference can help, but could not find a good C# implementation for the same.
Can some one help me, if there is a minimal way to achieve this?
Edit: The two points-set might not be the same. One may contain more points than other.
I have contour co-ordinates of a shape and a PNG which is of same shape, but orientation is different. I want to read the PNG, calculate the angle to turn it to the fit the Contour.
Calculate image moments for point cloud
Evaluate orientation of both clouds with Theta angle.
Rotate one cloud by theta difference.
Use other moments (centroid etc) to find translation and scale

c# how to detect intersecting circles as separate from edgepoints

I am trying to create a 2(or more) circles from a list of edgepoints which is sorted. A egdepoint is just a point. A list of edgepoints make the edge of a circle. Drawing a line between the edgepoints gives the black line in the pictures. So there is no radius and circles can vary in size.
It looks like this:
My idea is to split it like picture 2. Next, create circles like in this article. Ofcourse with the fist, middle and last point.
I created a method to detect whether the edgepoints are sorted clockwise or counter clockwise. Unfortunately I am stuck on how to detect these "split points" The picture can be rotated ofcourse.
The result should be 2(or more) list with edgepoints:
So how can I detect these "split points"? Or is there a better way to detect intersecting circles as separate?
Input: Something like Point[]. Output: Something like List[Circle]
Assume input is sorted by position around the outer edge of some picture that is made up of overlapping circles. Any points in the interior of the picture are not included.
I thought about it more and I think you can find the points easier if you consider slope. Points where the slope varies wildly are the points you are looking for.
[Revised thought - Find the transition points first, then the circles.]
Start by using a function to calculate the slope of a line segment between two points. As you go around a circle, you will have a reasonable change in slope (you will have to discover this by reviewing how close the points are together). Say you have points like { A, B, C, D, ...}. Compute the slope of A->B and B->C. If the points are evenly spaced, that difference or the average difference might be a tolerance (you have to be careful of transition points here - maybe compute an average over the entire set of points). If at some point the slope of K->L and L->M is very different from J->K and K->L then record that index as a transition point. Once you have traversed the whole set (include a test for Y->Z and Z->A as well if it is a closed shape), the recorded indexes should define the transition points. Use the mid-point of each segment as the third point for each circle. (e.g. if you identified I and M as transition points, then use I, K, and M to define a circle).
[Original thought - find the circles first]
Use the referenced article to determine the center of a circle based on three points. Then determine if it is really an interesting circle by testing some of the points around the reference points. (Say, pick every 5th or 10th point then verify with all the interior points). With more overlapping circles, this becomes a less effective process so you will have to define the algorithm carefully. Once you get all the reference circles, process through all of the edge points (assuming these are points on the exterior of the drawing). Using center, radius, a distance formula, and a tolerance, determine which points are on which circle. Points that fit the tolerance on more than one circle are the points you are looking for I think.

How to sort found chessboard corners?

I have a question about sorting found corners from chessboard.
I'm doing my program in C# using OpenCVSharp.
I need to sort found corners which are points described by X and Y.
This is the part of my code:
...
CvPoint2D32f[] corners;
bool found = Cv.FindChessboardCorners(gray, board_sz, out corners, out corner_count,
ChessboardFlag.NormalizeImage | ChessboardFlag.FilterQuads);
Cv.FindCornerSubPix(gray, corners, corner_count, new CvSize(11,11), new CvSize(-1,-1),
Cv.TermCriteria(CriteriaType.Epsilon | CriteriaType.Iteration, 30, 0.1));
Cv.DrawChessboardCorners(img1, board_sz, corners, found);
...
After that I'm displaying found corners in ImageBox:
see good order in all pictures
and this is the order of corners what I need always, but when I rotate the chessboard a bit - found corners changes like this:
see bad order in all pictures
I need always the same (like in picture 1) order of these points so I decided to use:
var ordered = corners.OrderBy(p => p.Y).ThenBy(p => p.X);
corners = ordered.ToArray();
but it doesn't work like I want:
see bad result 1 in all pictures
see bad result 2 in all pictures
The main point is that my chessboard won't be rotated too much, just for a little angle.
The second point is that the corners must be ordered from the first white square on the top left side of the board.
I know, that the base point (0,0) is on the left top corner of the image and the positive values of Y are increasing in the direction to the bottom of image and positive values of X are increasing in direction to the right side of image.
I'm working on the program to obtain this ordering (these pistures are edited in picture editor):
see example 1 in all pictures
see example 2 in all pictures
Thanks for any help.
Please find below some examples for how OpenCV's findChessboardCorners might return the corner point list and how drawChessboardCorners might display the corners.
For more clarity the order of indices of the subscribing quadrilateral is added as 0,1,2,3.
Basically there are 4 possible rotations of the result leading to the initial red marker being either:
topLeft
topRight
bottomLeft
bottomRight
So when you'd like to resort you can take this knowledge into account and change the order of indices accordingly. The good news is that with this approach you don't have to look at all the x,y values. It's sufficient to compare the first and last value in the list to find out what the rotation is.
To simplify the sorting you might want to "reshape" the list to an array that fits the chesspattern that you supplied to findChessBoardCorners in the fist place e.g. 9x9. In Python numpy there is a function for that i don't know how this would be done in C#.
Work on straightened points. Determine the slope of the image, for instance by taking the difference of the upper right and upper left points. See Rotation (mathematics). Instead of taking the cos you could as well take -diff.Y (the minus because we want to rotate back) and diff.X for the sin. The effect of taking these "wrong" values will result in a scaling.
Now determine the minimum and maximum of x and y of these straightened points. You get two pieces of information from these: 1) an offset from the coordinate origin. 2) The size of the board. Now rescale the transformed point to make them have coordinates between 0.0 and 8.0. Now if the image was perfect all the points’ coordinates should have integer values.
Because they don't, round the coordinates to make them all integers. Sorting these integer coordinates by y and then by x should yield your desired order. This is because the points on the same horizontal line now really have the same y value. This was not the case before. Since they probably all had different y-coordinates, only the second sorting by x had an effect.
In order to sort the original points, put the transformed ones and the original ones into the same class or struct (e.g. a Tuple) and sort them together.

How to find a shape in a series of mouse clicks?

I was wondering how (if at all) it would be possible to determine a shape given a set of X,Y coordinates of mouse clicks?
We're dealing with a number of issues here, there may be clicks (coords) which are irrelevant to the shape. Here is an example: http://tinypic.com/view.php?pic=286tlkx&s=6 The green dots represent mouse clicks, and the search is for a square at least x in height/width, at most y in height/width and compromised of four points, the red lines indicate the shape found. I'd like to be able to find a number of basic shapes, such as squares, rectangles, triangles and ideally circles too.
I've heard that Least Squares is something that would help me, but it's not clear to me how this would help me if at all. I'm using C# and examples are more than welcome :)
You can create detectors for each shape you want to support. These detectors will tell, if a set of points form the shape.
So for example you would pass 4 points to the quad detector and it returns, if the 4 points are aligned in a quad or not. The quad detector could work like this:
for each point
find the closest neighbour point
compute the inner angle
compute the distance to the neighbours
if all inner angles are 90° +- some threshold -> ok
if all distances are equal +- some threshold (percentage) -> ok
otherwise it is no quad.
A naive way to use these detectors is to pass every subset of points to them. If you have enough time, then this is the easiest way. If you want to achieve some performance, you can select the points to pass a bit smarter.
E.g. if quads are always axis aligned, you can start at any point, go right until you hit another point (again with some thresold), go down, go left.
Those are just some thoughts that might help you further. I can imagine that there are algorithms in AI that can solve this problem in a more pragmatic way, maybe neural networks.

Coordinate translation issues

I've been handed a csv file containing a series of coordinates, from which lines should be drawn on top of a bitmap grid; I can get the values out and convert them into ints for the DrawLine function, etc, just fine.
The problem is that these coordinates are basically percentages; x:0.5 and y:0.5 represent dead centre (being 50% of X and 50% of Y) and x:1.0/y:1.0 would be in the top right regardless of the absolute dimensions of what is being plotted on to (in this instance a 1000x1500 bitmap). In addition screen/window coordinates start in the top left which doesn't affect the x-axis but the y-axis needs to be somehow inverted.
So what do I need to do to the coordinates to get them to plot correctly? To be honest I've got the X-axis working fine, it's the Y-axis giving me the problems.
(The window containing the bitmap is 1600x1600, FWIW.)
Well the naive way is to simply calculate the single closest pixel i.e. round(WIDTH*x)
But thats bad generally, because some pixels would be left blank, some would be mapped multiple times.
What I'd do is to calculate the percentage of covering per each point - i.e. a point can cover 75% of one pixel, and 25% of it's neighbor and then fill the color of a pixel accordingly.
Without more details of what is wrong, I'll take a guess and say that you are calculating your Y value up-side-down. Try it this way:
round(HEIGHT*(1.0-y))
Then, give us more details of what you are having trouble with.

Categories

Resources