Основная проблема в том, что размер лапласианского ядра слишком мал .
Вы используете kernel_size = 3
, и он слишком мал для вышеуказанной сцены.
На изображениях, представленных выше, на kernel_size = 3
влияет в основном шум , потому что края (в изображение, которое показывает больше деталей), намного больше, чем 3x3 пикселей.
Другими словами, «особая частота» деталей - это низкая частота, а ядро 3x3 подчеркивает гораздо более высокую специальную частоту.
Возможные решения:
- Вы можете увеличить размер ядра - установите
kernel_size = 11
, например. - В качестве альтернативы вы можете изменить (уменьшить) исходное изображение, скажем, в 0,25 раза по каждой оси. Вы также можете вычислить взвешенную сумму стандартных значений до и после изменения размера (в случае, если сжатое изображение недостаточно точное, когда фокусировка хорошая).
В вашем коде есть небольшая проблема:
Core.convertScaleAbs(lplImage, absLplImage)
вычисляет абсолютное значение результата Лапласа, и в результате вычисленное значение STD является неправильным.
Я предлагаю следующее исправление:
Установите глубину лапласиана на CvType.CV_16S
(вместо CvType.CV_64F
):
Imgproc.Laplacian(filteredImage, lplImage, CvType.CV_16S, kernel_size, scale, delta, Core.BORDER_DEFAULT);
Не выполнять Core.meanStdDev(absLplImage, median, std)
, вычислить значение STD на lplImage
:
Core.meanStdDev(lplImage, median, std);
Я использовал следующий код Python для тестирования:
import cv2
def calc_sharpness_score(srcImage):
""" Compute sharpness score for automatic focus """
filteredImage = cv2.GaussianBlur(srcImage, (3, 3), 0, 0)
kernel_size = 11
scale = 1
delta = 0
#lplImage = cv2.Laplacian(filteredImage, cv2.CV_64F, ksize=kernel_size, scale=scale, delta=delta)
lplImage = cv2.Laplacian(filteredImage, cv2.CV_16S, ksize=kernel_size, scale=scale, delta=delta)
# converting back to CV_8U generate the standard deviation
#absLplImage = cv2.convertScaleAbs(lplImage)
# get the standard deviation of the absolute image as input for the sharpness score
# (mean, std) = cv2.meanStdDev(absLplImage)
(mean, std) = cv2.meanStdDev(lplImage)
return std[0][0]**2
im1 = cv2.imread('im1.jpg', cv2.COLOR_BGR2GRAY) # Read input image as Grayscale
im2 = cv2.imread('im2.jpg', cv2.COLOR_BGR2GRAY) # Read input image as Grayscale
var1 = calc_sharpness_score(im1)
var2 = calc_sharpness_score(im2)
Результат:
std1 = 668464355
std2 = 704603944