Определить, какое изображение четче - PullRequest
22 голосов
/ 11 июля 2011

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

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

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

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

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

Ответы [ 5 ]

13 голосов
/ 11 июля 2011

Простой метод состоит в том, чтобы измерить контрастность - изображение с наибольшей разницей между значениями пикселей является самым четким.Вы можете, например, вычислить дисперсию (или стандартное отклонение) значений пикселей, и в зависимости от того, какое большее число выигрывает.При этом учитывается максимальный общий контраст, который может не соответствовать желаемому, в частности, он будет иметь тенденцию отдавать предпочтение изображениям с максимальной глубиной резкости.

В зависимости от того, что вы хотите, вы можете предпочесть что-то использоватькак БПФ, чтобы увидеть, какой отображает контент наивысшей частоты.Это позволяет вам отдавать предпочтение изображению, которое в некоторых частях изображения является чрезвычайно резким (но в других случаях менее выраженным), чем изображению, которое имеет большую глубину резкости, поэтому большая часть изображения является достаточно резкой, но максимальная резкость ниже (что обычнодифракции с меньшими отверстиями).

8 голосов
/ 24 сентября 2014

Как, например, показано на этой странице Matlab Central , резкость можно оценить по средней величине градиента.

Я использовал это в 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)
5 голосов
/ 11 июля 2011

Простым практическим подходом было бы использование обнаружения краев (больше краев == более четкое изображение).

Быстрое и грязное практическое использование 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);

(изображение с меньшим размытиемчетче) Более эффективным подходом будет обнаружение краев в вашем коде с использованием оператора Собеля . Пример PHP (переписывание на C ++ должно дать огромный прирост производительности, я думаю).

3 голосов
/ 11 июля 2011

В этой статье описан метод вычисления коэффициента размытия с использованием DWT. Выглядело довольно прямолинейно, но вместо обнаружения резкости он обнаруживает размытость. Кажется, он сначала обнаруживает ребра (простая свертка), а затем использует DWT для его накопления и оценки.

2 голосов
/ 11 июля 2011

Проверка функций передачи контраста (CTF)

Вот реализация Вот объяснение

...