Ejemplos de ImageMagick -- Comparación de imágenes
- Prefacio e índice de los ejemplos de ImageMagick
- Métodos para comparar imágenes -- ¿qué es diferente?
- Programa compare
- Imágenes de diferencia
- Comparación por parpadeo
-
Estadísticas de comparación -- ¿cuánto difieren? Coincidencia y localización de subimágenes Encontrar imágenes pequeñas dentro de otras mayores. Encontrar imágenes duplicadas -- encontrar dos imágenes que son iguales Clasificar imágenes por tipo -- clasificaciones de imágenes para comparar
- Color lineal
- Blanco y negro puro
- Imágenes en color
- Coloreado en tonos medios
- Texto vs dibujo de líneas
-
Tratamiento de tipos de imagen específicos Métricas de imagen -- crear huellas de las imágenes para compararlas Cámaras web -- Encontrar qué ha cambiado en cámaras fijas Comparar dos o más imágenes, o encontrar imágenes duplicadas dentro de una gran colección, es una tarea muy delicada. En estos ejemplos veremos cómo comparar imágenes para determinar cuánto se parecen y en qué se diferencian. Esto puede implicar clasificar o agrupar las imágenes en distintos tipos para manejarlas mejor: descubrir alguna métrica que permita simplificar y agrupar imágenes similares, y agrupar en clústeres las imágenes parecidas según esas métricas. No obstante, aunque difíciles, estas comparaciones y estudios pueden resultar gratificantes, ya que permiten encontrar duplicados y copias de imágenes, e incluso eliminar «spam» u otros textos o avisos de las imágenes.
Métodos para comparar imágenes
Programa compare
El programa «magick compare» se ofrece como una forma sencilla de comparar dos imágenes similares y determinar cuán «diferentes» son. Por ejemplo, aquí tengo dos fotogramas de una «bolsa» animada, que luego pasé a «magick compare» para resaltar las zonas donde cambió.
magick compare bag_frame1.gif bag_frame2.gif compare.gif
Como puede ver, se obtiene una imagen en blanco y rojo que contiene una «sombra» de la segunda imagen. Muestra con claridad las tres zonas que cambiaron entre las dos imágenes. En lugar de guardar la imagen de «compare», por supuesto también puede verla directamente, lo cual me resulta más cómodo, enviándola al formato de salida especial «[x:](files.html#x)» o usando el programa «[display](basics.html#display)». Por ejemplo…
magick compare bag_frame1.gif bag_frame2.gif x:
magick compare bag_frame1.gif bag_frame2.gif miff:- | display
A partir de IM v6.4 puede cambiar el color de las diferencias del rojo a otro más interesante... |
magick compare bag_frame1.gif bag_frame2.gif \
-highlight-color SeaGreen compare_color.gif
![[IM Output]](../static/img/compare/compare_color.gif)
A partir de IM v6.4.2-8 también puede especificar el otro color. |
magick compare bag_frame1.gif bag_frame2.gif \
-highlight-color SeaGreen -lowlight-color PaleGreen \
compare_colors.gif
![[IM Output]](../static/img/compare/compare_colors.gif)
Si no quiere esa «sombra» de la segunda imagen, desde IM v6.4.2-8 puede añadir «-compose src» a las opciones para eliminarla. |
magick compare bag_frame1.gif bag_frame2.gif \
-compose Src compare_src.gif
![[IM Output]](../static/img/compare/compare_src.gif)
Usando los tres ajustes adicionales podemos generar una máscara en escala de grises de los píxeles que cambiaron... |
magick compare bag_frame1.gif bag_frame2.gif \
-compose Src -highlight-color White -lowlight-color Black \
compare_mask.gif
![[IM Output]](../static/img/compare/compare_mask.gif)
No obstante, tenga en cuenta que esta máscara refleja CUALQUIER diferencia, incluso la más pequeña. Por ejemplo, puede ver todas las diferencias menores que produce guardar una imagen en el formato JPEG con pérdidas...
magick bag_frame1.gif bag_frame1.jpg
magick compare bag_frame1.gif bag_frame1.jpg compare_lossy_jpeg.gif
Como puede ver, aunque en realidad no se aprecia ninguna diferencia entre las versiones GIF y JPEG de la imagen, «magick compare» informa de muchas diferencias. Usando un pequeño factor de borrosidad (fuzz) puede pedirle a IM que ignore estas diferencias menores entre las dos imágenes. |
magick compare -metric AE -fuzz 5% \
bag_frame1.gif bag_frame1.jpg compare_fuzz.gif
![[IM Output]](../static/img/compare/compare_fuzz.gif)
Lo que muestra que la mayoría de las diferencias reales son solo menores. El ajuste especial «[-metric](https://imagemagick.org/command-line-options/#metric)» con el valor «AE» (abreviatura de «Absolute Error», recuento de error absoluto) informa (por la salida de error estándar) del número real de píxeles que se enmascararon con el factor de borrosidad actual.
Imágenes de diferencia
Para hacerse una mejor idea de cuán diferentes son exactamente las imágenes, probablemente sea mejor obtener una imagen de composición «[difference](compose.html#difference)» más exacta... |
magick composite bag_frame1.gif bag_frame1.jpg \
-compose difference difference_jpeg.gif
![[IM Output]](../static/img/compare/difference_jpeg.gif)
Como puede ver, mientras que «magick compare» mostraba que JPEG creaba muchas diferencias entre las imágenes, una composición «[difference](compose.html#difference)» quedaba bastante oscura, lo que indica que todas las diferencias eran relativamente menores. Si la imagen resultante parece demasiado negra para ver las diferencias, quizá quiera normalizar la imagen (usando el más correcto matemáticamente «[-auto-level](https://imagemagick.org/command-line-options/#auto-level)») para realzar los resultados. |
magick difference_jpeg.gif -auto-level difference_norm.gif
![[IM Output]](../static/img/compare/difference_norm.gif)
Esto sigue mostrando que la mayoría de las diferencias son muy menores, y que la mayor diferencia se da a lo largo de los bordes nítidos de la imagen, que el formato de archivo JPEG no maneja muy bien. Por otro lado, obtener una imagen de diferencia entre los dos fotogramas originales de la animación muestra unas diferencias muy marcadas entre las dos imágenes, incluso sin ningún realce. |
magick composite bag_frame1.gif bag_frame2.gif \
-compose difference difference_frames.gif
![[IM Output]](../static/img/compare/difference_frames.gif)
Tenga en cuenta que, como el método de composición «[difference](compose.html#difference)» es asociativo, el orden de las dos imágenes en los ejemplos anteriores no importa; aunque, a diferencia de «magick compare», puede comparar imágenes de distinto tamaño, en cuyo caso la imagen de destino determina el tamaño final de la imagen de diferencia. El método difference resulta aún más útil cuando se usa con el programa «magick», ya que puede seguir procesando la imagen resultante antes de guardar o mostrar los resultados. Por ejemplo, puede aplicar un umbral y combinar cada uno de los canales de color para generar una máscara de cualquier píxel que haya cambiado de color entre las dos imágenes. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-threhold 0 -separate -evaluate-sequence Add \
difference_mask.gif
![[IM Output]](../static/img/compare/difference_mask.gif)
Esto es básicamente lo que hace el programa «magick compare», pero con más controles sobre el color y el estilo de salida. Sin embargo, como puede ver, tiende a encontrar hasta el cambio más pequeño entre dos imágenes. Si las imágenes proceden de un formato de archivo con pérdidas, como JPEG, o de una imagen GIF que requirió reducción de color y tramado (cuantización de color), probablemente coincidirá con todo en la imagen. Por eso normalmente no resulta muy útil. Para obtener mejores resultados puede intentar averiguar cuán diferentes son realmente los colores de los píxeles. Por ejemplo, podemos convertir el resultado a escala de grises para obtener una imagen de comparación mejor que una llena de color. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-colorspace Gray difference_gray.gif
![[IM Output]](../static/img/compare/difference_gray.gif)
Ahora bien, a diferencia de «magick compare», la imagen de diferencia muestra una mezcla de ambas imágenes combinadas en el resultado final. Por ejemplo, fíjese en el extraño «talismán» que parece aparecer en la frente del gato. En origen era el asa de la bolsa de la primera imagen. Esta fusión puede dificultar saber con exactitud qué diferencias está viendo, ya que se observa una mezcla tanto de las adiciones como de las eliminaciones de la imagen. Debido a esta confusión de detalles, «magick compare» suele ser la mejor forma de que los humanos lo veamos, mientras que la imagen de «difference» es el mejor método para seguir procesando la imagen. Sin embargo, convertir a escala de grises una imagen de diferencia se limita a promediar (en realidad un promedio ponderado) las distancias RGB en conjunto. Como consecuencia, una diferencia de color de un solo bit podría perderse por los efectos de redondeo cuántico. Si hasta la diferencia más pequeña entre imágenes es importante, un método mejor es sumar por separado los canales de color de la imagen de diferencia, para asegurarse de captar TODAS las diferencias, incluida la más mínima. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-separate -evaluate-sequence add difference_add.gif
![[IM Output]](../static/img/compare/difference_add.gif)
Los valores de diferencia producidos arriba se conocen como métrica de «distancia de Manhattan». Es decir, la distancia entre los dos colores de cada imagen cuando se restringe el movimiento a desplazamientos ortogonales (o axiales). Tenga en cuenta, no obstante, que las diferencias grandes pueden recortarse (o quemarse), ya que pueden superar el «Quantum Range» de los datos de píxel, o los límites enteros, salvo que use una versión HDRI de IM. Para llevar esto más lejos, puede obtener la distancia del vector de color usando cuadrados y raíces cuadradas para implementar una distancia pitagórica o euclidiana. |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-evaluate Pow 2 -separate -evaluate-sequence Add -evaluate Pow 0.5 \
difference_vector.gif
![[IM Output]](../static/img/compare/difference_vector.gif)
Esto, de hecho, es similar a lo que realmente mide un factor «fuzz» como parte de su umbralización (cuando no hay transparencia de por medio). Sin embargo, «fuzz» también divide los valores al cuadrado entre 3 antes de sumarlos, para garantizar que los resultados no superen los límites del rango de color de la imagen. Hacer esto significa que solo obtendría un píxel «blanco» puro en el resultado para la diferencia entre colores primarios y secundarios opuestos, como entre un píxel azul y uno amarillo. Así que hagamos también ese escalado... |
magick bag_frame1.gif bag_frame2.gif -compose difference -composite \
-evaluate Pow 2 -evaluate divide 3 -separate \
-evaluate-sequence Add -evaluate Pow 0.5 \
difference_vector_scaled.gif
![[IM Output]](../static/img/compare/difference_vector_scaled.gif)
En realidad, esto es muy similar a lo que obtendría con una imagen de diferencia «-colorspace Gray» (como la anterior), pero es una representación mucho más precisa de la diferencia de color. Podría omitir la segunda modificación «Pow 0.5», en cuyo caso obtendría una imagen de diferencia al cuadrado. Existen otras métricas de distancia de color, sobre las que puede leer en la página Color Difference, Wikipedia. La mayoría implican generar diferencias vectoriales (véase la última) pero usando un espacio de color distinto, como LAB o LUV. Esto, sin embargo, sería más importante al comparar diferencias de color del mundo real (por ejemplo, medidas de diferencia para la visión humana). Véase también Eliminación de fondo, donde se usan imágenes de diferencia como las anteriores para eliminar el fondo. También puede consultar esta página externa sobre Change Detection como ejemplo práctico de su uso.
Comparación por parpadeo
Una alternativa al programa «magick compare» para ver las diferencias entre imágenes es hacer una comparación por parpadeo entre las imágenes similares a un ritmo razonablemente rápido. |
magick -delay 50 bag_frame1.gif bag_frame2.gif -loop 0 flicker_cmp.gif
![[IM Output]](../static/img/compare/flicker_cmp.gif)
Para facilitarlo, escribí un script que muestra una animación de dos imágenes dadas, llamado «**[flicker_cmp](../static/img/scripts/flicker_cmp)**», que alterna entre las dos imágenes, igual que en el ejemplo anterior. También añade una etiqueta en la parte inferior de la imagen mostrada para indicar qué imagen está viendo en cada momento.
Comparación de animaciones
También puede comparar las diferencias entre dos animaciones fusionadas (coalesce) usando una técnica especial de «tira de película». Vea una técnica de «append» similar en Añadir lado a lado. Básicamente, unimos con append todos los fotogramas de la animación para formar una imagen única, grande y larga. Luego se comparan las dos imágenes y se crea una nueva animación volviendo a dividir la animación en fotogramas separados. Por ejemplo...
magick \( anim1.gif -coalesce -append \) \
\( anim2.gif -coalesce -append \) miff:- | \
magick compare - miff:- |\
magick - -crop 160x120 +repage anim_compare.gif
El resultado es una animación de las imágenes de «compare», que produce una versión «atenuada» de la segunda animación, superpuesta con un resaltado que muestra las partes que son diferentes. Tenga en cuenta que, para que esto funcione, el tamaño de «[-crop](https://imagemagick.org/command-line-options/#crop)» debe coincidir con el tamaño original de la animación. Además, la animación perderá cualquier retardo de tiempo variable que pudiera tener, y usará un retardo de tiempo constante basado en el primer fotograma de la animación original. Otra técnica de comparación de imágenes útil para animaciones sirve para localizar todas las zonas en las que cambia una animación, con el fin de separar las partes inconexas de la animación. De esta forma puede separar una animación grande en varias animaciones más pequeñas. Vea Dividir una animación.
Estadísticas de comparación
¿Cuán diferentes son dos imágenes?
En construcción
Estadísticas a partir de la imagen de diferencia...
Lo siguiente muestra información detallada y extrae únicamente la
sección que contiene las estadísticas de canal de la imagen....
magick image1 image2 -compose Difference -composite \
-colorspace gray -verbose info: |\
sed -n '/statistics:/,/^ [^ ]/ p'
Los números entre paréntesis (si los hay) son valores normalizados entre
cero y uno, de modo que son independientes del nivel Q de su IM.
Si no tiene estos números, debería plantearse actualizar su IM.
Para obtener el nivel de gris medio (mean) como porcentaje puede usar este
comando...
magick image1 image2 -compose Difference -composite \
-colorspace gray -format '%[fx:mean*100]' info:
Para obtenerlo sin porcentaje puede usar el aún más simple...
magick image1 image2 -compose Difference -composite \
-colorspace gray -format '%[mean]' info:
Estadísticas del programa compare...
Puede obtener un valor real de diferencia media usando -metric
magick compare -metric MAE image1 image2 null: 2>&1
Añadir -verbose proporcionará información más específica sobre cada canal
por separado.
magick compare -verbose -metric MAE rose.jpg reconstruct.jpg null: 2>&1
Image: rose.jpg
Channel distortion: MAE
red: 1884 (0.028748)
green: 1532.34 (0.023382)
blue: 1691.25 (0.0258068)
all: 1702.53 (0.025979)
Hay varias métricas distintas entre las que elegir.
Con el mismo conjunto de imágenes de prueba (casi las mismas)
Número de píxeles
AE ...... Recuento de error absoluto del número de píxeles diferentes (0=iguales)
Este valor puede umbralizarse con un ajuste -fuzz para
contar solo los píxeles que superen el umbral.
Desde IM v6.4.3, el recuento de -metric AE se ve afectado por -fuzz,
así que puede descartar diferencias «menores» de este recuento.
magick -metric AE -fuzz 10% image1.png image2.png null:
Qué píxeles son diferentes puede verse usando la imagen de
salida (ignorada en el comando anterior).
Esta es la ÚNICA métrica afectada por «fuzz».
Error máximo (de un solo píxel)
PAE ..... Error absoluto de pico (dentro de un canal, para espacio de color 3D)
PSNR .... Relación señal/ruido de pico (usada en artículos de compresión de imágenes)
La razón entre la diferencia cuadrática media y el máximo
cuadrático medio que puede existir entre dos imágenes
cualesquiera, expresada como valor en decibelios.
Cuanto mayor es el PSNR, más cercanas son las imágenes; la
diferencia máxima se da en 1. Un PSNR de 20 significa que las
diferencias son 1/100 del máximo.
Error medio (sobre todos los píxeles)
MAE ..... Error absoluto medio (distancia de error media por canal)
MSE ..... Error cuadrático medio (distancia de error al cuadrado promediada)
RMSE .... raíz del error cuadrático medio -- es decir: sqrt(MSE)
Métricas especializadas
MEPP .... Error medio normalizado Y error máximo normalizado
Estos deberían relacionarse directamente con el factor «-fuzz»,
para imágenes sin transparencia.
Con transparencia esto se complica: la máscara debería afectar
al número de píxeles comparados, y por tanto a la «media»,
pero actualmente no se hace.
FUZZ diferencia del factor fuzz teniendo en cuenta la transparencia
NCC correlación cruzada normalizada (1 = similar)
Obtuve los siguientes resultados con mis imágenes de prueba...
_métrica_|__jpeg Q bajo__|__negro vs blanco__
PSNR | 29.6504 | 0
PAE | 63479 | 65535
MAE | 137.478 | 65535
MSE | 4.65489e+06 | 4.29484e+09
RMSE | 2157.52 | 65535
La primera columna de números es una comparación de imágenes con
diferencias de JPEG de baja calidad, donde la imagen de prueba se leyó y
se guardó con un ajuste -quality muy bajo.
La segunda, «negro vs blanco», es una comparación de una imagen negra
sólida frente a una imagen blanca sólida. Si la comparación ignora el
«color medio» de la imagen, el valor resultante será muy pequeño. Esto
solo parece ocurrir con la métrica PSNR, ya que todas las demás
produjeron un valor de diferencia máximo.
El e+06 es notación científica, indica cuántas posiciones desplazar el
punto decimal. Por ejemplo: 4.65489e+06 --> 4,654,890.0
Equivale, pues, a unos 4 millones, y es el cuadrado de 2157.52
ADVERTENCIA: los números dependen de los niveles de calidad (Q) de IM
fijados al compilar. Cuanto mayor sea la calidad, mayores serán los números.
Solo PSNR debería no verse afectado. Por esta razón, IM también le da un
resultado «normalizado» que no se ve afectado por el ajuste de calidad de
compilación, aunque aún puede tener pequeños efectos «cuánticos» o de redondeo entero.
NO he averiguado si hay alguna de las opciones «-define» existentes que
sea utilizable con la función «compare».
NOTA: para colores opacos, las distancias AE -fuzz y RMSE son equivalentes.
SIN EMBARGO, cuando hay colores transparentes de por medio, la prueba del
factor fuzz de AE tratará dos colores completamente transparentes distintos
como iguales, ¡mientras que RMSE los tratará como diferentes!
Por ejemplo...
Para AE, el blanco completamente transparente y el negro completamente transparente son iguales.
magick compare -metric AE xc:#0000 xc:#FFF0 null:
0 (0)
Para RMSE son el mismo color porque ambos son completamente transparentes
magick compare -metric RMSE xc:#0000 xc:#FFF0 null:
0 (0)
Dissimilarity-threshold (umbral de disimilitud)
Si obtiene un error de «too different» (demasiado diferentes), puede desactivarlo usando...
-dissimilarity-threshold 1.0
Pero ¿qué es este umbral?
Para más información, consulte mis notas muy antiguas en texto plano... Image Comparing, Tower of Computational Sorcery
Coincidencia de subimágenes y formas
En construcción
Uso de la opción «compare -subimage-search»...
magick compare -subimage-search large_image.png sub-image.png results-%d.png
Esto produce dos imágenes
results-0.png
que muestra la ubicación coincidente
results-1.png
que es un mapa de las posibles ubicaciones de la esquina superior
izquierda que muestra cuán bien coincide la subimagen en esa ubicación.
Tenga en cuenta que la segunda imagen es más pequeña, pues solo son
ubicaciones de la esquina superior izquierda. Por eso su tamaño es large_image - small_image + 1
No obstante, la búsqueda se basa en una diferencia de vectores de color,
por lo que produce una comparación de color muy precisa.
La búsqueda básicamente compara la imagen pequeña en CADA ubicación posible
de la imagen mayor. ¡Por eso es lenta! **muy muy lenta.**.
Lo mejor es comparar una subimagen muy muy PEQUEÑA para encontrar posibles
ubicaciones y usar eso para luego hacer una comparación difference en cada
ubicación posible y obtener una coincidencia más precisa.
Eche un vistazo al script
../static/img/scripts/overlap
y a la discusión asociada
[Overlapped Images](https://magick.imagemagick.org/viewtopic.php?f=1&t=22526&p=95286)
Que trata de localizar subimágenes de «alta entropía» de una imagen para
buscar posibles coincidencias en una segunda imagen, de modo que pueda
descubrirse el desplazamiento de solapamiento entre ambas y fusionarlas en una imagen mayor.
Otra discusión usa búsquedas de subimágenes para encontrar patrones de
mosaico en imágenes mayores, con el objetivo de generar imágenes en mosaico
[Stitching image over a canvas](https://magick.imagemagick.org/viewtopic.php?f=1&t=22860)
Ejemplo usando RMSE y la nueva función -grayscale para combinar los
resultados de los canales de diferencia de color por separado en una imagen final
magick large_image.png small_image.png miff:- |
magick compare -metric RMSE -subimage-search - miff:- |
magick - -delete 0 -grayscale MS show:
Umbral de similitud (Similarity Threshold)
Muchas veces solo interesa la primera coincidencia que aparece. En cuanto
se encuentra esa «buena» coincidencia, no hace falta seguir buscando otra.
-similarity-metric define lo que usted consideraría una buena
coincidencia.
Un «-similarity-threshold 0.0» abortará en la primera coincidencia
«perfecta» encontrada, mientras que «-similarity-threshold 1.0» (el valor
por defecto) nunca coincidirá y buscará todos los puntos posibles. Un valor
intermedio fija un factor «fuzz» solo de color para una coincidencia aceptable.
Tenga en cuenta que, si la búsqueda de subimagen se aborta, la segunda
imagen «mapa» solo contendrá un resultado parcial, mostrando solo los
resultados hasta que la comparación abortó su búsqueda).
Algunos ejemplos básicos de búsqueda de subimágenes....
Tome una captura de pantalla de una ventana de terminal («screen.png»)
y recorte una imagen de una sola letra o palabra («letter.png»).
Informar solo de la primera coincidencia.... por velocidad,
abortar inmediatamente tras encontrar esa primera coincidencia.
No se moleste en generar los resultados de imagen incompletos.
magick compare -subimage-search -metric AE -similarity-threshold 1.0 \
screen.png letter.png null: 2>&1
NOTA: la velocidad dependerá en gran medida de dónde se encuentre esa
primera coincidencia en la imagen.
Encontrar todas las apariciones exactamente de esa imagen,
como imagen (puntos blancos en las coincidencias, negro en el resto)
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 show:
Extraer una lista de las coordenadas de todas las letras coincidentes (puntos blancos)
(como una lista enumerada de píxeles, ignorando todo lo negro)
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 txt:- | grep -v '#000000'
Solo la lista de coordenadas
magick compare -subimage-search -metric AE \
screen.png letter.png miff:- 2>/dev/null |
magick - -delete 0 txt:- | sed -n '/#FFFFFF/s/:.*//p'
Soluciones de búsqueda de subimágenes ajenas a ImageMagick...
«visgrep» del paquete «xautomation».
Este es un programa de búsqueda de subimágenes mucho más simple, que solo
genera una lista de coordenadas de las coincidencias (o incluso de varias subimágenes).
Como es mucho más simple (para coincidencias casi exactas) y no intenta
generar «imágenes de resultado» para estudiarlas, también es MUCHO MÁS RÁPIDO.
Por ejemplo...
visgrep screen.png letter.png
Resultados cronometrados
usando «compare» para obtener solo la primera coincidencia 0.21 segundos
usando «compare» para obtener una «imagen de resultado» 1.56 segundos
ídem, pero extrayendo la lista de coordenadas 1.76 segundos
usando «visgrep» para obtener todas las coordenadas 0.09 segundos
Otros métodos de búsqueda de subimágenes....
Morfología HitAndMiss
Esto es esencialmente una coincidencia binaria, donde se define qué píxeles
deben ser «fondo» y cuáles deben ser primer plano. No obstante, también
permite definir zonas donde no importa si el resultado es primer plano o
fondo.
Básicamente, un método de búsqueda de patrones binarios.
Correlate (una variante de Convolve)
Esto es similar a Hit and Miss pero usando valores de escala de grises.
Valores positivos para el primer plano, negativos para el fondo y cero para
lo indiferente. No obstante, está limitado a imágenes en escala de grises.
Vea [Correlación y búsqueda de formas](convolve.html#correlate_search).
Ambos son básicamente igual de lentos que la comparación de subimágenes
anterior, pero menos precisos en cuanto a los colores. Sin embargo, su
capacidad de especificar una forma (zonas indiferentes) a la subimagen los
hace útiles como método de búsqueda.
No obstante, hay que convertir («magick») la subimagen en un «núcleo», o
array de valores de coma flotante, en lugar de una imagen real.
FFT Convolve (NCC)
La transformada rápida de Fourier es un operador lento, pero normalmente
muchos órdenes de magnitud más rápido que los dos métodos anteriores. La
razón es que una convolución en el dominio de la frecuencia no es más que
una multiplicación directa píxel a píxel.
El método «Convolve» puede convertirse en un «Correlate» simplemente
rotando 180 grados la subimagen que se busca.
Vea [Correlate](convolve.html#correlate).
Básicamente, al convertir las imágenes al dominio de la «frecuencia», puede
hacer una búsqueda de subimagen muy muy rápido, comparado con lo anterior,
¡especialmente con subimágenes grandes que pueden ser del mismo tamaño que la original!
Creo que esto se ha añadido como una métrica de comparación NCC.
<a id="peak_finding"></a>
Búsqueda y extracción de picos (para coincidencias parciales aproximadas)...
Una vez comparada la imagen, normalmente tendrá una especie de «mapa de
probabilidad» que define cuán «perfecta» fue la coincidencia.
Lo que quiere hacer ahora es encontrar la mejor coincidencia, o quizá
varias coincidencias en la imagen. Es decir, quiere localizar los «picos»
principales del mapa resultante y extraer las ubicaciones reales.
* Usar un núcleo de convolución laplaciano
Para obtener resultados hay que encontrar los «picos» de la imagen, no
necesariamente los puntos más brillantes. Puede conseguirlo convolucionando
la imagen para restar al píxel central la media de los píxeles que lo
rodean. Como solo queremos resultados positivos, un sesgo (bias) elimina
los resultados negativos.
magick mandril3_ncc1.png \
-bias -100% -convolve Laplacian:0 result.png
Umbralizando y usándolo como máscara, podemos extraer solo esos píxeles.
magick mandril3_ncc1.png \
\( +clone -bias -100% -convolve Laplacian:0 -threshold 50% \) \
-compose multiply -composite \
txt:- | grep -v black
El problema es que puede obtener un grupo de puntos en un pico, en lugar
de un píxel definitivo, sobre todo con dos píxeles de pico rodeados de
valores muy bajos.
* Usar un núcleo de morfología Hit and Miss «Peaks»
magick mandril3_ncc1.png \
-morphology HMT Peaks:1.5 result.png
El problema es que esto puede no producir resultado si hay dos píxeles de
pico con exactamente el mismo valor (sin separación entre primer plano y fondo)
No obstante, hay otros núcleos «peak» que sí localizan un grupo de picos
así.
* Dilatar y comparar
Dilate (expande los valores máximos) la imagen 3 veces y luego compárela
con la imagen original. Cualquier pico dentro del área del tamaño del
núcleo dilatado (cuadrado de 7 píxeles) mantendrá el mismo valor. Ponga a
cero todos los píxeles que muestren una diferencia.
Método de HugoRune (tema de discusión de IM 14491)
* Coincidir y eliminar en bucle.
Básicamente, encuentre el valor de píxel más alto y anótelo. Luego
enmascare todos los píxeles de un área alrededor de ese pico, y repita
hasta alcanzar algún límite (número de puntos o umbral).
Vea una implementación en shell script de esto en el script de Fred
Weinhaus «[maxima](http://www.fmwconcepts.com/imagemagick/maxima/)»
Esto no contempla encontrar el centro de un gran «grupo» de píxeles de
valor casi igual, aunque esto sería muy raro en imágenes reales.
* Localización subpíxel
Si el pico no es un píxel exacto, sino que podría ser concebiblemente una
ubicación subpíxel (entre píxeles), entonces alguna forma de coincidencia
de patrones (ajuste de curva gaussiana) en el área del pico puede
permitirle localizarlo en una coordenada subpíxel.
Esto puede ser más importante en el registro de imágenes para la unión de
panoramas, sobre todo cuando no se usa un gran número de puntos para
obtener un promedio de mejor ajuste de la superposición en perspectiva.
* Encontrar un patrón de mosaico en una imagen
Cuando tenga todos los puntos, una búsqueda de un patrón repetido
(distancias vectoriales similares entre varios picos) debería revelar
alguna forma de estructura de mosaico.
Mejorar la coincidencia de subimágenes...
El principal problema de Correlate (o el rápido FFT correlate, que es lo
mismo) es que no entiende absolutamente nada de color.
La correlación (o convolución) es una técnica puramente matemática que se
aplica sobre un conjunto de valores. Con imágenes, eso significa que solo
se aplica sobre los canales individuales de una imagen, y NO sobre las
distancias vectoriales de color.
Mientras que compare sí compara realmente vectores de color. Esto encuentra
formas mejor que correlate, pero es muchísimo más lento.
Por eso, para aprovechar bien correlate, debería procesar («magick») sus
imágenes (de antemano por velocidad, o después sobre los resultados) para
intentar resaltar las diferencias de color como una imagen de «correlación» en escala de grises.
INCISO: usar -channel para limitar las operaciones a un solo canal en escala
de grises mejorará la velocidad. En IMv7, la conversión a escala de grises
reduce las imágenes a un canal, así que se gana en velocidad automáticamente.
Por ejemplo, en lugar de la intensidad, puede obtener una mejor
diferenciación entre primer plano y fondo extrayendo el Hue de una imagen.
Aunque puede que necesite rotar los tonos si hay mucho rojo en la subimagen
que se busca.
Vea los ejemplos de separación de canales HSL y HSB para ver este problema.
https://usage.imagemagick.org/color_basics/#separate
Otro método de conversión a escala de grises que debería funcionar muy bien
es hacer detección de bordes en las dos imágenes. Esto resalta los límites
y la forma, que normalmente son mucho más importantes que cualquier
degradado suave o cambio de color de la imagen.
Para ver ejemplos de métodos de detección de bordes, consulte
https://usage.imagemagick.org/convolve/#edgedet
También puede consultar la detección de bordes direccional o de tipo brújula.
Básicamente, cualquier cosa que realce la forma para su caso concreto es
una buena idea. Solo aplíquela a AMBAS imágenes antes de correlacionarlas.
Coincidencia invariante a escala y rotación...
* independencia de posición...
* coincidencia de subimagen rotada (independiente del ángulo)
* coincidencia de subimágenes redimensionadas (independiente del tamaño)
* independencia tanto de tamaño como de ángulo
--------------
Otras coincidencias de imagen más específicas..
Coincidencia de líneas...
Algoritmo de Hough
Coincidencia de círculos...
Variante del algoritmo de Hough
Coincidencia de caras
Una combinación de lo anterior.
Encontrar imágenes duplicadas
Archivos idénticos
¿Son los archivos idénticos a nivel binario, es decir, exactamente el mismo archivo y probablemente solo copias exactas unos de otros? No hace falta ImageMagick. No descarte esto. De esta forma puede comparar muchísimos archivos muy muy rápido. El mejor método que he encontrado es usar sumas de comprobación MD5.
md5sum * | sort | awk {'print $2 " " $1'} | uniq -Df 1
Y eso enumerará los md5 de las imágenes que son idénticas. Con esta técnica creé scripts que generan y comparan listas de md5sum de archivos, devolviendo los archivos que son idénticos por md5. Tenga en cuenta, no obstante, que cualquier cambio en un archivo de imagen distinto de una copia directa será clasificado por esto como diferente, aunque los propios datos de la imagen sean los mismos. Basta un cambio de fecha u otra pequeña diferencia de metadatos en el archivo para que la imagen sea distinta.
Firmas de imagen de IM
Puede hacer que IM genere una «firma» para cada imagen...
magick identify -quiet -format "%#" images...
Esto genera una cadena hash muy parecida a las de MD5 y SHA256. Sin embargo, a diferencia de estas, usa los datos reales de la imagen para generar la firma, no los metadatos de la imagen. Así, si tiene dos copias de la misma foto pero con marcas de tiempo de creación/modificación distintas, debería obtener la misma firma para ambos archivos, mientras que MD5 y SHA256 producirán dos firmas aunque la imagen en sí sea la misma. ADVERTENCIA: leer y escribir una imagen JPEG generará datos de imagen distintos y, por tanto, una firma distinta. Esto se debe simplemente a la compresión con pérdidas que usa el formato de imagen JPEG.
Comparación directa
Puede comparar directamente dos imágenes (usando el programa «magick compare») si tienen el mismo tamaño, para ver cuán bien coinciden. (Véase más arriba.) Esto es muy lento y, según mi experiencia, no muy útil cuando se usa contra una imagen a tamaño completo, porque es lentísimo. No obstante, probablemente sea la mejor forma de hacerse una idea de cuán parecidas son dos imágenes.
Clasificación de imágenes
En mis intentos de comparar imágenes he comprobado que las imágenes en color, las de tipo dibujo animado y los bocetos se comparan de forma muy distinta entre sí. Los dibujos de líneas y las imágenes en escala de grises tienden, en especial, a presentar diferencias menores que las imágenes en color con prácticamente cualquier método de comparación. Básicamente, como los colores están todos en una línea, cualquier métrica de color tiende a situar esas imágenes 3 veces más cerca entre sí (un espacio de color de 1 dimensión frente a un espacio de color de 3 dimensiones). Esto significa, en esencia, que separar las imágenes al menos en estos dos grupos puede ser un primer paso muy importante en cualquier intento serio de encontrar imágenes duplicadas o muy parecidas. Otras clasificaciones importantes, o tipos de imagen, también pueden facilitar la comparación, simplemente reduciendo el número de imágenes contra las que compara. Vea «Clasificación de imágenes» más abajo.
Comparaciones por miniaturas
Haces que un programa cree (en memoria) montones de pequeñas miniaturas (por ejemplo, de 64x64 píxeles) de las imágenes a comparar para buscar duplicados, lo que luego se hace por comparación directa. Suele ser lo primero que la gente (yo incluido) intenta hacer y, de hecho, es la técnica que emplean la mayoría de los programas de comparación de imágenes (como el software de gestión de fotos). En efecto, funciona bien y encuentra imágenes que coinciden exactamente. Además, con un poco de desenfoque y relajando el umbral de diferencia, puede incluso encontrar imágenes que se habían recortado y redimensionado ligeramente. No obstante, intentar almacenar en memoria 10.000 de esas miniaturas a menudo hace que un ordenador normal empiece a paginar en exceso (thrashing) y se vuelva muy lento. Como alternativa, almacenar todas esas miniaturas (salvo que el programa lo haga para que el usuario las vea) consume mucho espacio en disco. Un método para mitigar el problema de la paginación en disco es tener en memoria solo un número menor de imágenes. Es decir, comparar las imágenes por grupos, en lugar de una imagen con todas las demás. Una agrupación natural es por directorio, comparando cada directorio de imágenes con otros directorios de imágenes. De hecho, esto es bastante bueno, ya que las imágenes tienden a agruparse, y este grupo de imágenes a menudo coincidirá con un grupo similar. Que se devuelvan las imágenes coincidentes por pares de directorios es, por tanto, una ventaja añadida. Además, cuán aceptablemente parecidas son dos imágenes depende de su tipo de imagen. Comparar dos dibujos de líneas exige un «umbral» muy pequeño para descartar las imágenes diferentes, mientras que comparar imágenes con grandes áreas de color a menudo necesita un umbral mucho mayor para captar imágenes parecidas que fueron recortadas. Las imágenes del mundo real presentan un problema mayor, ya que una textura puede producir una diferencia aditiva muy seria entre imágenes con un desplazamiento mínimo. Por eso quizá necesite simplificar esas imágenes en áreas generales de color, ya sea usando filtros de mediana, desenfoque, reducción de color o segmentación de color. Tras ese proceso, una imagen del mundo real suele poder compararse de forma parecida a los dibujos animados.
Métricas de imagen
Crear una métrica pequeña para cada imagen es una operación de orden lineal (O), mientras que comparar todas las imágenes con todas las demás es una operación de orden cuadrático (O^2). Una métrica no pretende encontrar realmente las imágenes coincidentes, sino agrupar las imágenes similares (probablemente coincidentes) de modo que pueda hacer una comparación más intensiva sobre grupos más pequeños. Por eso, cualquier comparación por métricas debería ser indulgente y aceptar imágenes con una probabilidad baja (pero todavía existente) de coincidir. Pero no tan indulgente como para incluir demasiadas no coincidencias. También conviene considerar varias métricas, ya que algunas pueden emparejar imágenes que otra métrica «por poco no detecta» porque caen en regiones vecinas distintas (no coincidencia por umbral). En la sección siguiente (Métricas) hay varias métricas generadas con IM con las que he experimentado o teorizado, entre ellas: color medio, color predominante, primer plano/fondo, colores de borde, matriz de colores, etc. Günter Bachelier también ha informado de la posibilidad de usar métricas más exóticas para la comparación de imágenes, como: descriptores de Fourier, dimensiones fractales, áreas convexas, longitud y ángulos de los ejes mayor/menor, redondez, convexidad, curl, solidez, varianzas de forma, dirección, números de Euler, descriptores de contorno, curvatura, energía de flexión, curvatura absoluta total, áreas, centro geométrico, centro de masa, compacidad, excentricidad, momentos respecto al centro, etc., etc. Mi esfuerzo actual consiste en generar y usar una sencilla matriz 3x3 de promedios de color para representar la imagen (vea la métrica de matriz de color más abajo). A medida que se generan (o solicitan), la métrica se almacena en caché (junto con otra información del archivo) en archivos especiales en cada directorio. Así, solo necesito regenerar una métrica concreta cuando no hay una métrica en caché disponible o cuando la imagen ha cambiado.
Similitud o distancia
Las métricas de dos imágenes (o las propias imágenes) pueden compararse mediante varios métodos distintos, que generalmente producen una única medida de distancia o «métrica de similitud» que puede usarse para agrupar en clústeres las imágenes «parecidas».
- Umbral directo, o diferencia máxima (distancia de Chebyshev)
Compare las imágenes solo por la mayor diferencia en una sola métrica.
El umbral producirá un hipercubo de imágenes similares en el espacio métrico multidimensional. Por supuesto, la diferencia de imagen se basa solo en una métrica y no en todas las métricas. - Diferencia media (distancia media, distancia de Manhattan promediada)
Sume todas las diferencias y, opcionalmente, divida por el número de métricas.
También se conoce como la distancia de Manhattan entre dos métricas, ya que equivale a la distancia que hay que recorrer para desplazarse por una cuadrícula urbana. Todas las métricas contribuyen por igual, lo que hace que las cosas parezcan «más cercanas» de lo que cabría esperar. En el espacio, un umbral de esta métrica producirá una forma de rombo. - Diferencia euclidiana (pitagórica)
O la distancia vectorial directa entre las métricas en el espacio métrico.
El valor tiende a ser mayor cuando intervienen más métricas. Sin embargo, una métrica que produce una gran diferencia tiende a contribuir más que las demás. Un umbral produce un volumen esférico en el espacio métrico. - Error matemático/ajuste de datos o (¿¿¿momento de inercia???)
Sume todos los cuadrados de todas las diferencias y luego obtenga la raíz cuadrada
Esto se usa más habitualmente para calcular cuán bien se ajusta matemáticamente una curva a un conjunto concreto de datos, pero también puede usarse para comparar métricas de imagen.
Parece proporcionar la mejor medida de distancia no vectorial. - Ángulo vectorial
Encuentre el ángulo entre las dos líneas que parten del centro del espacio vectorial creado por la métrica de las imágenes. Esto debería eliminar cualquier efecto del contraste o de los realces que se hayan podido aplicar a las dos imágenes.
Aún sin probar - Distancia vectorial
Para imágenes que son dibujos de líneas o en escala de grises, donde todos los vectores de color individuales de una métrica apuntan en la misma dirección, probablemente sean más importantes las distancias relativas de las métricas respecto al color medio de la imagen. Normalizar las distancias respecto a la mayor distancia puede reducir el efecto del contraste.
Es decir, este es un método de comparación para imágenes de dibujo de líneas.
Aún sin probar - Análisis de clústeres
Todas las métricas se representan y se agrupan en clústeres similares dentro del espacio multidimensional. Un buen paquete de clustering podría incluso descubrir y descartar las métricas que no producen agrupamiento.
Aún sin probar
Por ahora estoy comprobando que la técnica del «error matemático» parece funcionar bien tanto para métricas en escala de grises como en color, usando una sencilla «métrica de matriz de color» 3x3 promediada (véase más abajo).
Verificación humana
Una vez que el ordenador ha terminado sus intentos de encontrar imágenes coincidentes, corresponde al usuario verificar realmente que las imágenes coinciden. Presentar las coincidencias al usuario también puede ser una tarea difícil, ya que probablemente querrá poder...
- Ver las imágenes una al lado de la otra
- Alternar muy muy rápido entre dos imágenes, a su tamaño original y, opcionalmente, a un tamaño «escalado» común.
- Alternar entre imágenes con distinta escala y traslación, o superponerlas, para intentar hacerlas coincidir.
- Ver otras imágenes del mismo directorio (origen) o quizá del mismo clúster (otras coincidencias cercanas) que la imagen coincidente, para tratar todo un grupo en lugar de cada imagen por separado.
- Renombrar, mover, reemplazar, eliminar o copiar las imágenes entre los dos (o más) directorios, para organizar las imágenes y rechazar otras.
- y así sucesivamente...
. Actualmente agrupo las coincidencias en conjuntos y uso una combinación de programas para manejarlas bajo el control del usuario. Entre estos programas están «magick display» y «magick montage» de IM, así como los visores de imágenes «XV» y «GQview». No obstante, agradezco sugerencias de otros programas que puedan abrir dos o más directorios simultáneamente y mostrar colecciones o grupos de imágenes de varios directorios. El control remoto o por parte de otros programas o scripts puede ser vital, ya que permite configurar y presentar los grupos de imágenes de la mejor manera para que el usuario los examine y los maneje. Ningún programa ha satisfecho aún mis necesidades. Por ejemplo, «gqview» tiene colecciones y una vista de un solo directorio, pero no permite vistas de varios directorios ni el control remoto/por línea de comandos de la presentación. Además, las colecciones no muestran de qué directorio procede cada imagen, ni permiten cambiar la vista de un solo directorio a otro directorio. Tampoco tiene control remoto por programa. Por otro lado, el muy antiguo «xv» sí permite vistas de varios directorios (usando varias ventanas «visual schnauzer») y una lista de colección en su ventana de control, pero solo puede verse una imagen a la vez, y solo puede abrirse y posicionarse un directorio desde su línea de comandos. Por supuesto, tampoco tiene control remoto. Estos son los mejores programas de verificación humana que he encontrado, y uso un script para configurarlos y lanzarlos para cada grupo de imágenes, pares coincidentes o todas las imágenes coincidentes del grupo. Pero ninguno resulta muy satisfactorio. Una mesa de luz y el software asociado me parecen un método mejor para organizar las imágenes, pero para eso hacen falta pantallas táctiles más grandes, y ahí está el gran gasto.
Comparación de imágenes de distinto tipo
Una de las cosas más difíciles que me gustaría hacer es encontrar imágenes que se crearon a partir de otra imagen. Por ejemplo, me gustaría emparejar un dibujo de líneas que otra persona ha coloreado o pintado para producir imágenes de dibujos animados o incluso ultrarrealistas. También puede haberse añadido un fondo. Estas cosas son muy difíciles, y mis experimentos con técnicas de detección de bordes han sido hasta ahora poco concluyentes. Aquí la clave está en encontrar la métrica adecuada, ya que los humanos hacen la conexión de «similitud» mucho mejor, pero aun así hay que encontrar posibles coincidencias para presentárselas al usuario.
Resumen sobre cómo encontrar imágenes duplicadas
En resumen, mi procedimiento actual para encontrar y manejar imágenes duplicadas es una tubería (pipeline) de programas que encuentran y organizan las imágenes «parecidas».
Generar/Cachear tipos de imagen y métricas
-> Comparar métricas y agrupar imágenes en clústeres.
-> comparar imágenes del clúster para buscar coincidencias
-> agrupar en conjuntos de imágenes coincidentes (por directorio de origen)
-> verificación humana
Como puede ver, contemplo un enfoque muy escalonado. ¡¡¡Envíeme sus ideas por correo!!!
Clasificar imágenes por tipo
Determinar de qué tipo es una imagen es importante, porque la mayoría de los métodos de comparación solo funcionan para un tipo concreto de imagen. No sirve de nada comparar una imagen de texto con el boceto de un artista, por ejemplo. Tampoco es útil usar un método de comparación de imágenes en color sobre una imagen que es casi blanca pura (un boceto). Normalmente, lo primero que hay que hacer al comparar imágenes es determinar de qué tipo de imagen, o «espacio de color», se trata. Las clasificaciones básicas de imágenes pueden incluir...
- Dibujo de líneas en blanco y negro o imagen de texto (casi todo de un solo color)
- Imágenes formadas por dos colores básicos, a partes iguales (¿imágenes de patrón?).
- Dibujos de artista en escala de grises (muchos matices)
- Imágenes de color lineal (los colores forman un degradado, pero no de negro a blanco)
- Imagen en color tipo dibujo animado con grandes áreas de colores sólidos.
- Una imagen real con áreas de colores con sombreado
- La imagen contiene algún texto anotado o un logotipo superpuesto. (un único pico de color)
Una vez que tenga las categorías básicas, también puede intentar ordenar las imágenes usando diversas métricas de imagen, como... * Color medio de toda la imagen * Color predominante de la imagen * Color de primer plano/fondo de la imagen.
Lo que es peor, las imágenes JPEG o redimensionadas a menudo también tienen el color distorsionado, lo que dificulta mucho más estas clasificaciones, ya que los colores no serán del todo como deberían. Los grises no serán grises puros, y las líneas pueden no ser nítidas y claras. En el foro de usuarios de IM hay una discusión de larga duración en curso sobre la clasificación de imágenes por tipo... How to check image color or black and white.
Imágenes en escala de grises
La forma más sencilla de comprobar si una imagen está en escala de grises es observar los niveles de saturación de color de la imagen. Esto se hace fácilmente convirtiendo la imagen a un espacio de color de imagen «Hue» y obteniendo los valores medio y máximo del canal de color (normalmente el verde). Por ejemplo...
magick rose: granite: -colorspace HCL \
-format '%M avg=%[fx:mean.g] peak=%[fx:maxima.g]\n' info:
Los números están normalizados a un rango de 0 a 1. Como puede ver, la «rose» es muy colorida (30% de media), con un pico fuerte (cercano a 1). La imagen «granite», en cambio, tiene una saturación muy baja (en torno al 2%) y un valor de pico bajo. Aunque no es escala de grises pura, se le acerca mucho. Una media baja y un pico alto indicarán pequeñas zonas de color intenso. Umbralizar ese mismo canal puede generar una máscara de las zonas con color de la imagen. PROBLEMA: lo anterior no encuentra imágenes que son lineales en color. Es decir, imágenes que solo contienen colores que forman un degradado lineal, como las fotos amarillentas (sepia) o los planos cianotipo. Estas son, en esencia, imágenes en escala de grises con color. Vea el siguiente tipo de imagen.
¿Es la imagen de color lineal?
Otra técnica consiste en hacer un «mejor ajuste» directo de una línea tridimensional a todos los colores (o a una matriz de color simplificada de métricas) de la imagen. El error del ajuste (generalmente la media de los cuadrados de los errores) le da una indicación muy buena de cuán bien se ajusta la imagen a esa línea. El ajuste de una línea a la imagen tridimensional suele implicar algo de matemática vectorial. El resultado no solo le dirá si la imagen usa un conjunto de colores casi «lineal», sino que funciona para CUALQUIER escala de colores, no solo de claro a oscuro, sino también líneas grisáceas sobre papel amarillo. El resultado también puede usarse para convertir la imagen en una imagen más simple en «escala de grises» (o simplemente convertir un conjunto de métricas de color en métricas de escala de grises) para comparaciones más simples y una mejor búsqueda de coincidencias. Mi programa de prueba ni siquiera usa la imagen completa para hacer esta determinación, sino que funciona usando una sencilla métrica de matriz de color de 9 colores (27 valores) para representar la imagen (más abajo). No obstante, tenga en cuenta que esta prueba generalmente no distingue muy bien los dibujos de líneas sin sombreado. Esas imágenes son casi por completo de un único color de fondo (normalmente blanco) y, por eso, pueden no mostrar ninguna forma de degradado lineal de colores. Conviene separarlas primero usando una prueba distinta (vea la siguiente; en realidad es mucho más fácil). Escríbame si le interesa y cuénteme qué ha probado.
Imágenes en blanco y negro puro
Para ver si una imagen es casi blanco y negro puro, con poco color o incluso grises (debido al suavizado de bordes), podemos hacer un uso ingenioso de la opción «[-solarize](https://imagemagick.org/command-line-options/#solarize)» (vea el ejemplo de IM sobre solarización). Aplicar esta operación a cualquier imagen hace que los colores brillantes se vuelvan oscuros (al negarse). Por eso, los colores casi blancos se volverán casi negros. A partir de una imagen así, un simple análisis estadístico de la imagen determinará si es pura (o casi puramente) blanco y negro.
magick wmark_dragon.jpg -solarize 50% -colorspace Gray wmark_bw_test.png
magick identify -verbose -alpha off wmark_bw_test.png | \
sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p' > wmark_stats.txt
| | ![[IM Text]](../static/img/compare/wmark_stats.txt.gif)
Si observa las estadísticas anteriores, verá que la «media» (mean) del color está muy cerca del negro puro («0»), mientras que la «desviación estándar» también es muy pequeña, pero mayor que la «media». Por tanto, esta imagen debe ser en su mayor parte blanco y negro puro, con muy pocos colores o grises de tono medio. Para imágenes generales en escala de grises y en color, la «media» será mucho mayor y, por lo general, la «desviación estándar» menor que la media. Cuando eso ocurre, significa que la imagen solarizada tiene muy poco negro casi puro. Es decir, hay muy pocos colores negro o blanco puros. Repitamos esta prueba usando la imagen granite incorporada.
magick granite: granite.jpg
magick granite.jpg -solarize 50% -colorspace Gray granite_bw_test.png
magick identify -verbose -alpha off granite_bw_test.png | \
sed -n '/Histogram/q; /Colormap/q; /statistics:/,$ p' > granite_stats.txt
| | ![[IM Text]](../static/img/compare/granite_stats.txt.gif)
Observe cómo la «media» es ahora mucho mayor, hacia la mitad del rango de color, con una «desviación estándar» mucho menor que el tamaño de la «media». A partir de IM v6.4.8-3 también verá otros dos valores estadísticos que pueden ayudar a determinar el tipo de imagen. Tanto la «curtosis» como la «asimetría» son relativamente grandes (y positivas) en la primera imagen en blanco y negro, lo que también refleja el hecho de que intervienen muy pocos grises en comparación con una imagen en gris. No obstante, «media» frente a «desviación estándar» sigue siendo probablemente el mejor indicador para fines de comparación. Tenga en cuenta que esta comparación no distingue entre «negro sobre blanco» o «blanco sobre negro», pero, una vez que sabe que no es realmente una imagen en escala de grises, una simple comprobación de la media normal de la imagen le dirá cuál es realmente el color de fondo.
Imágenes con manchas de color
Estas imágenes no pasan la prueba de escala de grises anterior, pero siguen siendo en blanco y negro, aunque con una pequeña zona o mancha de color. Las pequeñas manchas de color pueden quedar fácilmente ahogadas por la media general de una imagen grande, y podrían clasificarse erróneamente como escala de grises. No nos interesan las imágenes con, digamos, un único píxel de color, que probablemente sea un error de bit, ni un moteado de esos píxeles por la imagen. Sino, por ejemplo, una imagen con una flecha de color o un pequeño objeto coloreado. En otras palabras, una mancha concentrada de color. En una discusión en el foro de IM, False positive for greyscale images using the "saturation test", se pensó en dividir las imágenes en secciones más pequeñas y luego buscar una alta saturación en cualquiera de esas zonas. Esto condujo al siguiente método.
- convertir («magick») la imagen a un espacio de color con un canal de saturación o croma
- Redimensionar la imagen a una proporción de 1:50 (2%) (por ejemplo, un «tamaño de mancha» para el color)
- Umbralizar para obtener el valor máximo de saturación/croma
Las manchas individuales o muy pequeñas se eliminarán, pero una mancha de color más grande tendrá al menos un píxel con color en la imagen redimensionada.
Imágenes coloreadas en tonos medios
Las imágenes en tono sepia, o con los grises de tono medio coloreados hacia algún color de realce (por ejemplo, la imagen de la derecha), pueden resultar mucho más difíciles de distinguir. Generar imágenes así es fácil, como se muestra en Teñido de color de tonos medios, aunque no son muy comunes. Los colores siguen formando un degradado (línea) de colores en el espacio de color, pero ese degradado discurre por un trazado curvo, normalmente una especie de parábola, en un plano. Pero distinguir esas imágenes puede ser muy difícil. Una técnica consiste en obtener una desviación estándar de los tonos que no tengan una saturación extremadamente pequeña. Todos los tonos de una imagen coloreada en tonos medios deberían ser muy similares, aunque no sean muchos. Esta técnica se presentó en la publicación concreta de How to check image color or back and white. Solo un recordatorio de que el Hue es un valor cíclico y se enrolla en torno al color «rojo». Para probarlo correctamente, quizá tenga que hacerlo dos veces, con los tonos desplazados 180 grados. Además, el Hue no tiene un significado real para ningún color con una saturación muy baja (gris), así que cualquier color así debería ignorarse al probar la desviación estándar de los tonos.
Texto vs dibujo de líneas
Si tiene una imagen que es casi por completo de un solo color (normalmente blanco), puede intentar ver si el contenido de la imagen podría clasificarse como texto o como dibujo de líneas. El texto tendrá muchos objetos pequeños e inconexos, generalmente agrupados en líneas horizontales. Por otro lado, los dibujos de líneas deberían tener casi todo conectado entre sí como un conjunto, e implicar muchos ángulos distintos. Tenga en cuenta que las imágenes en color tipo dibujo animado también podrían convertirse en un dibujo de líneas para una comparación de imágenes más simple, así que disponer de un método de comparación de dibujos de líneas sería útil. ¿Alguien? Para saber más sobre el texto, se han comentado varias técnicas en los foros de IM, Check if image contains text.
Imagen real vs tipo dibujo animado
Básicamente, los dibujos animados tienen bloques de color muy concretos con regiones de bordes nítidos, a menudo hechos más nítidos mediante una línea negra separadora. Además, suelen tener efectos de degradado o sombreado mínimos. Las imágenes reales, en cambio, tienen muchos efectos de bordes suaves, degradados de color y texturas, y usan muchos colores distintos. Esto, por supuesto, no siempre es cierto. Una imagen real podría tener una cualidad muy de dibujo animado, sobre todo si se usa un contraste muy alto, y algunos dibujos animados modernos son tan realistas que puede ser difícil clasificarlos como dibujos animados. En general, la principal diferencia entre una imagen real y un dibujo animado son las texturas y los degradados. Por eso, determinar de qué tipo de imagen se trata exige comparar la imagen con esa misma imagen pero con la textura de escala fina eliminada. Una diferencia grande significa que la imagen es más «realista» y parecida al «mundo real», en lugar de «caricaturesca» o «plana». Recuerde también que un dibujo de líneas, un boceto de artista y el texto también pueden tener un estilo muy de dibujo animado, pero con una textura y un detalle tan finos que lo anterior podría considerar la imagen como del mundo real. Por eso, los dibujos de líneas y los bocetos deberían separarse de antemano.
Jim Van Zandt ofrece esta solución...
- escribir el color de cada píxel
- ordenar por color
- escribir el recuento de píxeles de cada color
- ordenar por recuento de píxeles
- Avanzar por la lista hasta haber contabilizado la mitad de los píxeles de la imagen.
- Si #píxeles >>> #colores, entonces es de tipo dibujo animado.
La sección inicial puede clasificarse como histograma. Vea los ejemplos de «[histogram:](files.html#histogram)».
Si ha creado algún tipo de esquema de clasificación de imágenes... aunque sea solo a grandes rasgos, cuéntenos sus resultados, para que otros (yo incluido) puedan beneficiarse.
Tratamiento de tipos de imagen específicos
Aquí tiene notas e información sobre técnicas de determinación de imágenes más específicas.
Escaneos o impresiones defectuosos
En el mundo real, las cosas nunca funcionan tan perfectamente como uno querría. Los escáneres tienen sensores estropeados y los tambores de las impresoras tienen rayas. Ambos problemas suelen dar lugar a escaneos e impresiones con largas líneas verticales. No obstante, determinar si una imagen tiene estas líneas verticales es bastante fácil. La idea es promediar juntos los píxeles de todas las filas de una imagen. Cualquier «defecto» aparecerá como un pico marcado en la fila de píxeles final, cuyo número puede contar usando un «histograma de umbral» de la fila de píxeles.
FUTURO -- se necesita un ejemplo de imagen para pruebas
magick bad_printout.png -crop 0x1+0+0 -evaluate-sequence mean \
-threshold 50% -format %c histogram:info:-
método más rápido pero necesita la altura de la imagen (se asume 1024)
magick bad_printout.png -scale 1024x1 \
-threshold 50% -format %c histogram:info:-
Cuando haya determinado y eliminado esas «líneas defectuosas» de un fax, una impresión o un escaneo, podrá continuar con sus otras pruebas sin tener que preocuparse por este tipo de defecto del mundo real.
Fax en blanco
Primero tendrá que recortar con «[-shave](https://imagemagick.org/command-line-options/#shave)» cualquier encabezado y pie de página que un fax pueda haber añadido a la página. Luego puede hacer un «histograma de umbral» (vea lo anterior) para ver cuántos píxeles negros individuales hay.
FUTURO -- se necesita un ejemplo de imagen para pruebas
magick blank_fax.png -threshold 50% -format %c histogram:info:-
O puede hacer un recorte con ruido para ver si la imagen contiene realmente alguna otra área sólida u objetos dignos de su atención.
FUTURO -- se necesita un ejemplo de imagen para pruebas
Imágenes con spam
Una imagen con spam mostrará generalmente un pico de color puro predominante en el histograma de color de la imagen. Una comprobación del color en la imagen mostrará normalmente que está en una de las esquinas de la imagen. No obstante, esto no funcionará con imágenes de tipo dibujo animado.
Imágenes de spam de correo electrónico
Estas son imágenes diseñadas para sortear los distintos filtros de spam. Básicamente, el texto del anuncio se oculta en una imagen usando varios colores y se añade «suciedad» extra y otro ruido para dificultar su detección. Y aunque son difíciles de distinguir, por ejemplo, del logotipo del encabezado de correo de una empresa, suelen ser también mucho más grandes que el típico logotipo de correo. Una técnica de detección es aplicar un filtro de mediana grande a la imagen. El texto del spam de correo generalmente desaparecerá, mientras que un logotipo o una imagen seguirá siendo muy colorido.
Métricas de imagen: encontrar rápidamente imágenes que comparar
Una métrica representa una especie de «huella dactilar» para representar una imagen, con una cantidad de memoria muy pequeña. Las imágenes similares deberían producir una métrica similar. Tenga en cuenta, no obstante, que una métrica no está diseñada para encontrar realmente las imágenes coincidentes, sino para intentar descartar las imágenes que claramente no coinciden. Es decir, una buena métrica le permitirá descartar la mayoría de las imágenes de comparaciones posteriores, reduciendo así el tiempo necesario para buscar en todas las imágenes.
Color medio de una imagen
Puede usar -scale para obtener el color medio de una imagen; no obstante,
también sugiero quitar los bordes exteriores de la imagen para reducir el
efecto de cualquier «pelusa» que se haya podido añadir alrededor de la imagen.
magick image.png -gravity center -crop 70x70%+0+0 \
-scale 1x1\! -depth 8 txt:-
Como alternativa, para obtener el color del «centroide ponderado», basado en
la agrupación de colores en lugar de un promedio, puede usar -colors
magick rose: -colors 1 -crop 1x1+0+0 -depth 8 -format '%[pixel:s]' info:-
rgb(146,89,80)
Esto generalmente emparejará imágenes que se han redimensionado, recortado ligeramente, rotado o trasladado. Pero también emparejará muchas imágenes que no están estrechamente relacionadas. El mayor problema es que esta métrica generalmente descartará imágenes a las que se ha aumentado o reducido el brillo, o cuyo tono general se ha cambiado. Además, aunque es una métrica estupenda para imágenes en color y del mundo real, es completamente inútil para imágenes en escala de grises. Todas esas imágenes suelen agruparse juntas sin más agrupación dentro del tipo. Esto, a su vez, muestra por qué cierta clasificación inicial de los tipos de imagen puede ser vital para una buena ordenación y coincidencia de imágenes.
Color predominante de una imagen
El color predominante de una imagen es un poco distinto: en lugar del promedio, que fusiona los colores de fondo con el primer plano, lo que quiere es encontrar el color de primer plano más común y, quizá, un porcentaje de qué parte de la imagen está formada por ese color predominante. Por eso no puede limitarse a tomar un histograma de una imagen, ya que la imagen puede usar muchos matices de color individuales en lugar de un color concreto. Esto puede hacerse usando la función de cuantización de bajo nivel -segment y luego tomando un histograma. Esto tiene una ventaja sobre el uso directo de -colors, ya que no intenta fusionar grupos de colores distantes (en cuanto a color), aunque los resultados pueden ser más difíciles de determinar.
ejemplo FUTURO
Después de lo cual, un histograma le dará la cantidad de cada uno de los colores predominantes. No obstante, normalmente el color predominante de un dibujo animado o de líneas es el color de fondo de la imagen. Por eso solo es realmente útil para imágenes reales. Por otro lado, puede que sirva para descubrir si una imagen tiene un fondo verdadero, comparándolo con el color medio del borde de la imagen. Tenga en cuenta que es más probable que el color predominante de una imagen esté más fuertemente influido por el color de fondo de la imagen que por el objeto de interés. Es decir, normalmente en el centro de la imagen o cerca de él.
Colores del borde
Recortando repetidamente cada uno de los cuatro bordes (2 o 3 píxeles como mucho) de una imagen y calculando el color medio de los bordes, puede determinar si una imagen tiene marco, y de qué grosor. Si la imagen tiene un fondo definido. O si hay algún tipo de separación de color cielo/tierra o primer plano/fondo en la imagen general. Comparando los colores medios de los lados con el color central medio de la imagen, puede descubrir si la imagen es uniforme, sin un tema o sujeto central, como una foto de un paisaje vacío.
Histograma: coincidencia general de color
Para una métrica relativa a los tipos de colores que se encuentran en una imagen, se usa un histograma de un tipo u otro. Esto se hace creando un array de «contenedores de color» (bins) e incrementando el recuento de cada «contenedor» a medida que se encuentran los colores. Ahora bien, ¡no me imagino que almacene un histograma grande para cada imagen! Así que, o bien solo almacena los colores más predominantes en el histograma, o bien usa un número de contenedores mucho menor (con más píxeles en cada contenedor). Un histograma corriente de «contenedores de color» no funciona muy bien en realidad. La razón es que cada color siempre cae en un solo contenedor. Es decir, cada píxel se añade a cada contenedor de forma todo o nada, sin tener en cuenta cuán cerca está ese color del borde de un contenedor. Esto, a su vez, no da una buena métrica. Una solución es crear un histograma con contenedores que se solapen. Es decir, cada color (salvo quizá el negro o el blanco) caerá en dos contenedores de color. Luego, al comparar las imágenes, un color cercano coincidirá con al menos uno de esos contenedores. Otra alternativa es crear el histograma haciendo que cada color contribuya a cada «contenedor» según cuán cerca esté del centro del contenedor. Es decir, un color en el borde de un contenedor se repartirá en realidad entre dos contenedores. Esto generará una especie de histograma difuso, o interpolado, pero que representaría la imagen con más precisión, sobre todo cuando se usa un número muy pequeño de «contenedores» de color. Además, los histogramas son tradicionalmente o bien solo el componente de escala de grises de una imagen, o bien tres componentes RGB separados. Pero esto no es una representación muy buena. En su lugar podría probar histogramas de tono, saturación y luminancia para representar mejor la imagen. Como alternativa, ¿por qué limitarse a un histograma unidimensional? ¿Qué tal mapear los colores a un conjunto de colores reales por todo el espacio de color? Es decir, en lugar de meter en contenedores solo el valor «rojo», ¿por qué no contarlo en un contenedor de color tridimensional (en el espacio de color que mejor funcione)? Eso generaría un histograma que representaría de verdad los colores que hay dentro de una imagen. Una métrica de histograma 3D así podría ser un sencillo array de, digamos, 8x8x8 o 2048 contenedores. Es decir, una métrica de 2 Kbytes. Una búsqueda de color localizaría entonces el número correcto de contenedores cercanos y obtendría un recuento interpolado de los contenedores próximos. ¡Lo que representaría el número de colores «cercanos» a ese color dentro de la imagen!
Separación de color primer plano/fondo
Usando -colors puede intentar separar la imagen en partes de primer plano y fondo, reduciendo la imagen a solo dos colores. Aplicar primero un filtro -median eliminará el efecto de los detalles menores, los bordes de líneas y el ruido que pueda haber en la imagen. Por supuesto, eso no es muy bueno para imágenes mayormente blancas de tipo boceto.
magick rose: -median 5 +dither -colors 2 \
-depth 8 -format %c histogram:info:-
Esto muestra un color rojo y uno gris como los colores predominantes de la imagen. Un recorte hacia el centro de la imagen debería entonces determinar qué es primer plano y qué es fondo.
magick rose: -median 5 +dither -colors 2 \
-trim +repage -gravity center -crop 50% \
-depth 8 -format %c histogram:info:-
Lo que muestra que el color rojo de la «rose» es el color de primer plano predominante. Tenga en cuenta que una imagen de paisaje puede separarse de otra forma, en la que se obtiene un color de tierra inferior y un color de cielo superior. Por eso, una mirada aproximada a cómo se separaron los colores podría ser muy útil para determinar el tipo de imagen. Además, una imagen con algo de «spam» de texto a menudo mostrará una mancha de color en una esquina mucho más prominente que el resto de la imagen. Si la encuentra, rehágalo con 3 colores y luego borre esa zona con el color de «fondo» más común encontrado antes de hacer su prueba final. Esta técnica es probablemente una buena forma de separar las imágenes en clases como «tono de piel», «vegetación», «paisaje», etc.
Matriz de color medio
Un esquema de color de matriz de tres por tres («-scale 3x3\!») es un esquema de clasificación de color razonable. Separa y agrupa muy bien las imágenes similares. Por ejemplo, los bocetos (todos casi blancos), la escala de grises, los paisajes, las marinas, las habitaciones, las caras, etc., quedarán todos separados en grupos básicos y similares (en teoría). También es una métrica razonable para indexar imágenes con el fin de generar fotomosaicos. La salida del formato de imagen NetPBM es especialmente adecuada para generar una métrica así, ya que puede sacar solo los valores de los píxeles como números de texto. Recuerde que esto produciría un resultado de 27 dimensiones (3x3 colores de 3 valores), así que puede que se necesite un algoritmo de agrupamiento multidimensional. ¿Conoce algún buen programa/algoritmo de clustering en 3D? Por ejemplo, aquí están los colores RGB 3 x 3 (a profundidad 8) del logotipo de IM.
magick logo: -scale 3x3\! -compress none -depth 8 ppm:- |\
sed '/^#/d' | tail -n +4
251 241 240 245 234 231 229 233 236 254 254 254
192 196 204 231 231 231 255 255 255 211 221 231
188 196 210
Lo anterior puede mejorarse usando valores de 16 bits y, posiblemente, recortando el 10% de los bordes para eliminar el logotipo y la basura de enmarcado que se haya podido añadir...
magick logo: -gravity center -crop 80% -scale 3x3\! \
-compress none -depth 16 ppm:- | sed '/^#/d' | tail -n +4
63999 59442 58776 62326 58785 58178 51740 54203 54965 65277 65262 65166
45674 47023 49782 56375 55648 55601 65535 65535 65535 52406 55842 58941
44635 48423 52881
Por supuesto, igual que la métrica de color medio anterior, esta también tendrá problemas para emparejar imágenes a las que se ha modificado el color, como cambios de tono o de brillo. (Vea la sección siguiente.) Además, esta métrica puede separar dibujos de líneas dentro de su agrupación, aunque solo de forma muy general. Esos dibujos seguirán agrupándose más por el color del «papel» de fondo que por el contenido y, en general, necesitan un «umbral» de similitud menor que las imágenes en color.
Matriz de diferencia de color
El mayor problema de usar los colores directamente como métrica es que se ata la imagen a un color general concreto. Esto significa que cualquier imagen a la que se haya aumentado o reducido el brillo, o cuyo tono se haya cambiado, no quedará agrupada. Una solución a esto es restar de algún modo de la métrica el color predominante o medio de la imagen, y usar una matriz de colores lo hace posible. Aquí, por ejemplo, resto el color medio del medio o centro de todos los colores que lo rodean en la matriz.
magick logo: -gravity center -crop 80% -scale 3x3\! -fx '.5+u-p{1,1}' \
-compress none -depth 16 ppm:- | sed '/^#/d' | tail -n +4
51093 45187 41761 49419 44529 41163 38834 39947 37950 52371 51007 48152
32767 32767 32767 43469 41393 38587 52629 51279 48521 39500 41587 41926
31729 34168 35867
Tenga en cuenta que sumo .5 a la diferencia, ya que no se puede guardar un valor de color negativo en una imagen. Además, el uso del lento operador «[-fx](https://imagemagick.org/command-line-options/#fx)» es aceptable, ya que solo se procesan 9 píxeles. Tenga en cuenta que el píxel central («32767 32767 32767» al inicio de la segunda línea de arriba) no cambiará mucho (cualquier cambio se debe solo a ligeros errores de redondeo), y podría eliminarse del resultado, reduciendo la métrica a 24 dimensiones (valores). Como alternativa, puede restar el color medio de la imagen de los 9 valores de color.
magick logo: -scale 3x3\! \( +clone -scale 1x1 \) -fx '.5+u-v.p{0,0}' \
-compress none ppm:- | sed '/^#/d' | tail -n +4
38604 35917 34642 37011 33949 32441 32839 33841 33649 39447 39259 38369
23358 24377 25436 33538 33174 32426 39612 39434 38605 28225 30576 32319
22271 24381 27021
Esto también podría hacerlo el comparador de métricas, en lugar del generador de métricas. La métrica sigue separando y agrupando muy bien las imágenes en color, situando las imágenes similares muy juntas, con independencia de cualquier cambio general de color o brillo. No obstante, sigue siendo sensible a los cambios de contraste. De hecho, esta modificación de la métrica podría hacerse durante el proceso de comparación, de modo que una métrica de matriz de color en bruto pueda seguir usándose como métrica de imagen estándar para recopilar, almacenar en caché y comparar. Esto es lo que yo mismo hago ahora para comparaciones de imágenes a gran escala. A diferencia de un promedio de color directo, puede usar esta métrica para diferenciar entre distintas imágenes de dibujo de líneas. No obstante, como los dibujos de líneas usan una escala de color lineal (todos los colores caen en una línea en el espacio métrico), las diferencias entre imágenes son aproximadamente 1/3 de las de las imágenes en color. Por eso se necesita un umbral muy distinto al comparar dibujos de líneas. Así que sigue siendo mejor separar los dibujos de líneas y las imágenes en escala de grises de las imágenes en color. En otras palabras, esta es una de las mejores métricas que he encontrado hasta ahora para imágenes en color. Solo asegúrese de determinar primero qué imágenes son dibujos de líneas y compararlas por separado usando un umbral mucho más bajo. Por suerte para nosotros, la propia métrica puede usarse para separar las imágenes en escala de grises o imagen de color lineal. Se agradecen sugerencias.
Diferencia entre vecinos
Lo anterior genera una matriz 3x3, con el píxel central restado y todos los valores desplazados hacia un gris perfecto. No obstante, un método mejor es que, en lugar de intentar guardar el color de cada celda individual, se generen las diferencias entre cada celda y sus vecinas (8 vecinas). Es decir, en lugar de guardar el color de la esquina superior izquierda, guarde la diferencia entre esa esquina y la superior-central, la central y la central-izquierda. Por supuesto, incluso con un array pequeño de 3x3, acabará con una firma que contiene 12 diferencias, aunque no necesita codificar la diferencia completa, solo un nivel general de diferencia, como iguales, o valores de diferencia positivos/negativos grandes/pequeños. Esto tiene muchas más probabilidades de encontrar imágenes que coinciden incluso entre imágenes que contienen colores tremendamente distintos, ya que el color real no interviene en absoluto en la firma. La biblioteca de comparación de imágenes «libpuzzle» hace exactamente eso, aunque usa una matriz 9x9, promediando juntos solo los píxeles centrales de cada celda. También se limita a versiones en escala de grises de la imagen. La técnica está completamente definida en un artículo en postscript, Image Signature for Any Kind of Image. El artículo también aborda métodos para almacenar esa firma en una base de datos y cómo realizar realmente una búsqueda para encontrar imágenes con firmas similares (no necesariamente iguales). Es el primer artículo que he descubierto que entra de verdad en detalle sobre cómo hacer esto. :-)
Hash perceptual
Reduzca la imagen a 8x8 y calcule una intensidad media. Cada bit del hash de 64 bits es entonces 1 si el píxel está por encima de la media, o 0 si está por debajo de la media. Para comparar la similitud entre dos imágenes, simplemente compara los hashes bit a bit y devuelve una distancia de Hamming. Cuanto menor es la distancia de Hamming, más similares son las imágenes. Cualquier valor por encima de 21 / 64 se considera no similar. El pHash parece usar codificación YCbCr. Algunos hablan de trabajar directamente con la DCT de JPEG, y lo más prometedor trabaja con la magnitud/fase y la mapea a un sistema de coordenadas polares logarítmicas.
Hacer coincidir mejor las imágenes
Notas y técnicas diversas que no he probado o que no funcionaron muy bien para comparar imágenes más grandes con una coincidencia más exacta.
Color de segmentación
Como puede ver, muchas de las métricas anteriores usan un filtro de desenfoque/mediana seguido de técnicas de reducción de color, intentos básicos de simplificar las imágenes para poder clasificarlas mejor. No obstante, el operador de cuantización de color no está realmente diseñado para este fin. Su trabajo es reducir los colores para resaltar los detalles importantes de la imagen. Sin embargo, para la comparación de imágenes no queremos realmente resaltar estas características, sino resaltar zonas de interés comparativo. Este es el trabajo de una técnica de color relacionada conocida como segmentación... INCISO: de Leptonica: la segmentación de imágenes es la división de la imagen en regiones que tienen propiedades distintas. Este operador bloquea zonas de colores similares, eliminando el detalle de esas zonas. Luego, al comparar las dos imágenes, está comparando zonas en lugar de detalles de bajo nivel de las imágenes. IM implementa un algoritmo de segmentación, «[-segment](https://imagemagick.org/command-line-options/#segment)»; para los detalles de su implementación, vea SegmentImage(). Ejemplo:
magick logo: -median 10 -segment 1x1 \
+dither -scale 100x100\! segment_image.gif
Un problema es que -segment es MUY lento y solo parece funcionar con imágenes más grandes. Las imágenes pequeñas (como una rose: o un logo: escalado a 100x100) parecen dar como resultado un único color. Esto puede ser un error. Por supuesto, puede escalar la imagen después de segmentarla, como hicimos arriba; así puede almacenar un mayor número de imágenes en memoria para compararlas entre sí. Además, la segmentación resultante no parece funcionar muy bien comparada con el algoritmo de segmentación de imágenes que proporciona Leptonica. Vea Leptonica: Color Segmentation. No obstante, una alternativa a la segmentación de IM es hacer un mal uso de la función de cuantización de color para encontrar zonas de color similar. Ejemplo:
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 segment_image.gif
La desventaja es que -color limita el número de zonas de color que puede haber en una imagen, mientras que segment intenta preservar las zonas similares, con independencia de cuántas zonas haya realmente en la imagen (o al menos eso es lo que debería hacer).
Comparación de bordes sin color
El color de las imágenes es notoriamente poco fiable, sobre todo para imágenes de tipo dibujo animado. Distintos usuarios podrían fácilmente recolorear esas imágenes, añadir fondos de colores distintos, o incluso tomar un boceto y colorearlo. Una forma de emparejar esas imágenes es hacer alguna reducción básica de color, como en el método anterior, pero luego, en lugar de comparar las imágenes según el color resultante, se realiza una detección de bordes y un procesamiento adicional, de modo que solo se usen los contornos de los cambios de color más importantes para las métricas y la comparación de las imágenes. Por ejemplo...
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 -edge 1 \
-colorspace gray -blur 0x1 outline_image.gif
Una alternativa puede ser usar -lat (umbral de área local) para la detección de bordes, lo que puede darle un mejor control...
magick logo: -scale 100x100\! -median 3 \
-quantize YIQ +dither -colors 3 \
-lat 3x3-5% -negate \
-colorspace gray -blur 0x1 outline_image.gif
Por supuesto, para comparar usaría un método de comparación de dibujos de líneas.
??? ¿cómo compararía dibujos de líneas de una forma viable ???
Multiplique las imágenes entre sí y vea si la imagen resultante aumentó o redujo la intensidad de las líneas. Las líneas que no coinciden se volverán negras.
Cámaras web
Qué ha cambiado en cámaras fijas
En construcción
Walter Perry
![[IM Output]](../static/img/images/bag_frame1.gif)
![[IM Output]](../static/img/images/bag_frame2.gif)
![[IM Output]](../static/img/compare/compare.gif)
![[IM Output]](../static/img/compare/bag_frame1.jpg)
![[IM Output]](../static/img/compare/compare_lossy_jpeg.gif)
![[IM Text]](../static/img/compare/compare_fuzz.txt.gif)
![[IM Text]](../static/img/compare/greyscale_test.txt.gif)