views:

658

answers:

5

Hi folks,

I'm trying to develop an image focusing algorithm for some test automation work. I've chosen to use AForge.net, since it seems like a nice mature .net friendly system.

Unfortunately, I can't seem to find information on building autofocus algorithms from scratch, so I've given it my best try:

take image. apply sobel edge detection filter, which generates a greyscale edge outline. generate a histogram and save the standard dev. move camera one step closer to subject and take another picture. if the standard dev is smaller than previous one, we're getting more in focus. otherwise, we've past the optimal distance to be taking pictures.

is there a better way?

update: HUGE flaw in this, by the way. as I get past the optimal focus point, my "image in focus" value continues growing. you'd expect a parabolic-ish function looking at distance/focus-value, but in reality you get something that's more logarithmic

update 2: okay, so I went back to this and the current method we're exploring is given a few known edges (okay, so I know exactly what the objects in the picture are), I do a manual pixel intensity comparison. as the resulting graph gets steeper, I get more in focus. I'll post code once the core algorithm gets ported from matlab into c# (yeah, matlab.. :S)

update 3: yay final update. came back to this again. the final code looks like this:

step 1: get image from the list of images (I took a hundred photos through the focused point)

step 2: find an edge for the object I'm focusing (In my case its a rectangular object that's always in the same place, so I crop a HIGH and NARROW rectangle of one edge)

step 3: get the HorizontalIntensityStatistics (Aforge.net class) for that cropped image.

step 4: get the Histogram (gray, in my case)

step 5: find the derivative of the values of the histogram

step 6: when your slope is the largest, is when you're in the most focused point.

A: 

I wonder if the standard deviation is the best choice: If the image gets sharper, the sobel filter image will contain brighter pixels at the edges, but at the same time fewer bright pixels, because the edges are getting thinner. Maybe you could try using an average of the 1% highest pixel values in the sobel image?

nikie
by the same logic I chose to go with standard deviation. the sharper the picture, the higher the contrast, the less variation there is in the histogram.if I grab some of the highest pixel values (i.e. get the brightest spots), that'll just give me how many bright spots there are on this picture compared to all the other spots there are in this picture. i.e. the graph slides shifts:focused shot: mean= 23, stddev = 15slightly out of focus: mean: 27, std dev = 16really out of focus: mean: 40, std dev = 20
Oren Mazor
A: 

This might be useful. It's how camera's AF system actually works - Passive Autofocus

Contrast measurement

Contrast measurement is achieved by measuring contrast within a sensor field, through the lens. The intensity difference between adjacent pixels of the sensor naturally increases with correct image focus. The optical system can thereby be adjusted until the maximum contrast is detected. In this method, AF does not involve actual distance measurement at all and is generally slower than phase detection systems, especially when operating under dim light. As it does not use a separate sensor, however, contrast-detect autofocus can be more flexible (as it is implemented in software) and potentially more accurate. This is a common method in video cameras and consumer-level digital cameras that lack shutters and reflex mirrors. Some DSLRs (including Olympus E-420, Panasonic L10, Nikon D90, Nikon D5000, Nikon D300 in Tripod Mode, Canon EOS 5D Mark II, Canon EOS 50D) use this method when focusing in their live-view modes. A new interchangeable-lens system, Micro Four Thirds, exclusively uses contrast measurement autofocus, and is said to offer performance comparable to phase detect systems.

m3rLinEz
The intensity difference between pixels is pretty close to what the sobel operation will give one.
kenny
A: 

I haven't built one myself, but my first thought would be to do a 2D DFT on a portion of the image. When out of focus, high frequencies will disappear automatically.

For a lazy prototype, You could try to compress a region of the image with JPEG (high quality), and look at the output stream size. A big file means a lot of detail, which in turn implies the image is in focus. Beware that the camera should not be too noisy, and that you can't compare file sizes across different scenes of course.

jdv
+1  A: 

While the sobel is a decent choice, I would probably choose to do an edge magnitude calculation on the projections in x and y directions over several small representative regions. Another .NET friendly choices based on OpenCV is @ http://www.emgu.com/wiki/index.php/Main_Page.

kenny
I didn't realize opencv is .net. I guess I mistakenly assumed it was c++ and just moved on without researching more (in my defence the research was started by somebody else)
Oren Mazor
It is C/C++ but the link providef is a C# wrapper around the DLLs.
kenny
+2  A: 

It may be a bit simplistic for your needs, but I've had good results with a simple algorithm that looks at the difference to neighbouring pixels. The sum of the difference of pixels 2-away seems to be a reasonable measure of image contrast. I couldn't find the original paper by Brenner in the 70's but it is mentioned in http://www.die.upm.es/im/papers/Autofocus.pdf

Another issue is when the image is extremely out of focus, there is very little focus information, so it's hard to tell which way is 'moving closer' or to avoid a local maximum.

Stew
your last point is one I encountered on friday when my camera started out way too far from the IC. I got around it when it occurred to me that I'm always going to be at the same height for best focus, so I need to go from a slightly-out-of-focus image to a sharp one only.that article is pretty awesome, by the way. especially because taking pictures of microorganisms is very close to taking pictures of ICs, which is what I'm doing.
Oren Mazor