10

At times our optical inspection system gets out of focus which results in nonsensical measurements. I've been tasked to develop an 'out of focus' detector which will be used to drive the Z axis of the camera system. The images available to me are bmp.

I'm looking for approaches and algorithms to investigate. For instance, should I be isolating features and measuring conformance or could edge detection be used?

This is the in focus image:

in focus


And this is the out of focus image:

out of focus

Community
  • 1
  • 1
john plourd
  • 125
  • 1
  • 8
  • In this situation, do you have several images of the same object and your task is to determine which of the images are out of focus or will you be required to determine if some arbitrary image is out of focus? – Max Allan Apr 05 '13 at 17:55

3 Answers3

12

The key is that in-focus image has much more strong gradients and sharp features. So what I suggest is to apply a Gaussian Laplace filter and then look at the distribution of pixel values of the result. The plot below shows the application of this idea to your images, where black refers to the out of focus image, and red to the one in focus. The in-focus one has much more high values (because the image has more sharp gradients).

When you have the histograms, you can distinguish one from another by comparing e.g. 90%th percentiles of the distributions (which is sensitive to tails). For the out of focus image it is 7 and for the in-focus image it is 13.6 (so twice the difference).

enter image description here

sega_sai
  • 7,309
  • 1
  • 26
  • 36
1

A quick and dirty version of the contrast algorithm is to sum the differences between adjacent pixels - higher sum is more contrast.

Martin Beckett
  • 90,457
  • 25
  • 178
  • 252
1

That's what I do in OpenCV to detect the focus quality:

Mat grad;
int scale = 1;
int delta = 0;
int ddepth = CV_8U;
Mat grad_x, grad_y;
Mat abs_grad_x, abs_grad_y;
/// Gradient X
Sobel(matFromSensor, grad_x, ddepth, 1, 0, 3, scale, delta, BORDER_DEFAULT);
/// Gradient Y
Sobel(matFromSensor, grad_y, ddepth, 0, 1, 3, scale, delta, BORDER_DEFAULT);
convertScaleAbs(grad_x, abs_grad_x);
convertScaleAbs(grad_y, abs_grad_y);
addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad);
cv::Scalar mu, sigma;
cv::meanStdDev(grad, /* mean */ mu, /*stdev*/ sigma);
focusMeasure = mu.val[0] * mu.val[0];
Nathan B
  • 1,154
  • 1
  • 14
  • 12