vegetarianas tipos son que proteínas proteinas proteina proporcionan pobres las ejemplos dietas dieta calidad bioquimica baja alta alimentos c# image algorithm image-processing pattern-matching
hereaplicación de línea de comandos C #

c# - tipos - Encontrar coincidencias entre imágenes pixeladas de alta calidad y baja calidad: ¿es posible? ¿Cómo?



proteinas de baja calidad (18)

Tengo un problema. Mi compañía me ha dado una tarea terriblemente aburrida. Tenemos dos bases de datos de cuadros de diálogo. Una de estas bases de datos contiene imágenes de calidad horrible, la otra de muy alta calidad.

Desafortunadamente, los diálogos de calidad horrible contienen asignaciones importantes a otra información.

Me han encargado, de forma manual, revisar todas las imágenes malas y ponerlas en buenas imágenes.

¿Sería posible automatizar este proceso en algún grado? Aquí hay un ejemplo de dos cuadros de diálogo (extraídos al azar de las imágenes de Google):

Por lo tanto, actualmente estoy intentando escribir un programa en C # para extraer estas fotos de la base de datos, recorrerlas, encontrar las que tienen formas comunes y devolver sus ID. ¿Cuáles son mis mejores opciones aquí?


¿Has probado las técnicas de contorno / umbral en combinación con una ventana de promedio andante (para valores RGB)?


Creo que un enfoque híbrido para esto sería lo mejor para resolver su problema particular de coincidencia de lotes

  1. Aplique el algoritmo Hashing de imagen sugerido por @Paolo Morreti, a todas las imágenes
  2. Para cada imagen en un conjunto, busque el subconjunto de imágenes con un hash más cerca que una distancia establecida
  3. Para este espacio de búsqueda reducido, ahora puede aplicar costosos métodos de coincidencia como lo sugieren @Running Wild o @Raskolnikov ... gana el mejor.

Dado que este es un trabajo aislado, me las arreglaría con un guión (elija su idioma favorito, probablemente elegiría Perl) e ImageMagick . Podría usar C # para lograr lo mismo que el script, aunque con más código. Simplemente llame a las utilidades de línea de comandos y analice la salida resultante.

La secuencia de comandos para comprobar la similitud de un par sería de aproximadamente 10 líneas de la siguiente manera:

Primero recupere los tamaños con identify y verifique las proporciones de aspecto casi de la misma manera. Si no, no hay coincidencia. Si es así, escale la imagen más grande al tamaño de la más pequeña con convert . Debe experimentar un poco de antelación con filter opciones de filter para encontrar el que produce la mayor similitud en las imágenes equivalentes conocidas. Nueve de ellos están disponibles.

Luego use la función de compare para producir una métrica de similitud. Compare es lo suficientemente inteligente como para lidiar con la traducción y el cultivo. Experimente para encontrar un umbral de similitud que no proporcione demasiados falsos positivos.


En mi humilde opinión, la mejor solución es difuminar ambas imágenes y luego usar alguna medida de similitud (correlación / información mutua, etc.) para obtener las mejores opciones de K (K = 5 pueden ser?).


Haría algo como esto:

  • Si ya sabe cómo se han difuminado las imágenes borrosas, aplique la misma función a las imágenes de alta calidad antes de compararlas.

    • Luego compara las imágenes usando mínimos cuadrados como se sugirió anteriormente.
    • El valor más bajo debería darle una coincidencia. Idealmente, obtendrías 0 si ambas imágenes son idénticas
    • para agilizar las cosas, puede realizar la mayoría de las comparaciones en las imágenes muestreadas y luego refinar en una submuestra seleccionada de las imágenes
  • Si no sabe, pruebe varias funciones probables (compresión JPEG, reducción de resolución, ...) y repita



La respuesta de Running Wild es muy cercana. Lo que está haciendo aquí es calcular la relación entre la señal pico y el ruido para cada imagen, o PSNR. En su caso, realmente solo necesita el error cuadrático medio, pero el componente de cuadratura ayuda mucho al calcular la diferencia entre las imágenes.

Referencia de PSNR

Tu código debe verse así:

sum = 0.0 for(imageHeight){ for(imageWidth){ errorR = firstImage(r,x,y) - secondImage(r,x,y) errorG = firstImage(g,x,y) - secondImage(g,x,y) errorB = firstImage(b,x,y) - secondImage(b,x,y) totalError = square(errorR) + square(errorG) + square(errorB) } sum += totalError } meanSquaredError = (sum / (imageHeight * imageWidth)) / 3


Me gusta mucho el algoritmo de Running Wild y creo que puede ser incluso más efectivo si puedes hacer que las dos imágenes sean más similares, por ejemplo, disminuyendo la calidad del mejor.


Podría intentar Recuperación de Imágenes Basadas en Contenido ( CBIR ).

