Using GraphicsPath to draw roads on a map image - c#

I have an application (WinForms C#) that allows users to draw a line (free draw) to highlight roads of interest on a bitmap taken from Google Maps.
I am using the Mouse Down/Move/Up events to add points to a GraphicsPath object. This works well for straight stretches o road that can be represented by just two points. But when the mouse draws turns with the button down for long periods, a lot of point data is generated.
This is not only inefficient but also a clunky way to draw over curves (specially when the zoom level is too low).
Question:
Once the path is complete, how can I programatically reduce the number of points without losing accuracy.
Is there a better way to capture point information using some form of geometric construct?

A commonly used way to reduce the number of points in a polygonal curve is the Ramer–Douglas–Peucker algorithm. It is perfectly suited for reducing the number of points in a map drawing, e.g. a route.

Related

3D z-buffer c# GDI plus

Im writting very simple 3d engine in c# and GDI+, just for render some models (I think Directx or OpenGL is like shovel to eat soup). So far I have succesfully implemented drawing Wireframe of my model, but next step is of course Faces. And there is my problem, for now I just project my 3d points to 2d point and then drawn it using simple
for each faceg.DrawPolygon(Pens.Red, projected_points); and for wireframe its ok.
It is possible to calculate overlapping part of polygon? and then draw FilledPolygon,
Or better idea is drawing pixel by pixel and if z-buffer of my pixel is further then set new pixel.
If first option is possible, which one is faster (for implement and calculating)?
It is possible to calculate overlapping part of polygon? and then draw FilledPolygon, Or
better idea is drawing pixel by pixel and if z-buffer of my pixel is further then set
new pixel.
If first option is possible, which one is faster (for implement and calculating)?
Yes, it is possible. You can test every polygon with every other of your list. The complexity depends on the type of the polygon (of course, it's easiest with triangles). But the performance may drop drastically with high count of polygons. And even if you find the overlapping areas, you will need to interpolate colors, or texture coordinates (if you plan to use such). Also I'm not sure about the API you use for drawing, but GDI doesn't support fill polygon with interpolated colors.
I have heard that this was the approach used in 3d graphics before inventing the Z buffer. :)
I once tried to realize similar project and used Z-buffer + my own routine to fill triangles with interpolated colors (which uses the Z-buffer). I drawed directly to a GDI bitmap's pixel data buffer. Then after all polygons has been rendered, I bitblt'ed the result to the screen.

Detect mouseover of non-square part of an Image

So I am working on a Risk type game in XNA/C#. I have a map, similar this one, and I need to be able to detect mouseovers on each territory (number). If these areas were squares, it would be easy, as they could each be represented by a rectangle. However, they are different size polygons. Is there a polygon shape that behaves similar to a square? If there isn't, how would I go about doing this?
I sugest this:attach color to each number, recreate your picture in these colors: every shape will be in its particular color. Dont draw it onscreen, use it only as reference map. And when the user clicks or moves mouse over your original map, you just simply project mouse coordinates into the color map, check the color of pixel laying under the mouse and because you have each color associated to number of territory...
This is not c# specific (as I've never written anything in the language, so no idea of what apis there are), though there are 2 algorithms that come to mind for detecting if a point is inside a polygon (which can be used to detect if a mouse point is over another polygon/map shape).
One is based on raycasting, where you cast a ray in 1 direction from the (mouse) point to "infinity" (edge of the board in this case) and count the number of times it crosses the polygon's edges. If it is odd, then the point is inside the polygon, if it is even, then the point is outside of the polygon.
A wiki link to it: http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm
The other algorithm that comes to mind works only for triangles I think but it can be more simple to implement I think (taking a quick glance at your shapes, I think they can easily be broken down into triangles and some are already triangles). It is to do with checking if the point is on the same (internal) "side" of all the edges in the triangle. To find out what "side" a point is on vs an edge, you'd take create 2 vectors, the first vector would be the edge itself (made up of 2 points) and the other vector would be the first point of that edge to the input point, then calculate the cross product of those 2 vectors. The result will be negative or positive, which can be used to determine the "direction".
A link to it: http://www.blackpawn.com/texts/pointinpoly/default.html
(On that page is another algorithm that can also work for triangles)
Hit testing on a polygon is not so difficult to do in real time. You could use a KD-Tree for optimisation if the map is huge. Otherwise find a simple Contains method for a polygon and use that. I have one on another computer. Let me know if you'd like it.

how to correct scan mistakes, like rotation?

I'm trying to scan some pictures together (personal 3x4 cm images) and then split them into separated images. the first step about scanning is done but about second step (edge detection and splitting) I've some problems.
1- Normally when they scan pictures, some pictures rotate some degrees and its preventing me to have straight edges.
2- How do I remove big noises? (Imagine when they scan those pictures, they put a paper behind them. sometimes the paper makes some edges in the scanned picture... how can I understand that its not the edge I'm looking for?)
Here is a sample image:
The sample images within the scan are all rectangular, and they are all roughly the same size. There are a variety of techniques for finding rectangles in an image (even at completely arbitrary rotation), but I'll start with the more fundamental techniques.
Hough line fit can be used to find lines in an image, even when the background is noisy. From the Hough line fits you can find intersection points and perhaps compare those intersection points to points found with corner detections (see 3 below).
Edge points on lines have gradients perpendicular to those lines. When searching for edge points, you can favor edge points that are roughly a distance L or a distance W from other edge points with gradients in the parallel direction, where L and W are the known length and width of your images.
Corner detectors can help identify corners of your small rectangular images. You know the length and width of the pictures, which should help you accept/reject corners.
If you want to get fancy (which I don't recommend), then a simple normalized cross-correlation technique could detect all instances of a "template" subimage within a larger image. The technique is a bit crude, but it works okay if there isn't much rotation. Since the subimages have well-defined borders of known shape and (presumably) consistent size, it'd be easier just to find the edges rather than try to match the image content.
Once you've identified the location and orientation of each rectangular subimage, then a simple rotational transform + interpolation could generate a "right side up" version of each image. With scanners you won't have problems with perspective distortion, but if at some point in the future you would take pictures of pictures (?) at an angle, then an affine transform can map the distorted, trapezoidal images to rectangular images.
Hough transform
http://en.wikipedia.org/wiki/Hough_transform
Corner detection
http://en.wikipedia.org/wiki/Corner_detection
For simple edge detection that should work sufficiently well for your application, see the section "Other first-order methods" in the Edge Detection article on Wikipedia. The technique is easy to understand and simple to implement.
http://en.wikipedia.org/wiki/Edge_detection
Good luck, and once again Happy New Year!

Position images along a Bézier curve

We currently have a dynamic image, which holds on it text which is created from user input. This text follows a Bézier curve to define its position and rotation.
For various reasons, the text needs to be changed to be a set of images as the font needs to be very specific. We will therefore have one PNG for every allowable character of the alphabet. So if the user enters the word "TEST", the system will pull out the letters T, E, S and T and position them next to each other. This part isn't an issue.
The problem is forcing each of the images to follow the same Bézier curve as the text did using graphics.DrawString. The images must be positioned correctly, and ideally should be rotated correctly as well.
Is this possible, and how could this be done?
The quick answer is that you "simply"
parametrise the bezier curve evenly (PDF on math) (Explanation of what is wrong with standard parametrisation)
calculate the normals to the curve
arrange your images along the curve according to the even parametrisation using the glyph widths as the parameter distance
rotate your images so that "up" for your image is the normal direction to the curve
But even this does not get a fairly good looking image. Usually you need to apply a nonlinear transform to each image so that parts away from curve have different width than those near the curve, depending on curvature and convexity.
This site explains many of the details by decomposing the outline of an image in paths
However, as the previous links I'm sure start to show, this is a calculation-intensive process. Instead, you may find it much easier to simply convert your images to fonts and use the method you were using previously. This solution would rely upon some third-party tool to do the conversion, and I hesitate to make suggestions. One direction, though, (of many) would be to use a raster-to-vector graphics tool like the open source Inkscape and create your fonts from the vector graphics output. This method scales best but may involve a separate step of converting the output to a preferred font format like True-Type.

Detect marker in 2D image

I am hoping to obtain some some help with 2D object detection. I'll give a brief overview of the context in which this will be implemented.
There will be an image taken of the ceiling. The ceiling will have markers placed on it so the orientation of the camera can be determined. The pictures will always be taken facing straight up. My goal is to detect one of these markers in the image and determine its rotation. So rotation and scaling(to a lesser extent) will be the two primary factors used in the image detection. I will be writing the software in either C# or matlab(not quite sure yet).
For example, the marker might be an arrow like this:
An image taken of the ceiling would contain markers. The software needs to detect a single marker and determine that it has been rotated by 170 degrees.
I have no prior experience with image analysis. I know image processing is a fairly broad topic and was hoping to get some advice on which direction I should take and which techniques would be best for my application. Thanks!
I'm not directly in this field but I would tell you to start by looking into edge detection specifically. If you have a background in math/engineering the materials are pretty easy to understand:
This seemed to spark some ideas:
http://www.cfar.umd.edu/~fer/cmsc426/lectures/edge1.ppt
I'd recommend MATLAB or if you're intent on using C#, Emgu CV is pretty good.
Hough transforms are a great idea. Once you detect the edges in your image, using, say a Canny edge detector, you get an edge image (which is binary image with only 1 or 0 for values).
Then, the Hough straight line transform (essentially) spins a line about each white pixel in the edge image (the resolution of the line depends on you) using a parametrized function for the line and calculates the total number of white (valued at 1) pixels along each spun line and stores this information in a big accumulator which stores the data indexed by the parameters of the line.
alt text http://upload.wikimedia.org/wikipedia/en/a/af/Hough_space_plot_example.png
In the example above, the parametric form for a line is:
rho = x*cos(theta) + y*sin(theta)
where rho is the distance and theta is
the angle
So as you can see the, if you look at the bin at a particular orientation you can find out how many lines are oriented at that angle. Of course, you'll have to do some extra work to figure out which lines are oriented at that angle since you have 5 other lines per arrow but that shouldn't be too hard.
as always in computer vision, your first problem is image illumination and acquisition. before going further, establish how your markers will be printed on the ceiling, what their form will be, what light you will be using to see them, and what camera setup you will chose to look at the markers.
given a good material, a good light and a good camera, you may have no problem at all to process the image. for example, you can print a full arrow in a retro-reflective material, with a longer tail than your example, use a colored light and a corresponding filter on the camera. now all you have on your image is arrows... there are plenty other ways of acquiring the image that will help you there.
once you have plain arrows, a simple blob analysis (which consist of computing statistical moments of objects in the image) will give you a lot of informations: each arrow should have values almost equal for the 7 hu moments, which allows you to filter objects efficiently, also the orientation computed from the central moments will give you the angle of the arrow. blob analysis being only statistical, it is extremely fast.
Several systems have been developed to detect markers and their orientation robustly:
reacTIVision (open source) uses these types of tags to find position and orientation:
ARToolKit (open source) uses a different type of tags to extract all 6 degrees of freedom:
alt text http://www.schanes.net/docs/robot/marker.png
If your primary goal is not to learn, but to make the application work, I would suggest you use one of these. It is not a trivial task for a beginner to robustly detect the position and orientation of a random marker in an image.
On the other hand, if you are manly interested in learning, I would also direct you to ARToolKit and its publications (and their references) that explain how to robustly implement marker detection.
You will need to explore edge detection, so look into Hough filters. After that you will need to look into pattern classifiers and feature extraction.
This paper has an algorithm that appears to work without edge detection.
This book excerpt is more oriented toward the kind of symbol detection you intend, once you have done the edge detection.
A rigorous way to determine the orientation of an imaged acquired under projective geometry (most of cameras) is using the vanishing points and vanishing lines. Good news to you: your marker can be used to find this information! More good news, your image can be rectified, so the image columns (the y-axis) will correspond to the up-down direction. You will find more about this stuff in chapter 8 of Hartley and Zisserman's book, Multiple View Geometry in Computer Vision.
Also remember that probably you will need to work on the radial distortion issue, the distortion caused by the camera lens. The other guys are right about the arrow detection problem: you have to use edge detection and, after that, Hough transform or template matching. Refer to Gonzalez and Woods' book Digital Image Processing for details.

Categories