Detect marker in 2D image - c#

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.

Related

Intersecting ellipses recognition in image C#

For a research project, I have to find the ellipses in a fossil image.
For each fossil image, I also have a CSV file containing the contour of the fossil, in cartesian coordinates.
I need help in determining the starting and ending points of each ellipses that are present in the fossil, so that I can apply a ellipse-fitting algorithm on them.
I started to look at the possibility of studying the variations in the different slopes of the contour.
It somehow worked, until the point where I tried on fossils that have very low curve variations. As you can see on the image below (click the link), the pink points are where the variation of the slopes of the contours are the highest. However, it doesn't work for the bottom ellipse.
So I need a new approach on that. Do you have any hints or ideas where I can look at ?

How to find rotation angle of image?

I'm feeding in a Bitmap image to my C# program to be able to perform OCR to identify the characters in the image. I can do this fairly well if the image is not rotated. One of the program requirements, however, is that the program automatically determines if the image has been rotated, and that it automatically corrects these rotations.
I've tried implementing a simple method where lines are traced across the image and points which contact a character are recorded, and then performing a simple linear regression on the line points. This works to an extent, although it has not proven very accurate due to curvature of characters, etc.
I was wondering if there was a better method to solve this problem? Many thanks in advance! :)
I use gmseDeskew algorithm to deskew an image in my program. It works very well.
It's an interesting problem to be sure. I'd look for certain letters that are easier to tell rotation for. For example, a capital A or R or K should have both of the lower parts are roughly the same horizontal plane. Another option is to take letters that cannot be identified and rotate them in various ways and re-attempt to identify them. If a letter than could not be identified in the raw scan CAN be identified when you rotate it, that's a pretty big clue. Once you have identified the "correction" rotation that makes a non-recognizable character into a recognizable one, apply the same rotation value to the others.
If it recognizes lines of text, then try to blur the image so that lines are mostly solid and find direction of the lines (either with analysis of Fourier transform or by ridge detection).
If the text is formatted like a printed document (column(s) and lines of text) then you can take advantage of this.
An approach that I've often seen used for document text is to do projection profiles:
Scan a document at a specific orientation and sum up the number of "black" pixels on each scan line (creating a 1D array of counts, each index representing a Y coordinate, the profile).
Calculate the variance of the counts (profile).
Repeat for multiple angles, (can be done in a binary search fashion to reduce processing)
The angle that results in the greatest variance is the correct angle (due to the text lines creating large peaks from the printed text, and low valleys due to the absence of text between the lines)
Then after finding this angle you can adjust your image accordingly and do your awesome OCR.
It might be easier to find the vertical-ish lines that are adjacent to the text (i.e., the left margin). For each scanline, record the first black pixel. Put all of those in a linear regression, and you should get a near vertical line. Measure its angle from true vertical and you should be able to unrotate the text. You could imagine doing the same thing for the top, bottom, and right sides, too, and taking an average.
We faced a similar problem before, and we searched for an easy and quick solution, and we ended up using a commercial toolkit (leadtools). You can use it to do auto processing to the image before OCR it. You can check this help topic to know how to use this toolkit to process and scan images.

How to detect water level on an image?

My homework is to write a very simple application (Java or C#, I know both), which can detect water level of a glass of water / coke in a picture (it have to draw a line there). I don't even know how to start it. I have googled all day, but have found no useful results. Are there any good algorithms, which can detect the level of the liquid?
The photo is taken from the side, like this:
(it's also good if it detects both lines). So could you help me out with how to start? Use egde detection (are there any good basic algorythms?), or other method?
It would be best would be if it detected water, coke, and every liqued etc....
You are going to have to do some edge detection and then once you have the edges, try and find the level within the glass. You could use a toolkit like Aforge.NET. Then code to detect the edges is pretty simple, for example:
Bitmap b = new Bitmap(Image.FromFile(#"C:\Temp\water.jpg"));
// create filter
Edges filter = new Edges();
// apply the filter
filter.ApplyInPlace(b);
pictureBox1.Image = b;
Yields an image like this:
Now it should be a little bit easier to find the point of water in the glass. Since all of the background noise has been eliminated, you can focus on determining which edge you should key off of.
Check Hough transformation here
It will help you to get the capacity of the glass in question.
Once you know how much water a glass can hold, you can draw two lines onto the image using functions that you write your self. I would advise one line for the glass size and one line for the water level super imposed over the image, you can then use these lines and the maximum capacity of the glass to form a correlation between the two and calculate the level of fluid contained within the glass.
Remember that your professors aren't interested so much in you getting the assignment 100% correct, they are more interested in preparing you to solve problems using your own initiative. Google searching can't always solve your problems.

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.

Categories