Para decirlo sin rodeos:

  1. Para cada imagen en la base de datos, genere una huella digital usando una Transformada de Fourier
  2. Cargue la imagen de origen, haga una huella digital de la imagen
  3. Calcule la distancia euclidiana entre la fuente y todas las imágenes en la base de datos
  4. Ordenar los resultados

Podría probar un algoritmo de coincidencia de bloques, aunque no estoy seguro de su eficacia exacta contra su problema específico - http://scien.stanford.edu/pages/labsite/2001/ee368/projects2001/dropbox/project17/block.html - http://www.aforgenet.com/framework/docs/html/05d0ab7d-a1ae-7ea5-9f7b-a966c7824669.htm

Incluso si esto no funciona, aún debes consultar la biblioteca de Aforge.net. Aquí hay varias herramientas (incluida la comparación de bloques desde arriba) que podrían ayudarlo en este proceso: http://www.aforgenet.com/


Realmente no veo ninguna razón para utilizar bibliotecas externas para esto, he hecho este tipo de cosas muchas veces y el siguiente algoritmo funciona bastante bien. Asumiré que si comparas dos imágenes tienen las mismas dimensiones, pero puedes cambiar el tamaño de una si no es así.

badness := 0.0 For x, y over the entire image: r, g, b := color at x,y in image 1 R, G, B := color at x,y in image 2 badness += (r-R)*(r-R) + (g-G)*(g-G) + (b-B)*(b-B) badness /= (image width) * (image height)

Ahora que tiene un valor de maldad normalizado entre dos imágenes, cuanto menor es la maldad, más probabilidades hay de que las imágenes coincidan. Esto es simple y efectivo, hay una variedad de cosas que lo hacen funcionar mejor o más rápido en ciertos casos, pero es probable que no necesite nada de eso. Ni siquiera necesita normalizar la maldad, pero de esta manera puede obtener un umbral único si desea ver varias coincidencias posibles manualmente.

Dado que esta pregunta ha recibido más atención, he decidido agregar una forma de acelerar esto en los casos en los que está procesando muchas imágenes muchas veces. Usé este enfoque cuando tenía varias decenas de miles de imágenes que necesitaba comparar, y estaba seguro de que un par típico de imágenes sería muy diferente. También sabía que todas mis imágenes serían exactamente las mismas dimensiones. En una situación en la que está comparando cuadros de diálogo, sus imágenes típicas pueden ser en su mayoría grises, y algunas de sus imágenes pueden requerir cambio de tamaño (aunque tal vez eso solo indique un desajuste), en cuyo caso este enfoque puede no ganarle. mucho.

La idea es formar un quad-tree donde cada nodo represente los valores RGB promedio de la región que ese nodo representa. Entonces, una imagen 4x4 tendría un nodo raíz con valores RGB iguales al valor RGB promedio de la imagen, sus hijos tendrían valores RGB que representaban el valor RGB promedio de sus respectivas regiones 2x2, y sus hijos representarían píxeles individuales. (En la práctica, es una buena idea no ir más allá de una región de aproximadamente 16x16, en ese punto debería comenzar comparando píxeles individuales).

Antes de comenzar a comparar imágenes, también deberá decidir sobre un umbral de maldad. No calculará maldades por encima de este umbral con una precisión confiable, por lo que este es básicamente el umbral en el que está dispuesto a etiquetar una imagen como "no coincidente".

Ahora, cuando compara la imagen A con la imagen B, primero compare los nodos raíz de sus representaciones de árbol cuádruple. Calcule la maldad como lo haría con una imagen de un solo píxel, y si la maldad excede su umbral, regrese inmediatamente e informe la maldad en este nivel. Como está utilizando maldades normalizadas, y como las maldades se calculan usando diferencias al cuadrado, la maldad en cualquier nivel particular será igual o menor que la maldad en niveles inferiores, por lo que si excede el umbral en cualquier punto que sepa, también excederá el umbral en el nivel de píxeles individuales.

Si la prueba de umbral pasa una imagen nxn, simplemente baje al siguiente nivel y compárela como si fuera una imagen 2nx2n. Una vez que te bajas lo suficiente, simplemente compara los píxeles individuales. Dependiendo de su corpus de imágenes, esto le puede permitir omitir muchas comparaciones.


Si calcula solo la diferencia de píxeles de las imágenes, solo funcionará si las imágenes tienen el mismo tamaño o si sabe exactamente cómo escalarlas en dirección horizontal y vertical, y tampoco tendrá ningún cambio o invarianza de rotación.

Así que recomiendo usar la métrica de diferencia de píxeles solo si tiene la forma más simple de problema (las imágenes son las mismas en todas las características, pero la calidad es diferente, y por qué la calidad es diferente? Artefactos jpeg o simplemente reescalar?), De lo contrario recomiendo usa una correlación cruzada normalizada, es una métrica más estable. Puedes hacerlo con FFTW o con OpenCV.


Si extrae los contornos de la imagen, puede usar ShapeContext para obtener una buena coincidencia de imágenes.

ShapeContext es creación para estas cosas exactas (comparando imágenes basadas en formas mutuas)

