Simple way to check if an image bitmap is blur

user2923045 picture user2923045 · Jan 14, 2014 · Viewed 10.8k times · Source

I am looking for a "very" simple way to check if an image bitmap is blur. I do not need accurate and complicate algorithm which involves fft, wavelet, etc. Just a very simple idea even if it is not accurate.

I've thought to compute the average euclidian distance between pixel (x,y) and pixel (x+1,y) considering their RGB components and then using a threshold but it works very bad. Any other idea?

Answer

r3mainer picture r3mainer · Jan 15, 2014

Don't calculate the average differences between adjacent pixels.

Even when a photograph is perfectly in focus, it can still contain large areas of uniform colour, like the sky for example. These will push down the average difference and mask the details you're interested in. What you really want to find is the maximum difference value.

Also, to speed things up, I wouldn't bother checking every pixel in the image. You should get reasonable results by checking along a grid of horizontal and vertical lines spaced, say, 10 pixels apart.

Here are the results of some tests with PHP's GD graphics functions using an image from Wikimedia Commons (Bokeh_Ipomea.jpg). The Sharpness values are simply the maximum pixel difference values as a percentage of 255 (I only looked in the green channel; you should probably convert to greyscale first). The numbers underneath show how long it took to process the image.

close-up of Ipomea flower, sharpness calculated as 71.0%

same image with slight blurring, sharpness is reduced to 36.1%

same image with severe blurring; sharpness is now 17.6%

If you want them, here are the source images I used:


Update:

There's a problem with this algorithm in that it relies on the image having a fairly high level of contrast as well as sharp focused edges. It can be improved by finding the maximum pixel difference (maxdiff), and finding the overall range of pixel values in a small area centred on this location (range). The sharpness is then calculated as follows:

sharpness = (maxdiff / (offset + range)) * (1.0 + offset / 255) * 100%

where offset is a parameter that reduces the effects of very small edges so that background noise does not affect the results significantly. (I used a value of 15.)

This produces fairly good results. Anything with a sharpness of less than 40% is probably out of focus. Here's are some examples (the locations of the maximum pixel difference and the 9×9 local search areas are also shown for reference):

"Pure Linen" by mystuart @ Flickr (source)

"Blurred Buty" by Ilya @ Flickr (source)

"Blurry Downtown" by Andy Arthur @ Flickr (source)

"blurry volcanic mound" by matt Dombrowski @ Flickr (source)

The results still aren't perfect, though. Subjects that are inherently blurry will always result in a low sharpness value:

"Clouds and sky" by William Warby @ Flickr (source)

Bokeh effects can produce sharp edges from point sources of light, even when they are completely out of focus:

"The Side" by HD41117 @ Flickr (source)

You commented that you want to be able to reject user-submitted photos that are out of focus. Since this technique isn't perfect, I would suggest that you instead notify the user if an image appears blurry instead of rejecting it altogether.