Подтвердить что ты не робот

Определить, какое изображение более резкое

Я ищу способ определить, какое из двух (похожих) изображений является более резким.

Я думаю, что это может использовать некоторую меру общей остроты и генерировать оценку (гипотетический пример: image1 имеет показатель точности 9, image2 имеет показатель резкости 7, поэтому изображение1 более четкое)

Я выполнил некоторые поиски алгоритмов определения/оценки заточки, но только обнаружил, что они улучшат резкость изображения.

Кто-нибудь сделал что-то подобное или имел какие-то полезные ресурсы/ведет?

Я бы использовал эту функциональность в контексте webapp, поэтому предпочтительнее использовать PHP или C/С++.

4b9b3361

Ответ 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 для накопления и оценки.