image processing - img - Detectar qué imagen es más nítida
seo image alt tag example (5)
Como se muestra, por ejemplo, en esta página de Matlab Central , la nitidez puede estimarse por la magnitud del gradiente promedio.
Utilicé esto en Python como
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)
Se puede calcular un número similar con numpy.diff más numpy.diff lugar de numpy.gradient . Los tamaños de matriz resultantes deben adaptarse allí:
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)
Estoy buscando una manera de detectar cuál de las dos imágenes (similares) es más nítida.
Pienso que esto podría estar usando alguna medida de la nitidez general y generar una puntuación (ejemplo hipotético: imagen1 tiene una puntuación de nitidez de 9, imagen2 tiene una puntuación de nitidez de 7, por lo que imagen1 es más nítida)
He realizado algunas búsquedas de algoritmos de detección / puntuación de nitidez, pero solo he encontrado algunos que mejorarán la nitidez de la imagen.
¿Alguien ha hecho algo como esto, o tiene recursos / pistas útiles?
Estaría usando esta funcionalidad en el contexto de una aplicación web, por lo que se prefiere PHP o C / C ++.
El enfoque práctico simple sería utilizar la detección de bordes (más bordes == imagen más nítida).
Práctica rápida y sucia usando 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);
(la imagen con menos desenfoque es más nítida) Un enfoque más eficiente sería detectar bordes en su código, utilizando el operador Sobel . Ejemplo de PHP (la reescritura en C ++ debería dar un gran aumento de rendimiento, supongo).
El método simple es medir el contraste: la imagen con las mayores diferencias entre los valores de píxeles es la más nítida. Por ejemplo, puede calcular la varianza (o desviación estándar) de los valores de píxel, y el que produzca el mayor número gana. Eso busca el máximo contraste general, que puede no ser lo que usted quiere, aunque en particular, tenderá a favorecer las imágenes con la máxima profundidad de campo.
Dependiendo de lo que desee, es posible que prefiera usar algo como una FFT, para ver cuál muestra el contenido de mayor frecuencia. Esto le permite favorecer una imagen que es extremadamente nítida en algunas partes (pero menos en otras) sobre una que tiene más profundidad de campo, por lo que más de la imagen es razonablemente nítida, pero la nitidez máxima es menor (lo cual es común, debido a difracción con aberturas más pequeñas).
Este artículo describe un método para calcular un factor de desenfoque utilizando DWT. Parecía bastante directo, pero en lugar de detectar la nitidez es detectar borrosidad. Parece que detecta los bordes primero (convolución simple) y luego usa DWT para acumularlos y puntuarlos.