2010-08-17 22 views
17

Actualmente extiendo una biblioteca de imágenes utilizada para categorizar imágenes y quiero encontrar imágenes duplicadas, imágenes transformadas e imágenes que contienen o están contenidas en otras imágenes.
He probado la implementación SIFT de OpenCV y funciona muy bien pero sería bastante lento para múltiples imágenes. Demasiado rápido, pensé que podría extraer las características y guardarlas en una base de datos, ya que muchos otros metadatos relacionados con imágenes ya se están reteniendo allí.Comparación de las características de SIFT almacenadas en una base de datos mysql

¿Cuál sería la forma más rápida de comparar las características de una nueva imagen con las características de la base de datos?
Por lo general, la comparación se hace calculando la distancia euclidiana usando kd-trees, FLANN, o con el Pyramid Match Kernel que encontré en otro hilo aquí en SO, pero aún no he investigado mucho.

Ya que no sé de una manera de ahorrar y buscar un kd-árbol en una base de datos de manera eficiente, estoy actualmente sólo ver tres opciones:
* Vamos MySQL calcular la distancia euclídea a todas las características de la base de datos , aunque estoy seguro de que tomará un tiempo irrazonable para más de unas pocas imágenes.
* Cargue todo el conjunto de datos en la memoria al principio y construya los kd-tree (s). Esto probablemente sea rápido, pero con mucha memoria. Además, todos los datos deberían transferirse desde la base de datos.
* Guardar los árboles generados en la base de datos y cargarlos a todos, sería el método más rápido pero también generaría grandes cantidades de tráfico ya que con las nuevas imágenes los árboles-kd tendrían que reconstruirse y enviarse al servidor.

Estoy usando la implementación SIFT de OpenCV, pero no estoy totalmente equivocado. Si hay un extractor de funciones más adecuado para esta tarea (y más o menos igualmente robusto) me alegra que alguien pueda sugerir uno.

+4

OpenCV ya incluye una implementación de SURF así como Kd-Trees para la coincidencia (ya no es necesario SIFT). Y: Esto no está directamente relacionado con su pregunta, pero es posible que desee considerar la coincidencia de histogramas (u otras características globales) primero. De esta forma, posiblemente podría reducir drásticamente la cantidad de pares de imágenes para compararlas con las características lentas de alta dimensión al eliminar de antemano todos los candidatos con histogramas muy diferentes. – zerm

Respuesta

14

Así que básicamente hizo algo muy similar a esto hace unos años. El algoritmo que desea estudiar fue propuesto hace unos años por David Nister, el documento es: "Reconocimiento escalable con un árbol de vocabulario". Prácticamente tienen una solución exacta a su problema que puede escalar a millones de imágenes.

Aquí hay un enlace a lo abstracto, se puede encontrar un enlace de descarga por googleing el título. http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=1641018

La idea básica es construir un árbol jerárquico con un algoritmo k-medias para modelar las características y luego aprovechar la distribución dispersa de características en ese árbol para encontrar rápidamente sus vecinos más cercanos ... o algo por el estilo, Han pasado algunos años desde que trabajé en eso. Se puede encontrar una presentación de PowerPoint en la autores página web aquí: http://www.vis.uky.edu/~dnister/Publications/publications.html

A otras pocas notas:

  • no me molestaría con el núcleo partido pirámide, es realmente más para mejorar el reconocimiento de objetos de duplicar/detección de imágenes transformadas.

  • no habría almacenar cualquiera de estas cosas entidad en una base de datos SQL. Dependiendo de su aplicación, es veces más eficaz para calcular sus características sobre la marcha, ya que su tamaño puede exceder el tamaño de la imagen original cuando computarizada densamente. Los histogramas de características o punteros a nodos en un árbol de vocabulario son mucho más eficientes.

  • bases de datos SQL no están diseñados para hacer cálculos masivos punto vector flotantes. Puede almacenar cosas en su base de datos, pero no las use como una herramienta para el cálculo. Intenté esto una vez con SQLite y terminó muy mal.

  • Si decide implementar esto, lea el documento en detalle y tenga una copia a mano mientras lo implementa, ya que hay muchos detalles menores que son muy importantes para que el algoritmo funcione de manera eficiente.

+0

Eso parece mucho de lo que estaba buscando. ¡Gracias! Sé que las bases de datos SQL no son óptimas, ¿qué método de almacenamiento usaría? El ingenuo "Obtener todo lo que la memoria permita (desde db o archivos), calcular, obtener el próximo" parece un poco crudo. Aunque parece que se beneficiaría de la paralelización masiva que ofrece la computación GPU, que a su vez requeriría ese tipo de gestión de datos. Tendré que estrenar eso, supongo. – Darcara

+0

Si implementa el método de árbol HK-means, debería poder caber todo el árbol en la memoria de una vez (si no puede, comprar más memoria). Luego puede almacenar las hojas del árbol en el disco si es necesario. – Doug

