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.