Enlaces de implementación de ShapeContext: publicación original Un ppt de goot sobre el tema Página de CodeProject sobre ShapeContext

* Es posible que debas probar algunas técnicas de "extracción de contorno" como umbrales o transformada de Fourier, o echar un vistazo a esta página de CodeProject sobre la extracción de contorno

Buena suerte.


Si la mala calidad es solo el resultado de una menor resolución, entonces:

  • cambiar la escala de la imagen de alta calidad a resolución de imagen de baja calidad (o reescalar ambos a igual resolución baja)
  • compara cada color de píxel para encontrar la coincidencia más cercana

Así que, por ejemplo, cambiar el tamaño de todas las imágenes a 32x32 y comparar ese conjunto por píxeles debería dar resultados bastante razonables y es aún más fácil de hacer. Aunque el método de cambio de escala puede hacer la diferencia aquí.


Solo pensando en voz alta:

Si usa dos imágenes que deben compararse como capas y las combina (restar una de la otra), obtendrá una nueva imagen (algunos programas de dibujo pueden ser creados con scripts para hacer conversiones por lotes, o puede usar la GPU escribiendo un pequeño DirectX o Programa OpenGL)

A continuación, debería obtener el brillo de la imagen resultante; cuanto más oscuro es, mejor es el partido.


Supongo que las imágenes de las dos bases de datos muestran el mismo diálogo y que las imágenes deben ser idénticas pero de diferente calidad. Luego, las imágenes coincidentes tendrán la misma relación de aspecto (o muy cerca de la misma).

Si las imágenes de baja calidad se produjeron a partir de imágenes de alta calidad (o imagen equivalente), debe usar el mismo procedimiento de procesamiento de imágenes que un paso de preprocesamiento en la imagen de alta calidad y combinar con la base de datos de imágenes de baja calidad. Entonces, la comparación píxel a píxel o la coincidencia de histograma debería funcionar bien.

La coincidencia de imágenes puede usar muchos recursos si tiene muchas imágenes. Tal vez un enfoque multipaso es una buena idea? Por ejemplo: pase 1: use medidas simples como relación de aspecto para agrupar imágenes (campos de ancho y alto en db?) (Computacionalmente barato) Pase 2: partido o grupo por histograma para canal de primer color (o todos los canales) (relativamente computacionalmente) barato)

También recomendaré OpenCV. Puede usarlo con c, c ++ y Python (y pronto Java).


Yo personalmente iría por un algoritmo de hashing de imagen.

El objetivo del hash de imágenes es transformar el contenido de la imagen en una secuencia de características para obtener una representación condensada. Esta secuencia de características (es decir, un vector de bits) debe ser lo suficientemente corta para una correspondencia rápida y preservar características distinguibles para que la medición de similitud sea factible.

Hay varios algoritmos que están disponibles gratuitamente a través de comunidades de código abierto.

Un ejemplo simple se puede encontrar en este artículo , donde el Dr. Neal Krawetz muestra cómo funciona el algoritmo Average Hash :

  1. Reducir el tamaño La forma más rápida de eliminar las altas frecuencias y los detalles es reducir la imagen. En este caso, reduzca a 8x8 para que haya 64 píxeles en total. No te preocupes por mantener la relación de aspecto, simplemente aplástala para que quepa en un cuadrado de 8x8. De esta forma, el hash coincidirá con cualquier variación de la imagen, independientemente de la escala o la relación de aspecto.
  2. Reducir el color La pequeña imagen de 8x8 se convierte a escala de grises. Esto cambia el hash de 64 píxeles (64 rojo, 64 verde y 64 azul) a 64 colores en total.
  3. Promedio de los colores . Calcule el valor medio de los 64 colores.
  4. Calcule los bits . Esta es la parte divertida. Cada bit simplemente se establece en función de si el valor del color está por encima o por debajo de la media.
  5. Construye el hash . Establezca los 64 bits en un entero de 64 bits. El orden no importa, siempre que seas consecuente. (Configuro los bits de izquierda a derecha, de arriba abajo usando big-endian).

David Oftedal escribió una aplicación de línea de comandos C # que puede clasificar y comparar imágenes usando el algoritmo Average Hash. (Probé su implementación con sus imágenes de muestra y obtuve un 98.4% de similitud).

El principal beneficio de esta solución es que lee cada imagen solo una vez, crea los hashes y los clasifica en función de su similiaridad (utilizando, por ejemplo, la distancia de Hamming ).

De esta manera, desacopla la fase de extracción de características de la fase de clasificación, y puede cambiar fácilmente a otro algoritmo de hash si encuentra que no es lo suficientemente preciso.

Editar

Puede encontrar un ejemplo simple here (Incluye un conjunto de prueba de 40 imágenes y obtiene una puntuación de 40/40).


Aquí hay un tema que analiza la similitud de imágenes con algoritmos, ya implementado en la biblioteca OpenCV . No debería tener problemas para importar funciones de bajo nivel en su aplicación C #.