# Measuring sharpness/contrast for autofocus

For the implementation of an auto-focus for the raspberry cam I need some measure of image sharpness. I used the following sample picture:

The first approach was to compute the shannon entropy of the whole image over its histogram. Then I artificially blurred the image to see the change in entropy. Expectation was that the entropy monotonically increasing with increasing blur. But in practice this was not the case. The increase in entropy was very little, and at some point it starts decreasing again for some reason. The fact, that the entropy increase is weak lies probably in the nature of the image: The majority of the image is already uniform. Blurring out the vessel does not change too much on the entropy.

If you are interested in the code, here it is:

Created on Tue Jun 28 23:54:58 2016

@author: asus
"""
import cv2
import cv2.cv
import numpy as np
import time

cv2.namedWindow('output')
src = cv2.imread("3.jpeg",1)
img = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#img = cv2.medianBlur(img, 5)
for i in range(1,300):
entropy=0
temp = cv2.blur(img, (i,i))
hist = np.bincount(temp.ravel(),minlength=256)+1
hist=hist/float(np.sum(hist))
entropy=np.sum(-hist*np.log2(hist))
print entropy

#    circles = cv2.HoughCircles(temp, cv2.cv.CV_HOUGH_GRADIENT,1,10)
#
#    if circles is not None:
#
#        circles = np.round(circles[0, :]).astype("int")
#        for (x, y, r) in circles:
#            cv2.circle(temp, (x, y), r, (0, 255, 0), 4)
#            while not cv2.waitKey(1)&0xFF==27:
#                    cv2.imshow('output',temp)

while not cv2.waitKey(1)&0xFF==27:
time.sleep(0.1)
cv2.imshow('output',temp)

cv2.destroyAllWindows()


As you may have noticed, I also tried to apply the histogram method only to few sections of the image. In this case I searched for circles via Houghtransform, and then only histogrammed the rectangles around the circles. But the circle detction itself is not really reliable for blurred images.

How can I enhance this method? What other options do I have to obtain a measure of sharpness?

EDIT: After overthinking this, the decrease of entropy after a certain degree of blur actually makes sense: Tf the image is too blurred to strongly, then the image will be more monochrome, which means a peak in the histogram--> entropy converging to zero.

EDIT:

In response to A_A's comment I tried the following idea: devide the image into 20 segments. blur the image at several different strengths (like going through all camera foci). For each of the 20 segments observe, how the entropy changes as a function of blur strength (or as a function of camera focus). Those segments, which do not contain too much of the objects will not change too much with increasing blur. Their entropies even decrease. Those with object information will have increasing entropy. Select those segments, and apply the entropy method on them all at once.

Results are little better. I will try that also with standard deviation instead of entropy, and then select the relevant segments with a threshold.

• It is likely that you will need a known target for autofocus estimation. You might find the responses to this question useful.
– A_A
Jun 29, 2016 at 17:47
• Why don't you use a property that certainly is associated with image sharpnes: fine details. You could compute the total sum over the gradient of the image, or the sum over the second-order derivate... Or look at the magnitude of the highest frequencies in Fourier-space.
– M529
Jun 30, 2016 at 6:00

## 2 Answers

Just run the image through an edge or corner filter and then take the maximum value over the entire image.

This gives you the sharpness of the sharpest edge. Then refocus the camera and repeat. Since the scene hasn't changed, the sharpest edge is still the same, but it may have become a bit more blurred as a result of the focus change. Or less blurred.

Taking the maximum over the image – as opposed to the average – is important. Many images consist of large uniform areas interrupted by a few edges. The reasoning is:

• If there is no sharp edge in an area, it could be because there is no edge at all. Alternatively, there may be edges but they're all blurred. You cannot tell the difference.
• If there is a sharp edge in an area, you know for sure that the image is not blurred. If the camera was defocused, it would affect all edges, no exceptions. The existence of a sharp edge serves as a proof by counterexample.

The maximum operator returns the counterexample if it exists, without diluting it. The average operator would drown the one counterexample in a sea of garbage.

While your approach is interesting, it might be better just to take a classic approach.
Classic approaches deals with measuring properties of the edges in the image.
Either their distribution or their local properties.

For instance, in the paper A No Reference Perceptual Blur Metric (Available on ResearchGate) they measure the width of the edges to estimate the level of the blur.
They use the statistics across the image to create a single measure.
In the paper they use average while you can do even more exotic things.