+0

¿Alguien implementó esta solución? – Wiliam

2

La clave, creo, es que esta no es una pregunta SIFT. Es una pregunta sobre la búsqueda aproximada del vecino más cercano. Al igual que la imagen que coincide con esto también es un problema de investigación abierta. Puede intentar buscar en Google "búsqueda de vecinos más cercanos" y ver qué tipo de métodos están disponibles. Si necesita resultados exactos, intente: "búsqueda exacta del vecino más cercano".

El rendimiento de todas estas estructuras de datos geométricos (como kd-trees) se degrada a medida que aumenta el número de dimensiones, por lo que la clave es que puede necesitar representar sus descripciones SIFT en un menor número de dimensiones (por ejemplo 10-30 en lugar de 256-1024) para tener búsquedas realmente eficaces en el vecino más cercano (use PCA por ejemplo).

Una vez que tenga esto, creo que se volverá secundario si los datos están almacenados en MySQL o no.

+0

Sé cómo comparar las funciones. Estoy buscando una forma de utilizar el poder de la base de datos para hacerlo de manera más eficiente que las 3 ingenuas ideas que describí. No he encontrado algoritmos de búsqueda que se ajusten a los requisitos especiales y las fortalezas de las bases de datos (relacionales). – Darcara

+1

Su pregunta sonaba más como: dado que ya uso una base de datos, decidí poner los descriptores allí también, ¿cómo puedo hacer esto posible? Para decirlo más sucintamente, mi respuesta es: no creo que encuentres ningún algoritmo que tenga en cuenta la fortaleza de una base de datos relacional. Las bases de datos espaciales son prácticas de hasta 2 o 3 dimensiones (buscar GIS). No se comprenden los aspectos geométricos de las dimensiones superiores (por ejemplo, más de 5). – carlosdc

1

Creo que la velocidad no es el problema principal aquí. El problema principal es cómo usar las características para obtener los resultados que desea.

Si desea categorizar las imágenes (por ejemplo, persona, automóvil, casa, gato), definitivamente vale la pena mirar el núcleo Pyramid Match. En realidad, es un histograma de los descriptores de las características locales, por lo que no es necesario comparar las características individuales entre sí. También hay una clase de algoritmos conocida como la "bolsa de palabras", que intenta agrupar las características locales para formar un "vocabulario visual". Nuevamente, en este caso, una vez que tenga sus "palabras visuales", no necesita calcular distancias entre todos los pares de descriptores SIFT, sino que determina a qué grupo pertenece cada característica. Por otro lado, si desea obtener correspondencias de puntos entre pares de imágenes, como para decidir si una imagen está contenida en otra, o para calcular la transformación entre las imágenes, entonces necesita encontrar los vecinos más cercanos.

Además, hay características locales distintos a cribar. Por ejemplo, SURF son características similares a SIFT, pero son más rápidas de extraer y se ha demostrado que funcionan mejor para ciertas tareas.

Si todo lo que quiere hacer es encontrar duplicados, puede acelerar su búsqueda considerablemente utilizando un descriptor de imagen global, como un histograma de color, para eliminar las imágenes que son obviamente diferentes. La comparación de dos histogramas de color es mucho más rápida que la comparación de dos conjuntos que contienen cientos de características SIFT. Puede crear una lista breve de candidatos usando histogramas de color y luego refinar su búsqueda utilizando SIFT.

+1

El núcleo de la pirámide parece interesante, ya que agrega los datos más, por lo que hay menos para buscar. Sin embargo, mi principal objetivo no es el reconocimiento de objetos o la categorización, sino encontrar duplicados que se hayan transformado significativamente, por lo que una simple coincidencia de histogramas es desafortunadamente insuficiente. – Darcara

+0

Por supuesto, en su caso, la coincidencia de histogramas es insuficiente. Pero le permitirá rechazar rápidamente un gran porcentaje de no duplicados. Piense en ello como un proceso de dos etapas: si los histogramas de color coinciden, solo entonces intente hacer coincidir las características de SIFT. – Dima

1

Tengo algunas herramientas en python con las que puedes jugar con here. Básicamente es un paquete que usa vectores transformados SIFT, y luego calcula el hashing de celosía más cercano de cada vector de cribado de 128d. El hash es la parte importante, ya que es sensible a la localidad, lo que significa que los vectores cercanos en el espacio R^n dan como resultado probabilidades de colisión hash equivalentes. El trabajo que proporciono es una extensión de Andoni que proporciona una heurística adaptativa de consulta para eliminar las listas de búsqueda exacta de LSH, así como una implementación CUDA optimizada de la función de hashing. También tengo una pequeña aplicación que realiza búsquedas en la base de datos de imágenes con buenos comentarios visuales, todo bajo bsd (la excepción es SIFT, que tiene algunas restricciones adicionales).

Cuestiones relacionadas