Определить, какое изображение более резкое
Я ищу способ определить, какое из двух (похожих) изображений является более резким.
Я думаю, что это может использовать некоторую меру общей остроты и генерировать оценку (гипотетический пример: image1 имеет показатель точности 9, image2 имеет показатель резкости 7, поэтому изображение1 более четкое)
Я выполнил некоторые поиски алгоритмов определения/оценки заточки, но только обнаружил, что они улучшат резкость изображения.
Кто-нибудь сделал что-то подобное или имел какие-то полезные ресурсы/ведет?
Я бы использовал эту функциональность в контексте webapp, поэтому предпочтительнее использовать PHP или C/С++.
Ответы
Ответ 1
Простым методом является измерение контраста - наиболее резкое изображение с наибольшими различиями между значениями пикселей. Вы можете, например, вычислить отклонение (или стандартное отклонение) значений пикселей и в зависимости от того, какое из них выиграет больше. Это ищет максимальный общий контраст, который может быть не таким, каким вы хотите, - в частности, он будет склонен поддерживать фотографии с максимальной глубиной резкости.
В зависимости от того, что вы хотите, вы можете использовать что-то вроде FFT, чтобы увидеть, какой из них отображает самое высокое частотное содержимое. Это позволяет использовать изображение, которое чрезвычайно резкое в некоторых частях (но, тем более, в других), по сравнению с тем, которое имеет большую глубину резкости, поэтому изображение более разумно резкое, но максимальная резкость ниже (что является обычным явлением к дифракции с меньшими апертурами).
Ответ 2
Простым практическим подходом было бы использовать обнаружение края (больше краев - более четкое изображение).
Быстрая и грязная практическая работа с использованием PHP GD
function getBlurAmount($image) {
$size = getimagesize($image);
$image = imagecreatefromjpeg($image);
imagefilter($image, IMG_FILTER_EDGEDETECT);
$blur = 0;
for ($x = 0; $x < $size[0]; $x++) {
for ($y = 0; $y < $size[1]; $y++) {
$blur += imagecolorat($image, $x, $y) & 0xFF;
}
}
return $blur;
}
$e1 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/5/51/Jonquil_flowers_at_f32.jpg/800px-Jonquil_flowers_at_f32.jpg');
$e2 = getBlurAmount('http://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Jonquil_flowers_at_f5.jpg/800px-Jonquil_flowers_at_f5.jpg');
echo "Relative blur amount: first image " . $e1 / min($e1, $e2) . ", second image " . $e2 / min($e1, $e2);
(изображение с меньшим размытием становится более резким)
Более эффективным подходом было бы обнаружение краев в вашем коде, используя оператор Sobel. Пример PHP (переписывание на С++ должно дать огромное повышение производительности, я думаю).
Ответ 3
. показанном в этой центральной странице Matlab, резкость может быть оценена по средней величине градиента.
Я использовал это в Python как
from PIL import Image
import numpy as np
im = Image.open(filename).convert('L') # to grayscale
array = np.asarray(im, dtype=np.int32)
gy, gx = np.gradient(array)
gnorm = np.sqrt(gx**2 + gy**2)
sharpness = np.average(gnorm)
Аналогичное число можно вычислить с помощью более простого numpy.diff вместо numpy.gradient. Результирующие размеры массива должны быть адаптированы:
dx = np.diff(array)[1:,:] # remove the first row
dy = np.diff(array, axis=0)[:,1:] # remove the first column
dnorm = np.sqrt(dx**2 + dy**2)
sharpness = np.average(dnorm)
Ответ 4
В этом документе описывается метод вычисления размытия с использованием DWT. Выглядел довольно прямо, но вместо того, чтобы обнаруживать резкость, он обнаруживает размытость. Кажется, он сначала обнаруживает края (простая свертка), а затем использует DWT для накопления и оценки.
Ответ 5
Проверить функции передачи контраста (CTF)
Вот реализация
Вот описание