How can I detect if an image is of poor quality?

I need to filter out blurry or otherwise bad quality images from a set. I would like an efficient method to detect images that have any of the following three attributes:

1. Out of focus or motion blur
2. Lens occlusions: particles (hair or dust), smudges or hand/fingers over the lens
3. Poorly lighted over or under exposed images.
• Jan 14 '15 at 16:35
• I think an optimal solution will likely consider the "circle of confusion" in an out-of-focus image. Jan 14 '15 at 16:40
• Can you post a couple of samples to play with? Have you tried a GradientFilter? Jan 14 '15 at 16:52
• Also, just to be nitpicky :) This image is in fact very much out of focus. Now I really do wonder how cameras evaluate focus based on the recorded image. Jan 14 '15 at 16:56
• You could probably use a convolutional neuronal network to classify the images (or random sampled parts of larger images). I would assume that such a network would learn some kind of gradient filters in the first layers and build up logic from there. Dec 8 '16 at 6:01

As was correctly noted in comments, out-of-focus images cannot been correctly detected by a simple gradient filter since out-of-focus images can have sharp edges. I propose another simple idea to detect such images.

Introduction

Roughly speaking, the brightness of a defocused image $B(x,y)$ is a convolution of a focused image $B_0(x',y')$ with some kernel $K$ $$B(x,y) = \int K(x-x',y-y')B_0(x',y')dx\,dy.$$

Typically, $K$ is something like DiskMatrix in Mathematica. However, pixel values nonlinearly depend on brightness (or exposure) because of the logarithmic scale in the following figure

Therefore, the real brightness exponentially depends on the pixel value $V(x,y)$. The exponential function is nonlinear so the defocusing is not a convolution in terms of $V(x,y)$. However, the exponential function grows very fast so we can approximately write

$$V(x,y) = \max_{(x-x')^2+(y-y')^2<r^2} V_0(x',y').$$

So defocusing is rather Dilation (wiki) than ImageConvolve. Indeed, dilated image looks like real out of focus image.

Dilation has an interesting property: there is no sharp local maximums of pixel values. All local maximums cover some area (circle with radius $r$ at least). There is an appropriate function MaxDetect. It gives:

There is a lot of tiny areas in the focused images and only big areas in the defocused image.

Filter

Thus, we can introduce a simple out-of-focus measure, which is based on MaxDetect and ComponentMeasurements (these default values of thr and q is better then thr=0.15 and q=0.9 which I used in the first revision)

outOfFocus[img_Image, thr_: 0.05, q_: 0.8] :=
Quantile[ComponentMeasurements[#, "Area"][[All, 2]]/
ComponentMeasurements[#, "PerimeterLength"][[All, 2]], q] &@MaxDetect[img, thr];


Tests

Some test images

imgs = {
lena = ExampleData@{"TestImage", "Lena"},
pentagon = ExampleData@{"AerialImage", "Pentagon"},
park = Import@"http://i.stack.imgur.com/KoXDo.jpg",
city1 = Import@"http://i.stack.imgur.com/UOH7V.jpg",
city2 = Import@"http://i.stack.imgur.com/L0yMA.jpg",
city3 = Import@"http://i.stack.imgur.com/LCOpK.jpg"};

lena


pentagon


park


city1


city2


city3


Results

outOfFocus /@ imgs


Out of focus images have bigger values, so you can introduce some threshold around 0.8. outOfFocus works fine with artificial blurring and dilation as well

Plot[{Unevaluated@outOfFocus@Blur[lena, r],
Unevaluated@outOfFocus@Dilation[lena, DiskMatrix@r]}, {r, 0, 4},
PlotPoints -> 10, MaxRecursion -> 0, PlotRange -> {0, All},
PlotLegends -> {"Blur", "Dilation"},
AxesLabel -> {"r", "outOfFocus"}]


• It's nice to have you actively posting again. :-) Jan 15 '15 at 19:24
• The present code is rather slow. This large image took 24 seconds to process. How might one optimize this? Jan 15 '15 at 19:28
• Although it displays depth of field this image would not generally be considered out of focus yet your function returns a value of 4.98737. Thoughts? Jan 15 '15 at 19:31
• @Mr.Wizard one may downsample large images provided it is not done to such an extent as to degrade the contrast at high spatial frequencies. I also disagree about the second image; the majority of it is in fact out of focus, even if the focal point is included in the scene. Jan 15 '15 at 19:35
• @Mr.Wizard Big images: one can check downsampled image, then some randomly picked pieces. DOF: your image is very bright so it is difficult to find local maximums. This one gives 0.9, which is close to values of focused images. Anyway, there are many possibilities to tune parameters and optimize algorithm. No other algorithms which I tried, couldn't distinguish city1 and city3 :-) Jan 15 '15 at 20:07