Comparativa de algoritmos de detección de características para visión artificial
Texto completo
(2)
(3) 3. Abstract Features detection is one of the essential components of several artificial vision applications; this is the reason why it has received an increasing attention in the last few years. A wide variety of detectors and feature descriptors have been proposed during all this time, taking into account the parameters chosen when selecting the features. All applications of artificial vision depend on the presence of reliable and stable features, so it is important that these are selected correctly. The objectives of this project are to describe the steps of the Structure From Motion (SFM) technique, where the detection of characteristics fits and indicate the importance of selecting the appropriate algorithm to locate them. We will also analyze the best known algorithms (Moravec, Harris and Shi-Tomasi algorithms), showing their advantages and disadvantages, as well as methods of evaluating their performance.. Resumen La detección de caracterı́sticas es uno de los componentes esenciales de varias aplicaciones de visión artificial, por lo que ha recibido una creciente atención en los últimos años. Se ha propuesto durante todo este tiempo una gran variedad de detectores y descriptores de caracterı́sticas atendiendo a los parámetros elegidos a la hora de hacer la selección de caracterı́sticas. Todas las aplicaciones de visión artificial dependen de la presencia de caracterı́sticas fiables y estables, por lo que es importante que estas se seleccionen correctamente. Los objetivos de este proyecto son describir los pasos de la tecnica Structure From Motion (SFM), dónde encaja la detección de caracterı́sticas e indicar la importancia de seleccionar el algoritmo adecuado para localizarlas. También se analizarán los algoritmos más conocidos (Moravec, Harris y ShiTomasi), mostrando sus ventajas y desventajas, ası́ como métodos de evaluar el rendimiento..
(4)
(5) Índice general 1. Introducción. 7. 1.1. Objetivos y motivaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 7. 1.2. Estructura del documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 8. 2. Definiciones y principios 2.1. Caracterı́sticas globales y locales . . . . . . . . . . . . . . . . . . . . . . . . . . .. 9 9. 2.2. Propiedades de los detectores de caracterı́sticas . . . . . . . . . . . . . . . . . . 10 3. Problema. 13. 3.1. Detectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3.2. Descriptores de caracterı́sticas visuales . . . . . . . . . . . . . . . . . . . . . . . 14 3.3. Correspondencia de caracterı́sticas . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4. Estado del arte. 17. 4.1. Tipos de detectores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.1.1. Detectores de escala única . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2. Algoritmos correspondencia de caracterı́sticas . . . . . . . . . . . . . . . . . . . 24 5. Código. 27. 5.1. Estructura del código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.1.1. AlgorithmTester.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.1.2. Transformer.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 5.1.3. featureDetector.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 5.1.4. Matcher.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 5.2. Funcionamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 5.3. Limitaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 6. Pruebas. 33. 6.1. Pruebas de validación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33.
(6) 6. ÍNDICE GENERAL 6.2. Pruebas de rendimiento de los algoritmos . . . . . . . . . . . . . . . . . . . . . . 34. 7. Conclusiones 37 7.1. Evaluación del algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 7.2. Aspectos sociales, ambientales y éticos . . . . . . . . . . . . . . . . . . . . . . . 40 7.3. Trabajo futuro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 8. Anexo I. 45.
(7) Capı́tulo 1. Introducción. 1.1.. Objetivos y motivaciones. En las últimas décadas, los detectores y descriptores de caracterı́sticas de imágenes se han convertido en herramientas populares en la comunidad de visión artificial y se están usando ampliamente en un gran número de aplicaciones. Entre otras, en la representación de imágenes [1], clasificación y recuperación de imágenes [2, 3, 4, 5], detección y reconocimiento de objetos [6, 7, 8, 9, 10], reconstrucción de escenas 3D [11], captura de movimiento [12, 13, 14], clasificación de texturas [15, 16], localización de robots [17, 18, 19], y sistemas biométricos [20, 21, 22], todos dependen de la presencia de caracterı́sticas estables y representativas en las imágenes. Por ello, detectar y extraer caracterı́sticas de una imagen son pasos vitales para estas aplicaciones. Con frecuencia en visión artificial es necesario establecer correspondencias entre caracterı́sticas de dos imágenes dadas. A fin de establecer esas correspondencias se requiere identificar un conjunto de puntos destacados en cada imagen [8, 23]. En una tarea de clasificación, los descriptores de caracterı́sticas de la imagen consulta son emparejados con todas las caracterı́sticas de las imágenes de entrenamiento y la imagen de entrenamiento que da la máxima correspondencia entre puntos se considera la mejor correspondencia con la imagen consulta. En este caso, la correspondencia con descriptores de caracterı́sticas se puede basar en medidas de distancia, tales como la distancia Euclı́dea o la distancia de Mahalanobis. Dada la importancia de los detectores de caracterı́sticas en las distintas aplicaciones de visión artificial, este trabajo se centra en el análisis de rendimiento de varios de estos algoritmos de detección de puntos de interés, en concreto los algoritmos de Moravec, Harris y Shi-Tomasi. Existen más algoritmos de detección, pero por la extensión y alcance de trabajo nos centramos en esos tres..
(8) 8. Introducción. 1.2.. Estructura del documento. El presente documento está dividido en 7 partes: A continuación de esta descripción, la sección 2 introduce unos términos básicos necesarios para la comprensión de la visión artificial, ası́ como algunas propiedades de los detectores de caracterı́sticas. La sección 3 explorará el problema de la de la visión artificial, desde la detección de puntos de interés, hasta la correspondencia de caracterı́sticas mediante el uso de descriptores. Sección 4, se examinan algunos de los algoritmos disponibles para detección de esquinas; entre ellos, se encuentran los que se analizarán en este trabajo. Asimismo, se explica de forma breve los dos algoritmos más usados para la correspondencia de caracterı́sticas. La sección 5 describirá el código usado en detalle. Será analizado al objeto de exponer sus limitaciones. En la sección 6, la salida de los algoritmos será evaluada con el fin de estudiar el rendimiento, junto con las ventajas y desventajas de los mismos. Finalmente, en el capı́tulo 7, se presentarán las conclusiones de este proyecto, junto con una pequeña descripción de la dirección en la que se pueda encaminar una futura investigación sobre esta materia..
(9) Capı́tulo 2. Definiciones y principios 2.1.. Caracterı́sticas globales y locales. En tareas de procesamiento de imágenes y visión artificial, se necesita representar las imágenes mediante caracterı́sticas extraı́das de las mismas. La imagen en bruto es perfecta para que el ojo humano extraiga toda la información de ella. Sin embargo, este no es el caso para los algoritmos informáticos. Generalmente, hay dos métodos para representar imágenes: mediante caracterı́sticas globales y locales. En la representación de forma global, la imagen se representa por un vector de caracterı́sticas multidimensional que describe la información de toda la imagen. En otras palabras, el método de representación global produce un sólo vector con valores que miden varios aspectos de la imagen, tales como, color, textura o forma. De forma práctica, se extrae un sólo vector de cada imagen, y posteriormente se pueden comparar dos imágenes al comparar sus vectores de caracterı́sticas. Por ejemplo, cuando se quiere distinguir imágenes de un mar (azul) y un bosque (verde), un descriptor global de color producirı́a vectores bastante diferentes para cada categorı́a. En este contexto, las caracterı́sticas globales pueden ser interpretadas como una propiedad particular de la imagen que involucra todos los pı́xeles. Esta propiedad puede ser histogramas de color, textura, bordes o incluso un descriptor especı́fico extraı́do al aplicar algunos filtros sobre la imagen [24]. Por otro lado, el objetivo principal de la representación de caracterı́sticas locales es representar de manera distintiva la imagen en función de algunas regiones destacadas, mientras que permanece invariante a los cambios de punto de vista e iluminación. Por lo tanto, la imagen se representa en base a sus estructuras locales dadas por un conjunto de descriptores de caracterı́sticas locales extraı́dos de una colección de regiones de la imagen llamadas regiones de interés, como se ilustra en la Figura 2.1. La mayorı́a de las caracterı́sticas locales representan la textura del interior de las áreas de la imagen. Generalmente, el uso del tipo de caracterı́sticas puede depender en gran medida en la aplicación que se le vaya a dar. Por ejemplo, para grandes conjuntos de datos en aplicaciones de indexación de imágenes a escala web, es más apropiado considerar las caracterı́sticas globales. También, las caracterı́sticas globales son útiles en aplicaciones donde está disponible una segmentación aproximada del objeto de interés. Algunas de las ventajas son la rapidez.
(10) 10. Definiciones y principios. (a) Caracterı́sticas globales. (b) Caracterı́sticas locales. Figura 2.1: Representación de caracterı́sticas de una imagen. y compactación a la vez que facilidad cálculo, y normalmente requieren pequeñas cantidades de memoria. Sin embargo, la representación global sufre de limitaciones conocidas, en particular no son invariantes a transformaciones y sensibles al desorden y la oclusión. En algunas aplicaciones, como la detección de copias, la mayorı́a de las copias ilegales son muy similares al original; sólo han sufrido compresión, escalado o recorte. En contraste, la ventaja de las caracterı́sticas locales es su rendimiento superior [25]. El uso de representaciones locales para búsquedas de imágenes a gran escala tiene un rendimiento mucho mayor que el que ofrecen las funciones globales [26]. Además, como las estructuras locales son más distintivas y estables que otras estructuras en regiones planas, se espera que sea más útil para la coincidencia de imágenes y el reconocimiento de objetos. Sin embargo, generalmente requieren una cantidad significativa de memoria porque la imagen puede tener cientos de caracterı́sticas locales. Como solución para este problema, los investigadores sugieren agregar descriptores de imagen locales en una representación vectorial muy compacta y optimizar la reducción de la dimensionalidad de estos vectores [26].. 2.2.. Propiedades de los detectores de caracterı́sticas. Tuytelaars and Mikolajczyk [27] definen una caracterı́stica local como “un patrón de la imagen que difiere de su entorno inmediato“. Por tanto, consideran que la finalidad de las caracterı́sticas locales invariantes es proveer una representación que permita encontrar correspondencias entre estructuras locales de varias imágenes de manera eficiente. Es decir, se quiere obtener un conjunto disperso de medidas locales que capturen la esencia subyacente de las imágenes de entrada y codifique sus estructuras de interés. Para alcanzar esta meta, los detectores y extractores de caracterı́sticas deben poseer ciertas propiedades teniendo en cuenta que la importancia de dichas propiedades depende en las configuración actual de la aplicación y de los requisitos necesarios. Las siguientes propiedades son importantes para la utilización de un detector de caracterı́sticas en aplicaciones de visión artificial:.
(11) 2.2. Propiedades de los detectores de caracterı́sticas. 11. Robustez, los algoritmos de detección de caracterı́sticas deberı́an ser capaces de detectar las mismas caracterı́sticas independientemente de escalado, rotación, traslación, deformaciones fotométricas, artefactos de compresión y ruido. Repetibilidad, los algoritmos de detección de caracterı́sticas deberı́a ser capaz de detectar las mismas caracterı́sticas de la misma escena u objeto repetidamente bajo una variedad de condiciones de visualización. Precisión, los algoritmos de detección de caracterı́sticas deberı́an ser capaces de localizar las caracterı́sticas de la imagen (misma localización de los pı́xeles), especialmente para tareas de correspondencia de imágenes, donde correspondencias precisas se requieren para estimar la geometrı́a epipolar. Generalidad, los algoritmos de detección de caracterı́sticas deberı́an ser capaces de detectar caracterı́sticas que puedan ser usadas en diferentes aplicaciones. Eficiencia, los algoritmos de detección de caracterı́sticas deberı́an ser capaces de detectar caracterı́sticas en nuevas imágenes rápidamente para poder soportar aplicaciones en tiempo real. Cantidad, los algoritmos de detección de caracterı́sticas deberı́an ser capaces de detectar todos o la mayorı́a de las caracterı́sticas en la imagen. La densidad de caracterı́sticas detectadas deberı́a reflejar la cantidad de información de la imagen para proveer una representación compacta de la imagen..
(12)
(13) Capı́tulo 3. Problema Cuando se trata de conceptos en visión artificial, la detección y comparación de caracterı́sticas son una de las técnicas esenciales en muchas de estas aplicaciones. Algunas tareas involucradas en esta técnica son el reconocimiento, la reconstrucción 3D, la estructura desde el movimiento, la imagen de recuperación, la detección de objetos entre otras. Esta técnica generalmente se divide en tres tareas que son detección, descripción y comparación. En la tarea de detección, los puntos que son fáciles de notar o coincidir se reconocen en cada imagen. En la tarea de descripción, el aspecto que rodea a cada caracterı́stica se representa de una manera que sea invariante frente a cambios de iluminación, traslación, escala y rotación en el plano. En la correspondencia, para clasificar caracterı́sticas similares, se comparan los descriptores entre imágenes.. 3.1.. Detectores. Los detectores de caracterı́sticas se pueden clasificar en lı́neas generales en tres categorı́as: detectores de escala única, detectores multiescala y detectores invariantes afines. En resumen, escala única significa que hay sólo una representación para las caracterı́sticas o los contornos del objeto usando los parámetros internos del detector. Estos detectores son invariantes en mayor o menor medida a transformaciones de imágenes tales como rotación, translación, cambios en la iluminación y agregación de ruido. Sin embargo, son incapables de tratar con problemas de escalado. Para extraer caracterı́sticas distintivas fiables dadas dos imágenes de la misma escena relacionadas por un cambio de escala, se hizo necesario el crear un detector multiescala. El trabajo se centrará en analizar los detectores de escala única más conocidos: Moravec, Harris y Shi-Tomasi..
(14) 14. Problema. 3.2.. Descriptores de caracterı́sticas visuales. Una vez que se han seleccionado los puntos de una imagen [p(x, y)], escala s, y orientación θ, su contenido necesita ser codificado en un descriptor adecuado para correspondencia y que no sea sensible a deformaciones locales de imagen. Los descriptores deberı́an estar alineados con θ y proporcionales a la escala s. Hay un gran número de descriptores de caracterı́sticas visuales en la literatura; algunos de los más usados son los siguientes: Speeded-Up Robust Features Descriptor (SURF) Scale Invariant Feature Transform (SIFT) Binary Robust Independent Elementary Features (BRIEF) Local Binary Pattern (LBP) Gradient Location-Orientation Histogram (GLOH). 3.3.. Correspondencia de caracterı́sticas. Correspondencia de caracterı́sticas o, generalmente, correspondencia de imágenes, es la tarea de establecer correspondencias entre dos imágenes que representan la misma escena u objeto. Forma parte de muchas aplicaciones de visión artificial tales como calibración de cámaras, reconocimiento de objetos y registro de imágenes. Un acercamiento común a la correspondencia de imágenes consiste en detectar un conjunto de puntos de interés asociados a descriptores de imagen. Una vez las caracterı́sticas y sus descriptores han sido extraı́dos de dos o más imágenes, el siguiente paso es establecer algunas correspondencias preliminares entre esas imágenes, tal y como se muestra en la figura 3.1.. Figura 3.1: Correspondencia entre caracterı́sticas de una imagen y de su correspondiente con una compresión del 95 %.
(15) 3.3. Correspondencia de caracterı́sticas. 15. Generalmente, el rendimiento de los métodos de correspondencia basados en puntos de interés dependen de los puntos en sı́ mismos y de los descriptores de la imagen [28]. Debido a esto, los detectores y los descriptores para los contenidos de las imágenes deben elegirse con sumo cuidado en las aplicaciones. Por ejemplo, si una imagen contiene células bacterianas, un detector de regiones deberı́a ser usado en vez de un detector de esquinas. Pero si la imagen es de una vista aérea de una ciudad, un detector de esquinas es más adecuado para encontrar estructuras artificiales. Es más, seleccionar un detector y descriptor que aborde las degradaciones de las imágenes es muy importante. Por ejemplo, si no hay cambios de escala presentes, un detector de esquinas que no controla la escala es muy apropiado; mientras que si una imagen contiene un alto nivel de distorsión, tales como escala y rotación, el detector y descriptor de caracterı́sticas SURF, que es más costoso computacionalmente hablando, es una opción más adecuada para ese caso. Para mayor precisión, se recomienda usar varios detectores y descriptores a la vez. Algunos de los métodos de correspondencia de imágenes son fuerza bruta y FLAAN..
(16)
(17) Capı́tulo 4. Estado del arte En este capı́tulo, se detallarán algunos de los algoritmos de los detectores de escala única y la correspondencia de caracterı́sticas.. 4.1.. Tipos de detectores. 4.1.1.. Detectores de escala única. Moravec Es uno de los algoritmos de detección de esquinas más antiguos y define una esquina como un punto con una baja autosimilitud [29]. El algoritmo comprueba cada pı́xel de la imagen para ver si existe alguna esquina, considerando la similitud entre un área centrada en el pı́xel seleccionado con áreas cercanas y en gran parte superpuestas. Esta similitud se mide tomando la suma de las diferencias de cuadrados entre los pı́xeles correspondientes de ambos parches. Cuanto menor es el número obtenido, mayor es la similitud. Si el pı́xel está en una región de intensidad uniforme, entonces las áreas cercanas serán similares. Si el pı́xel está en un borde, los parches en una dirección perpendicular al borde serán bastante diferentes, pero los situados en direcciones paralelas sólo tendrán una pequeña variación. Si el pı́xel se sitúa en una caracterı́stica con variaciones en todas las direcciones, entonces ningún área cercana tendrá bastante similitud. El peso de cada esquina se define como la mı́nima suma de diferencia de cuadrados entre el área seleccionado y los de sus alrededores (horizontal, vertical y en las dos diagonales). La razón es que si este número es elevado, entonces la variación a lo largo de todos los desplazamientos es o bien igual o mayor, por lo que resultarı́a que todas las áreas vecinas serı́an diferentes. Si el peso de la esquina se calcula para todas las ubicaciones, el hecho de que haya un máximo local para una ubicación indica que dicha esquina es un punto de interés..
(18) 18. Estado del arte Tal y como indica Moravec en su artı́culo [29], uno de los principales problemas de este operador es que no es isotrópico: si hay un borde presente en la direción de los vecinos (horizontal, vertical, o diagonal), entonces el mı́nimo de las sumas de diferencia de cuadrados será elevada y dicho borde será seleccionado erróneamente como punto de interés. El cambio de intensidad para el desplazamiento [u, v] vendrı́a dado por la siguiente ecuación: h i2 X E(u, v) = w(x, y) I(x + u, y + v) − I(x, y) x,y. Siendo w(x, y) la función para calcular el área, I(x + u, y + v) la intensidad del área desplazada e I(x, y) la intensidad del área seleccionada. Como previamente se ha detallado, los desplazamientos (u, v) se corresponderı́an con movimientos en horizontal, vertical y las dos diagonales: (u, v) = (1, 0), (1, 1), (0, 1), (−1, 1). (a) Flat. (b) Edge. (c) Corner. Figura 4.1: Ejemplos de desplazamientos para áreas planas, bordes y esquinas. Con estos cambios se calcuları́a el mı́nimo local, y si este se sitúa por encima de un umbral T , se considerarı́a como esquina o punto de interés. Este algoritmo de detección de esquinas presenta ciertos problemas: - Respuesta “ruidosa”debido al usar una función binaria para el cálculo de la ventana (Fig. 4.2a). - Sólo se considera un conjunto de desplazamientos a cada 45 grados..
(19) 4.1. Tipos de detectores. 19. - Responde con demasiado peso en los bordes al solamente tener en cuenta el mı́nimo de E. - El detector de esquinas de Harris [30] soluciona estos problemas.. (a) Moravec (Binario). (b) Harris (Gaussiano). Figura 4.2: Funciones para calcular las ventanas (áreas) de los algoritmos de detección. Harris Harris y Stephens [30] desarrollaron un detector combinado de esquinas y bordes para solucionar las limitaciones dadas por el detector de Moravec. Al obtener la variación de la autocorrelación (p.e., variación de intensidad) sobre todas las diferentes orientaciones, resulta en un detector más conveniente en términos de detección y tasa de repetibilidad. El detector resultante basado en la matriz de autocorrelación es la técnica más ampliamente usada. La matriz 2 x 2 simétrica de autocorrelación usada para detectar puntos de interés y describir sus estructuras locales se puede representar como Ix Iy (x, y) w(u, v) ∗ 2 Ix Iy (x, y) Iy (x, y) . M (x, y) =. X u,v. Ix2 (x, y). donde Ix e Iy son derivadas locales de la imagen en las direcciones x e y, respectivamente, y w(u, v) denota una ventana de ponderación sobre el área (u, v). Si una ventana circular es usada, tal y como una gaussiana, entonces la respuesta será isotrópica y los valores serán más ponderados según se acercan al centro de la ventana. Para encontrar puntos de interés, los se calculan los autovalores de la matriz M para cada pı́xel. Si ambos autovalores son grandes, esto indica la existencia de una esquina en esa localización. Se muestra un diagrama para la clasificación de los puntos con respecto a estos valores en la Fig. 4.3a. La construcción del mapa de respuesta se puede hacer calculando la medida de esquina (cornerness measure) C(x, y) para cada pı́xel (x, y) usando C(x, y) = det(M ) − K(trace(M ))2 donde.
(20) 20. Estado del arte. det(M ) = λ1 ∗ λ2 ,. y. trace(M ) = λ1 + λ2. El parámetro K es ajustable y λ1 , λ2 son los autovalores de la matriz de autocorrelación. El cálculo exacto de los autovalores es computacionalmente costoso, ya que requiere el cálculo de una raı́z cuadrada. Por tanto, Harris sugirió usar este valor para las esquinas que combina los dos autovalores en una sóla medida. Se deberı́a realizar una supresión no maximal para encontrar los extremos locales(una supresión maximal es una técnica para evitar que el algoritmo encuentre varias veces el mismo objeto). Todos los puntos distintos de cero que quedan en el mapa de esquinas son los puntos buscados. Shi-Tomasi El detector de esquinas de Harris tiene un criterio de selección de esquinas basado en una puntuación calculada por cada pı́xel. Si esta calificación está por encima de un cierto valor o umbral, el pı́xel se marca como esquina. Esta puntuación se calcula usando una función que utiliza dos valores eigen para obtener la valoración del pı́xel. En 1994, J. Shi y C. Tomasi sugirieron una pequeña modificación al algoritmo de Harris en su artı́culo Good Features to Track que muestra mejores resultados en comparación al detector de esquinas de Harris. Este cambio consistı́a en eliminar la función que usaba el algoritmo de Harris para calcular las puntuaciones de los pı́xeles, exponiendo que sólo es necesario usar los autovalores para comprobar si el pı́xel es una esquina o no.. (a) Harris. (b) Shi-Tomasi. Figura 4.3: Representación en un espacio λ1 − λ2 de los algoritmos de Harris y Shi-Tomasi. La puntuación para el detector de esquinas de Harris se calculaba de la siguiente forma.
(21) 4.1. Tipos de detectores. 21. (siendo R la puntuación): R = det M − k(traceM )2 Siendo “det M = λ1 λ2 “ y “traceM = λ1 + λ2 “ se obtiene: R = λ1 λ2 − k(λ1 + λ2 )2 En cambio, Shi-Tomasi propusieron la siguiente forma de calcular el valor puntuación: R = min(λ1 , λ2 ) Si el valor es mayor que un umbral, se considera una esquina. Si lo representamos en un espacio λ1 − λ2 tal y como se hizo en el detector de esquinas de Harris, se obtiene una imagen semejante a que se presenta en la figura 4.3b. A partir de esta figura, se puede ver que sólo cuando λ1 y λ2 están por encima de un valor mı́nimo, λmin , es considerado como esquina (región en verde). Las regiones naranjas, en las que uno de los dos valores λ, ya sea λ1 o λ2 , está por debajo del umbral, se considera que se trata de un borde. La región gris, que se corresponde con que ambos λ están por debajo del valor mı́nimo, se identifica con zonas “planas“ o sin cambios. Wang-Brady El detector de Wang-Brady considera la imagen como una superficie, y busca lugares donde hay una gran curvatura a lo largo de un borde. En otras palabras, el algoritmo busca lugares donde los bordes cambian de dirección rápidamente. La puntuación de la esquina, C, viene dada por:. C=. δ2I δt2. !2 − c|∇I|2 ,. donde t es el vector unitario perpendicular al gradiente, y c determina la tolerancia a los bordes del detector. Los autores también indicaron que se requiere de un suavizado previo de la imagen para reducir el ruido (se sugiere que sea gaussiano). SUSAN En vez de usar derivadas de imágenes para calcular esquinas, Smith y Brady crearon una técnica genérica de bajo nivel de procesamiento de imagenes llamada SUSAN (Smallest Univalue Segment Assimilating Nucleus). Aparte de ser un detector de esquinas, ha sido usado para detección de bordes y reducción de ruido. Las esquinas son detectadas situando una máscara circular de radio fijo a cada pı́xel en la imagen. El pı́xel central, llamado núcleo, es comparado con cada pı́xel bajo la máscara para comprobar si tienen un valor de intensidad similar o diferente. Pı́xeles con casi la misma luminosidad que el núcleo son agrupados y el área resultante es llamado USAN (Univalue Segment Assimilating Nucleus). Las esquinas se ubican en localizaciones donde el número de pı́xeles en el área USAN alcanza un mı́nimo local y por debajo de un valor umbral especı́fico T. Para.
(22) 22. Estado del arte detectar esquinas, la función de comparación C(r, r0 ) entre cada pı́xel de la máscara y el núcleo de la máscara, viene dada por: ( C(r, r0 ) =. 1, Si |I(r) − I(r0)| ≤ T , 0, resto. y el tamaño de la región USAN es n(r0 ) =. X. C(r, r0 ). r∈c(r0 ). donde r0 y r son las coordenadas del núcleo de la máscara y las coordenadas del pı́xel a comparar, respectivamente. El rendimiento del detector de esquinas SUSAN depende principalmente en la función de comparación C(r, r0 ), la cual no es inmune a ciertos factores de modificación de la imagen (por ejemplo, fuertes cambios de luminancia y ruido). El detector SUSAN, sin embargo, posee ciertas ventajas tales como: - No usa derivadas, por lo que no es necesaria reducción de ruido o computaciones costosas. - Una alta repetibilidad a la hora de detectar caracterı́sticas. - Invariante a cambios de traslación y rotación. Desafortunadamente, no es invariable a escalados y otras transformaciones, y un umbral global fijo no es adecuado para situaciones generales. El detector de esquinas necesita un umbral adaptativo y la forma de la máscara deberı́a de modificarse dependiendo de las imágenes usadas. FAST FAST (Features from Accelerated Segment Test) es un detector de esquinas desarrollado originalmente por Rosten y Drummondn. En este esquema de detección, los puntos candidatos se detectan aplicando una prueba de segmento a cada pı́xel de la imagen considerando un cı́rculo de 16 pı́xeles alrededor del pı́xel candidato como base de computación. Si un conjunto de n pı́xeles en el cı́rculo de Bresenham con radio r son todos más luminosos que la intensidad del pı́xel candidato (denotado como Ip ) más un umbral con valor t, Ip + t, o todos más oscuros que la intensidad del pı́xel candidato menos el valor del umbral Ip − t, entonces p se clasifica como esquina. Una prueba de alta velocidad puede usarse para excluir un gran número de puntos que no sean esquinas; esta prueba examina sólo los pı́xeles 1,5,9 y 13. Una esquina puede existir solamente si tres de estos pı́xeles son más luminosos que Ip + t o más oscuros que Ip − t y el resto de pı́xeles son entonces examinados para una conclusión final. La figura 4.4 ilustra el proceso, donde los cuadrados remarcados son los pı́xeles usados para la detección de esquinas. El pı́xel p es el centro de una esquina candidata. EL arco se indica por la lı́nea discontinua que pasa por los 12 pı́xeles contiguos que son más luminosos.
(23) 4.1. Tipos de detectores. 23. Figura 4.4: Detección de caracterı́sticas de un área de una imagen usando el detectos FAST [31] que p y el umbral. Los mejores resultados se obtienen con un cı́rculo de radio r = 3 y n = 9. Aunque la comprobación de alta velocidad consigue un alto rendimiento, sufre algunas limitaciones y debilidades, mencionadas en [31]. Una mejora para tratar estas limitaciones se consigue usando un acercamiento mediante aprendizaje automático. C(x, y) = max(. X j∈Sbright. |Ip→j − Ip | − t,. X. |Ip − Ip→j | − t). j∈Sdark. Ip→j denota los pı́xeles que se encuentran dentro del cı́rculo de Bresenham, De esta forna, el tiempo de procesamiento sigue siendo corto por que el segundo test se ejecuta solamente sobre una de fracción de los puntos originales, que son los que han pasado el primer test. Hessian El detector de regiones Hessiano [42,43] está basado en una matriz 2 x 2 de derivadas de segundo orden de la intensidad de la imagen I(x, y), llamada matriz hessiana. Esta matriz puede ser usada para analizar estructuras locales de la imagen y es expresada de la siguiente forma: Ixx (x, y, σ) Ixy (x, y, σ) H(x, y, σ) = Ixy (x, y, σ) Iyy (x, y, σ).
(24) 24. Estado del arte donde Ixx , Ixy e Iyy son derivadas de segundo orden calculadas usando una función gaussiana de desviación estándar σ. Para detectar caracterı́sticas de interés, busca un subconjunto de puntos donde las respuestas de las derivadas son altas en dos direcciones ortogonales. Es decir, el detector busca puntos donde el determinante de la matrix hessiana tiene máximos locales. 2 det(H) = Ixx Iyy − Ixy. Al elegir puntos que maximizan el determinante de la matriz hessiana, esta medida penaliza más aquellas estructuras alargadas que tienen segundas derivadas pequeñas en una sola dirección. Se aplica el algoritmo de supresión no maximal usando una ventana de tamaño 3 x 3 sobre la imagen completa, manteniendo sólo los pı́xeles cuyo valor es más grande que los valores de todos los 8 pı́xeles vecinos en la ventana. Entonces, el detector devuelve todas las localizaciones restantes cuyo valor está por encima de un umbral predefinido t. Las respuestas resultantes del detector se concentran principalmente en las esquinas y en las zonas muy texturizadas de la imagen. Mientras la matriz hessiana se usa para describir la estructuras local en la vecindad alrededor del punto, su determinante se usa para detectar las estructuras de la imagen que exhiben cambios de señal en dos direcciones. Comparado con otros operadores como el laplaciano, el determinante hessiano responde sólo si el patrón local de la imagent contiene variaciones significantes a lo largo de cualquiera de dos direcciones ortogonales [44]. Sin embargo, al usar derivadas de segundo orden en el detector, éste es sensible al ruido. Además, los máximos locales suelen encontrarse a menudo cerca de contornos o bordes rectos, donde los cambios de señal ocurren en sólo una dirección, y por tanto son menos estables ya que la localización puede verse afectada por ruido o pequeños cambios en patrones cercanos.. 4.2.. Algoritmos correspondencia de caracterı́sticas. En la correspondencia de puntos de interés, se comparan los descriptores de las imágenes entre ellos para identificar caracterı́sticas similares. Para dos imágenes se puede conseguir un conjunto de pares (Xi , Yi ) ↔ (Xi0 , Yi0 ), donde (Xi , Yi ) es una caracterı́stica de la primera imagen y (Xi0 , Yi0 ) su correspondencia en la otra. Fuerza bruta La correspondencia por fuerza bruta es un algoritmo simple. Toma cada descriptor de la primera imagen y lo corresponde con todas las caracterı́sticas de la segunda imagen usando cálculos por distancia y seleccionando el punto más cercano. La desventaja es el tiempo de ejecución aumenta de forma exponencial con respecto al aumento del conjunto de datos. FLAAN.
(25) 4.2. Algoritmos correspondencia de caracterı́sticas. 25. FLAAN es una librerı́a que contiene una colección de algoritmos optimizados para búsquedas de puntos más cercanos en grandes conjuntos de datos. El rendimiento es mejor y más rápido en grandes conjuntos de datos frente al algoritmo de fuerza bruta.
(26)
(27) Capı́tulo 5. Código El programa ha sido realizado completamente en Python, usando principalmente las librerı́as de OpenCV (https://opencv.org), Pandas (https://pandas.pydata.org) y Matplotlib (https://matplotlib.org). Las siguientes secciones se adentran en profundidad en el funcionamiento del código y se exponen sus limitaciones.. 5.1.. Estructura del código. El programa está dividido en cuatro módulos en función a la finalidad de cada uno: AlgorithmT ester.py, T ransf ormer.py, f eatureDetector.py y M atcher.py. A continuación se van a explicar. 5.1.1.. AlgorithmTester.py. Es el módulo principal en él se declaran los argumentos de los algoritmos a utilizar. También se inicializan las variables imagen de entrada y los parámetros usados para transformar las imágenes. getF eatures(algorithm, parameters) Pasando como argumentos de entrada el algoritmo y sus parámetros, calcula las caracterı́sticas de todas las imágenes, tanto la original como las transformadas. saveImageF eatures(algorithm, parameters) Guarda las imágenes en una carpeta dibujando los puntos obtenidos con el método anterior. calculateErrorR() Calcula el error de repetibilidad (ε) usando el método precisionError(f eatures, matches) del módulo M atcher.py..
(28) 28. Código calculateErrorP () Calcula el error de precisión de cada imagen transformada con respecto a la original llamando a la función errorM atch(match) del módulo M atcher.py. writer(transf ormation, name, algorithm, xArr, avgArr, pArr) Atendiendo al tipo de transformación, el nombre, el algoritmo y los errores obtenidos pasados como argumento, crea un csv y lo guarda en local. plotter(csvname) A partir del csv, dibuja una gráfica y la guarda con formato PNG en local.. 5.1.2.. Transformer.py. Es el segundo módulo que se utiliza en el programa. Están definidas todas las funciones necesarias para realizar las transformaciones de la imagen de entrada, que serán usadas para realizar el análisis de rendimiento. Asimismo tiene métodos para representar y guardar las caracterı́sticas obtenidas y graficar los errores del análisis. Las principales funciones de este módulo son las siguientes: saveImage(src img, f eatures, windowN ame) Representa las caracterı́sticas pasadas en formar de array en una imagen y lo guarda en una ruta por defecto con el nombre proporcionado. scale(img, scale, name) Escala la imagen de entrada atendiendo al argumento scale. El valor mı́nimo de dicho argumento es 0. Devuelve la imagen escalada al finalizar la función. compress(img, quality, name) Comprime la imagen de entrada. El parámetro quality se corresponde con el porcentaje de compresión usado, por lo que el valor oscila entre 0 y 100. Cuanto mayor es el valor, más artefactos saldrán en la imagen resultante. f lip(img, k, name) Devuelve una imagen simétrica verticalmente (k = 1), horizontalmente (k = 0) o ambas (k = −1). gaussianBlur(img, k, name) Añade una transformación de desenfoque gaussiano a la imagen original. rotate(img, deg, name) Devuelve la imagen rotada respecto a los grados pasados como argumento..
(29) 5.1. Estructura del código. 29. addN oise(img, sigma, name) Añade ruido gaussiano a la imagen. deScaleF eatures(f eatures, scale) Método para calcular la posición homográfica de los puntos de la imagen escalada con respecto a la imagen original. deF lipF eatures(f eatures, k, height, width) Método para calcular la posición homográfica de los puntos de la imagen simétrica con respecto a la imagen original. deRotateF eatures(f eatures, img, deg) Método para calcular la posición homográfica de los puntos de la imagen rotada con respecto a la imagen original.. 5.1.3.. featureDetector.py. En este tercer módulo se almacenan los métodos que contienen los algoritmos de detección de caracterı́sticas. El algoritmo de Moravec se ha programado desde cero, mientras que para los otros dos se han usado funciones propias de OpenCV. moravec(img, threshold) Método que devuelve un vector de puntos calculados siguiendo el algoritmo de detección de Moravec. Se precisa de un argumento umbral para dicho cálculo. cornerHarris(img, thresh, k) Función para calcular los puntos de interés de una imagen mediante el algoritmo detector de Harris. Los argumentos necesarios para esta función son el umbral mı́nimo y una constante k. ShiT omasi(img, maxF eatures, minDistance, k) Método que utiliza el algoritmo de Shi-Tomasi para devolver una lista de caracterı́sticas. Los parámetros de entrada son el número máximo de puntos, la distancia mı́nima entre ellos, y una constante k.. 5.1.4.. Matcher.py. En este módulo se encuentran las funciones que realizan cálculos de errores y computa las correspondencias entre caracterı́sticas de las imágenes. distance(match) Función que calcula la distancia entre dos puntos dada una correspondencia de dos caracterı́sticas..
(30) 30. Código matchF eatures(f eatures1, f eatures2) Método que dados dos vectores de puntos, se comparan las distancias de cada elemento del primer vector con todos los del segundo y se seleccionan el elemento con la menor distancia. ref ineM atches(matchesArr) Se refina el vector obtenido mediante la función anterior y se eliminan correspondencias que contengan puntos repetidos. errorM atch(match) Calcula el error dado una correspondencia de dos puntos. El error se calcula contando los pı́xeles de la unión e intersección de dos circunferencias con centro en los respectivos puntos . precisionError(f eatures, matches) Calcula el error de precisión relacionando el número de caracterı́sticas de la imagen original con los obtenidos en las imágenes transformadas.. 5.2.. Funcionamiento. El funcionamiento del programa se puede resumir a grandes rasgos en los siguientes pasos: 1. Inicialización de los parámetros de transformación usados. 2. Comprobar si existen las carpetas de salida de imágenes y CSVs. En caso de no existir, se crean. 3. Inicializar las variables string de la imagen de entrada y el algoritmo o lista de algoritmos a usar por unas constantes por defecto en caso de estar vacı́as: ’img/lena.jpg’ y ’moravec, CornerHarris, Shi-Tomasi’, respectivamente. 4. Se lee cadena de la imagen y se comprueba si existe. En caso negativo, devuelve un error y se finaliza la ejecución del programa. 5. Se realizan las transformaciones configuradas a la imagen original y se almacenan como elementos en un vector por cada transformación. 6. Se comprueba si el argumento de entrada que contiene los algoritmos a usar engloba la palabra ’Moravec’. En caso negativo, se pasa al punto 16.. 7. Ejecutar la función getF eatures() para obtener los puntos de interés de la imagen original y todas las transformaciones usando el algoritmo de Moravec..
(31) 5.3. Limitaciones. 31. 8. Calcular los puntos homográficos con respecto a la imagen original en las transformaciones de rotación, escalado y simetrı́a. 9. Guardar las imágenes con las caracterı́sticas representadas como puntos en la ruta ’output/<imagen>/images/moravec’. 10. Computar las correspondencias mediante el uso del algoritmo de fuerza bruta. 11. Calcular los errores de repetibilidad de cada correspondencia usando circunferencias con radios 5, 10, 15 y 20. 12. Realizar la media de error por cada transformación. 13. Calcular el error de precisión. 14. Escribir un CSV en la ruta ’output/<imagen>/errors/csv’ que contenga los errores de repetibilidad y precisión usando ’;’ como separador. 15. Utilizando los CSVs guardados, se representan gráficos de error con el módulo M atplotlib y se almacenan en la ruta ’output/<imagen>/errors/plots’. 16. Se comprueba si el argumento de entrada que contiene los algoritmos a usar engloba la palabra ’CornerHarris’. En caso afirmativo, se ejecutan los pasos 7. a 15. modificando el algoritmo de obtención de caracterı́sticas y la ruta de guardado de imágenes. En caso negativo, se pasa al punto siguiente. 17. Se comprueba si el argumento de entrada que contiene los algoritmos a usar engloba la palabra ’Shi-Tomasi’. En caso afirmativo, se ejecutan los pasos 7. a 15. modificando el algoritmo de obtención de caracterı́sticas y la ruta de guardado de imágenes. En caso negativo, se finaliza la ejecución del programa.. 5.3.. Limitaciones. Una de las principales limitaciones de este código es el tiempo de ejecución del programa. Debido a que los algoritmos de Moravec y Harris no tienen un número máximo de puntos a descubrir, se pueden dar casos en los que el algoritmo devuelve más del 90 % de los pı́xeles como caracterı́sticas. Esto a su vez deriva en que el tiempo para cálculo de correspondencias se eleva exponencialmente. La solución a este problema serı́a realizar una modificación de los algoritmos, ordenando los puntos en un vector atendiendo al valor dado por el algoritmo, y tomando solamente los primeros n elementos de dicha lista. Otra limitación es el algoritmo de correspondencias usado (Fuerza bruta). Según aumenta el número de caracterı́sticas a correlar, más aumenta el tiempo de cálculo. Se podrı́a mejorar este apartado usando un algoritmo adecuado a la cantidad de puntos de interés en la imagen. Con el fin de que el análisis sea normalizado, se ha usado sólo algoritmo..
(32)
(33) Capı́tulo 6. Pruebas Las pruebas, tanto de validación como de rendimiento, se realizarán con nueve fotos que presentan distintas caracterı́sticas. Estas imágenes están en la carpeta ’img/’ del código del programa. Para obtener los valores de los argumentos usados para cada algoritmo, se ha ejecutado la obtención de caracterı́sticas para obtener el número de puntos devueltos por cada valor de los argumento de entrada. A continuación se ha hecho la media entre los resultados de todas las imágenes y se han seleccionado los rangos de parámetros que se han estimado convenientes: Moravec • Umbral: 2500-5500, con incrementos de 100. Harris • Umbral: 150,230, con incrementos de 10. • k: 0.01-0.05, con incrementos de 0.01. Shi-Tomasi • minDistancia: 1,5,10,15,20. • maxPuntos: 5,10,25,50,100.. 6.1.. Pruebas de validación. Las pruebas de validación tienen la finalidad de comprobar que el software se comporta de acuerdo a las especificaciones. Con esto en mente, se crearon algunos casos para evaluar el rendimiento del programa que son similares a como se comporta el software en circunstancias normales. Se ejecutó el programa contra las imágenes sin transformaciones (Ejemplo de algunos resultados en la Figura 6.1). Los resultados se pueden encontrar en la carpeta ’output/<imagen>/images/’ en el proyecto..
(34) 34. Pruebas. (a) Moravec. (b) Harris. (c) Shi-Tomasi. Figura 6.1: Ejemplos de los algoritmos para tres de las imágenes de prueba.. 6.2.. Pruebas de rendimiento de los algoritmos. El análisis del rendimiento de los distintos algoritmos se realiza en base en base al propuesto por Mikolajczyk et al. [32]. Se trata de un procedimiento basado en el criterio de repetitibilidad y la superposición de las regiones detectadas. El criterio de repetitibilidad puede considerarse como uno de los criterios más importantes a la hora de evaluar la estabilidad de los detectores de caracterı́sticas. Este principio mide la habilidad de un detector para extraer los mismos puntos en imágenes independientemente de las condiciones de las mismas.. ε=1−. A ∩ (HT B H) A ∪ (HT B H). Consiste en contar el número de pı́xels en la unión e intersección de ambas regiones. Una correspondencia es correcta si el área cubierto por dos regiones correspondientes es menor que el 50 % de la unión de la región, es decir, ε < 0,5. Cuanto menor sea el valor, mejor será el rendimiento del algoritmo. Debido a que no hay lı́mite máximo de puntos para los algoritmos de Moravec y Harris, se tiene en cuenta también la precisión de los mismos. Este valor se calcula dividiendo el número de correspondencias partido por el número de caracterı́sticas en la imagen original sin transformaciones. Al igual que con el error ε, un menor número indica un rendimiento superior:.
(35) 6.2. Pruebas de rendimiento de los algoritmos. 35. Figura 6.2: Áreas de unión e intersección usadas para calcular el error de repetibilidad.. P recision = 1 −. N correspondencias N caracteristicas. Para las pruebas de rendimiento, se ha ejecutado el programa contra 9 imágenes para obtener los errores de repetibilidad y precisión de las mismas. Los argumentos de entrada para cada algoritmo han sido los mismos que los configurados en las pruebas de validación. Las salidas de la ejecución del código contra cada imagen se pueden encontrar en la ruta ’output/<imagen>/errors/’. Las imágenes contra las cuales se va a analizar el criterio de repetibilidad son transformaciones de la imagen original: rotación, desenfoque gaussiano, ruido gaussiano, escalado, simetrı́a y compresión. En la Figura 6.3 se pueden ver ejemplos de estos errores representados en forma de gráfica obtenidos mediante la ejecución del código. Se han seleccionado seis gráficas de cada algoritmo, tres de error de repetibilidad y sus respectivas precisiones, contra la imagen ’bird.jpg’ y la transformación de compresión. Los argumentos para cada algoritmo de estas gráficas de ejemplo se han elegido aleatoriamente entre el conjunto de todas las salidas. Asimismo, se reproduce en la tabla 6.1 uno de los archivos CSV resultantes de la ejecución y que usa el programa para representar las gráficas, tal y como se menciona en el capı́tulo de Código. Esta tabla se corresponde con el error de compresión y precisión de la imagen ’bird.jpg’ usando el algoritmo de Shi-Thomasi con los argumentos de entrada minDistancia = 5 y maxP untos = 25. Error Comp. Bird.jpg – Shi-Tomasi 5-25 Comp( %) r5 r10 r15 r20 0 0.000000 0.000000 0.000000 0.000000 5 0.017692 0.009945 0.006907 0.005290 10 0.000000 0.000000 0.000000 0.000000 15 0.019231 0.010810 0.007508 0.005750 ... ... ... ... ... 90 0.464990 0.332567 0.259604 0.211942 95 0.552819 0.431215 0.344667 0.284795 100 0.817314 0.672277 0.569399 0.486097. p 0.000000 0.000000 0.000000 0.080000 ... 0.400000 0.480000 0.520000. Cuadro 6.1: Tabla con el error de compresión de la imagen ’bird.jpg’ representando los distintos errores para cada radio y la precisión.
(36) 36. Pruebas. Figura 6.3: Ejemplos de gráficas de errores de repetibilidad y precisión: (a) Moravec; (b) Harris; (c) Shi-Tomasi..
(37) Capı́tulo 7. Conclusiones 7.1.. Evaluación del algoritmo. Para facilitar el análisis de los resultados obtenidos, mediante el uso del programa editor de gráficos rasterizados Adobe Photoshop CC 2015, se han agrupado las gráficas por imagen transformada y algoritmo. Con esto se ha conseguido reducir el número de archivos de 19920 a solamente 624 y simplifica el estudio de los resultados. El análisis de los resultados se podrı́a dividir en el estudio de los parámetros usados para cada detector y en las diferencias entre algoritmos para cada transformación. El comportamiento de los algoritmos en base a los parámetros de entrada se podrı́a resumir en: Moravec: Un valor de umbral más pequeño, equivale a más puntos de interés detectados y un menor error ε, pero implica mayor tiempo de computación. Harris: El parámetro umbral se comporta de la misma forma que en el caso del detector de Moravec. Con respecto al segundo parámetro, k, este mejora el funcionamiento al aumentar. Se recomienda mantenerlo en el rango 0,04 − 0,06. Shi-Tomasi: A mayor valor de maxCaracteristicas, mejor rendimiento. Resultado aceptable en comparación con los otros algoritmos. El parámetro de minDistancia no presenta notables diferencias, pero su desempeño es ligeramente mejor con valores ≤ 5. Por otro lado, se analiza el rendimiento de los algoritmos frente a las transformaciones. De forma general, se corrobora con estas pruebas las limitaciones de los detectores de escala única al enfrentarse a cambios escalares. Todos actúan de manera deficiente en los casos en que el factor de escala es menor que 1, mientras que el único detector que tiene un comportamiento aceptable al aumentar la imagen es Shi-Tomasi (Fig. 7.1). Al visualizar las gráficas de los desenfoques se pueden ver tres comportamientos diferentes: Moravec: Cuanto mayor desenfoque gaussiano, menos caracterı́sticas detecta, e incluso a valores muy bajos no detecta ningún punto..
(38) 38. Conclusiones. (a). (b). (c). Figura 7.1: Gráficas de error de escala: (a) Moravec; (b) Harris; (c) Shi-Tomasi. Harris: A más desenfoque, más puntos detecta. El error sigue siendo bajo, pero el aumento exponencial del número de caracterı́sticas lo hace ineficaz. Shi-Tomasi: El comportamiento es lineal con respecto al aumento del desenfoque (Fig. 7.2).. (a). (b). Figura 7.2: Caracterı́sticas detectadas por Shi-Tomasi (a) Original; (b) Con fuerte desenfoque gaussiano. En el caso de la transformación de compresión de imagen con pérdida, con la consecuente aparición de artefactos, el algoritmo con peor estabilidad de tasa de error de repetibilidad es el detector de Harris. Sorprendentemente, el rendimiento del algoritmo de Moravec está al nivel del detector de Shi-Tomasi para esta casuı́stica (Fig. 7.3). A continuación se comparan los resultados de las transformaciones simétricas de las imágenes. Los puntos de interés detectados por los tres algoritmos son más o menos invariantes, pero el que más destaca es el detector de Harris. El resto, debido a que no tienen precisión a nivel de pı́xel, presentan errores mı́nimos. Por otro lado, pese a que los detectores estudiados son invariantes a la rotación sobre el papel, estos presentan cierto grado de error. El más notable, es el aumento de detección de caracterı́sticas sobre un borde para el algoritmo de Moravec atendiendo a la inclinación (Fig..
(39) 7.1. Evaluación del algoritmo. 39. (a). (b). (c). Figura 7.3: Gráficas de error de compresión con pérdida: (a) Moravec; (b) Harris; (c) Shi-Tomasi.. 7.4). En contra a Moravec, la actuación de los detectores Harris y Shi-Tomasi es bastante aceptable, mantenı́endose regularmente por debajo de ε = 0,5.. (a). (b). Figura 7.4: Caracterı́sticas detectadas por Moravec con umbral = 2700: (a) 10o ; (b) 15o. Finalmente, se analizan las gráficas de los errores obtenidos de imágenes transformadas con ruido gaussiano. Tal y como se menciona en la descripción del algoritmo de Moravec, al presentar una ventana binaria, el comportamiento frente al ruido es ineficaz debido al alto número de ’granos’ que detecta como puntos de interés. En cambio, el rendimiento de los otros dos detectores, es bastante aceptable. Después de analizar todos los detectores, se puede confirmar que el algoritmo de Shi-Tomasi es el más polivalente, actúa de forma aceptable en la mayor parte de las casuı́sticas. Es seguido por el detector de Harris, que aunque se queda corto en ciertos entornos, sigue siendo muy versátil..
(40) 40. Conclusiones. 7.2.. Aspectos sociales, ambientales y éticos. La detección y descripción de las caracterı́sticas de la imagen juegan un papel vital en varios dominios de aplicaciones, como el procesamiento de imágenes, la visión artificial, el reconocimiento de patrones y el aprendizaje automático. En particular, la visión artificial, el arte de procesar imágenes digitales, se ha convertido en una tecnologı́a clave en varios campos y se utiliza como parte central en un gran número de aplicaciones de visión industrial [33]. Otro ejemplo serı́an los sistemas autónomos de estacionamiento inteligente de vehı́culos, control de crucero adaptativo, detección de agotamiento del conductor, detección de obstáculos o señales de tráfico [34] [35] y sistemas de asistencia al conductor [36]. Por ello, el análisis del rendimiento de los algoritmos en distintos puede enfocarse a aplicarse a dichas aplicaciones y mejorar el nivel de vida. En lo relativo a impacto ambiental, no se ha apreciado nada reseñable de incluir en el trabajo.. 7.3.. Trabajo futuro. Aparte de corregir las limitaciones mencionadas previamente, sin contar con la realización de más pruebas con nuevas imágenes y algoritmos, hay distintas posibilidades para el futuro desarrollo del código propuesto. Uno de los puntos de mejora más significativos es la disminución del tiempo de ejecución del código. Se podrı́an considerar dos opciones: Una de las formas en las que esto se puede conseguir fácilmente serı́a la modificación del programa para hacerlo multihilo. Al ejecutar de manera concurrente varios procedimientos a la vez, se conseguirı́a reducir la duración sin esfuerzo. La otra solución serı́a cambiar el algoritmo de correspondencia de caracterı́sticas usado (Fuerza bruta) por otro más rápido. Otra mejoras podrı́a ser la unificación por algoritmo e imagen de todas las gráficas resultantes de la ejecución. Esto disminuye en gran medida el número de archivos a manejar y se consumirı́a menos espacio en el disco duro al almacenar las imágenes. Otra funcionalidad que se podrı́a incluir serı́a permitir el paso de los parámetros de imagen y algoritmo a usar mediante argumento a la hora de ejecutar el programa. Este cambio posibilitarı́a la integración de este código dentro de otro programa..
(41) Bibliografı́a [1] T. Yap, X. Jiang, and A.C. Kot. Two-dimensional polar harmonic transforms for invariant image representation. IEEE Trans. Pattern Anal. Mach. Intell., 32(7):1259–1270, 2010. [2] Y. Wang, J.and Li, Y. Zhang, C. Wang, H. Xie, G. Chen, and X. Gao. Bag-of-features basedmedical image retrieval via multiple assignment and visual words weighting. IEEE Trans. Med. Imaging, 30(11):1996–2011, 2011. [3] R. Rahmani, S. Goldman, H. Zhang, S. Cholleti, and J. Fritts. Localized content-based image retrieval. IEEE Trans. Pattern Anal. Mach. Intell., 30(11):1902–1912, 2008. [4] S. Liu and X. Bai. Discriminative features for image classification and retrieval. Pattern Recogn. Lett., 33(6):744–751, 2012. [5] J. Stöttinger, A. Hanbury, N. Sebe, and T. Gevers. Sparse color interest points for image retrieval and object categorization. IEEE Trans. Image Process., 21(5):2681–2691, 2012. [6] A. Andreopoulos and J. Tsotsos. 50 years of object recognition: directions forward. Comput. Vis. Image Underst., 117(8):827–891, 2013. [7] P. Dollár, C. Wojek, B. Schiele, and P. Perona. Pedestrian detection: an evaluation of the state of the art. IEEE Trans. Pattern Anal. Mach. Intell., 34(4):743–761, 2012. [8] M. Felsberg, F. Larsson, J. Wiklund, N. Wadströmer, and J. Ahlberg. Online learning of correspondences between images. IEEE Trans. Pattern Anal. Mach. Intell., 35(1):118–129, 2013. [9] O. Miksik and K. Mikolajczyk. Evaluation of local detectors and descriptors for fast feature matching. In: International Conference on Pattern Recognition(ICPR 2012), Tsukuba, Japan:pp. 2681–2684., 11–15 Nov 2012. [10] B. Kim, H. Yoo, and K. Sohn. Exact order based feature descriptor for illumination robust image matching. Pattern Recogn., 46(12):3268–3278, 2013. [11] P. Moreels and P. Perona. Evaluation of features detectors and descriptors based on 3d objects. Int. J. Comput. Vis., 73(3):263–284, 2007. [12] G. Takacs, V. Chandrasekhar, S. Tsai, D. Chen, R. Grzeszczuk, and B. Girod. Rotationinvariant fast features for large-scale recognition and real-time tracking. Sign. Process. Image Commun., 28(4):334–344, 2013..
(42) 42. BIBLIOGRAFÍA. [13] S. Tang, M. Andriluka, and B. Schiele. Detection and tracking of occluded people. Int. J. Comput. Vis, 110(1):58–69, 2014. [14] J.M. Rincón, D. Makris, C. Uruňuela, and J.C. Nebel. Tracking human position and lower body parts using kalman and particle filters constrained by human biomechanics. IEEE Trans. Syst. Man Cybern., Part B 41(1):26–37, 2011. [15] S. Lazebnik, C. Schmid, and J. Ponce. A sparse texture representation using local affine regions. IEEE Trans. Pattern Anal. Mach. Intell., 27(8):1265–1278, 2005. [16] L. Liu and P. Fieguth. Texture classification from random features. IEEE Trans. Pattern Anal. Mach. Intell., 34(3):574–586, 2012. [17] A. Murillo, J. Guerrero, and C. Sagues. Surf features for efficient robot localization with omnidirectional images. In: International Conference on Robotics and Automation, Rome, Italy:pp. 3901–3907, 10–14 Apr, 2007. [18] C. Valgren and A.J. Lilienthal. Sift, surf & seasons: appearance-based long-term localization in outdoor environments. Rob. Auton. Syst., 58(2):149–156, 2010. [19] F.M. Campos, L. Correia, and J.M.F. Calado. Robot visual localization through local feature fusion: an evaluation of multiple classifiers combination approaches. J. Intell. Rob. Syst., 77(2):377–390, 2015. [20] N. Farajzadeh, K. Faez, and G. Pan. Study on the performance of moments as invariant descriptors for practical face recognition systems. IET Comput. Vis., 4(4):272–285, 2010. [21] A. Mian, M. Bennamoun, and R. Owens. Keypoint detection and local feature matching for textured 3d face recognition. Int. J. Comput. Vis., 79(1):1–12, 2008. [22] A.K. Jain, A.A. Ross, and K. Nandakumar. Introduction to Biometrics. 1st edn. Springer, 2011. [23] T. Burghardt, D. Damen, W. Mayol-Cuevas, and M. Mirmehdi. Correspondence, matching and recognition. Int. J. Comput. Vis., 113(3):161–162, 2015. [24] A. Oliva and A. Torralba. Modeling the shape of the scene: a holistic representation of the spatial envelope. Int. J. Comput. Vis., 42(3):145–175, 2001. [25] S. Bianco, D. Mazzini, D. Pau, and R. Schettini. Local detectors and compact descriptors for visual search: a quantitative comparison. Digital Signal Process., 44:1–13, 2015. [26] H. Jégou, F. Perronnin, M. Douze, J. Sánchez, P. Pérez, and C. Schmid. Aggregating local descriptors into a compact codes. IEEE Trans. Pattern Anal. Mach. Intell., 34(9):1704–1716, 2012. [27] K. Tuytelaars, T. y Mikolajczyk. Local invariant feature detectors: a survey. Found. Trends Comput. Graph. Vis., 3(3):177–280, 2007..
(43) BIBLIOGRAFÍA. 43. [28] T. Lindeberg. Image matching using generalized scale-space interest points. J. Math. Imaging Vis., 52(1):3–36, 2015. [29] H. Moravec. Obstacle avoidance and navigation in the real world by a seeing robot rover. Tech Report CMU-RI-TR-3 Carnegie-Mellon University, Robotics Institute, 1980. [30] Chris Harris and Mike Stephens. A combined corner and edge detector. In In Proc. of Fourth Alvey Vision Conference, pages 147–151, 1988. [31] E. Rosten and T. Drummond. Machine learning for high speed corner detection. In: 9th European Conference on Computer Vision (ECCV’06), Graz, Austria:pp. 430–443., 7–13 May 2006. [32] K. Mikolajczyk, T. Tuytelaars, C. Schmid, A. Zisserman, J. Matas, F. Schaffalitzky, T. Kadir, and L. Gool. A comparison of affine region detectors. Int. J. Comput.Vis., 65(1/2):43–72, 2005. [33] R. Klette. Concise Computer Vision: An introduction into Theory and Algorithms. Springer, USA, 2014. [34] C. Raxle. Automatic vehicle detection using local features-a statistical approach. IEEE Trans. Intell. Transp. Syst., 9(1):83–96, 2008. [35] A. Mukhtar and X. Likun. Vehicle detection techniques for collision avoidance systems: A review. IEEE Trans. Intell. Transp. Syst., 16(5):2318–2338, 2015. [36] D. Geronimo, A. Lopez, A. Sappa, and T. Graf. Survey of pedestrian detection for advanced driver assistance systems. IEEE Trans. Pattern Anal. Mach. Intell., 32(7):1239–1258, 2010..
(44)
(45) Capı́tulo 8. Anexo I. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29. Listing 8.1: AlgorithmTester.py # -* - coding : cp1252 -* import cv2 as cv import numpy as np import math import time import os import ntpath import pandas as pd import matplotlib . pyplot as plt import threading import Queue from featureDetector import * from Transformer import * from Matcher import * # # Global parameters global features global features_Rot global features_Scaled global features_Comp global features_Flip global features_GBlur global features_GNoise global features_Rotated_R global features_Scaled_R global features_Flip_R global matchesRotatedArr global matchesScaledArr global matchesCompArr global matchesFlipArr.
(46) 46 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49. 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68. Anexo I. global matchesGBlurArr global matchesGNoiseArr global precisionRotatedArr global precisionScaledArr global precisionCompArr global precisionFlipArr global precisionGBlurArr global precisionGNoiseArr # # Parameters maxFeatures = 100 thresh = 180 algorithm = ’ moravec ’ imgName = ’ grass ’ imgfile = ’ img / ’+ imgName + ’. jpg ’ rotateArr = [0 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 60 , 65 , 70 , 75 , 80 , 85 , 90] scaleArr = [0.0 , 0.1 , 0.2 , 0.3 , 0.4 , 0.5 , 0.6 , 0.7 , 0.8 , 0.9 , 1.0 , 1.1 , 1.2 , 1.3 , 1.4 , 1.5 , 1.6 , 1.7 , 1.8 , 1.9 , 2.0] qualityArr = [0 , 5 , 10 , 15 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 55 , 60 , 65 , 70 , 75 , 80 , 85 , 90 , 95 , 100] flipArr = [ -1 , 0 , 1] GBlurArr = [1 , 3 , 5 , 7 , 9 , 11] GNoiseArr = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30] if not os . path . exists ( ’ output ’) : os . makedirs ( ’ output ’) if not os . path . exists ( ’ output / ’+ imgName ) : os . makedirs ( ’ output / ’+ imgName ) if not os . path . exists ( ’ output / ’+ imgName + ’/ images ’) : os . makedirs ( ’ output / ’+ imgName + ’/ images ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ images / moravec ’) : os . makedirs ( ’ output / ’+ imgName + ’/ images / moravec ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ images / cornerharris ’) : os . makedirs ( ’ output / ’+ imgName + ’/ images / cornerharris ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ images / shitomasi ’) : os . makedirs ( ’ output / ’+ imgName + ’/ images / shitomasi ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ errors ’) : os . makedirs ( ’ output / ’+ imgName + ’/ errors ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ errors / plots ’) : os . makedirs ( ’ output / ’+ imgName + ’/ errors / plots ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ errors / csv ’) : os . makedirs ( ’ output / ’+ imgName + ’/ errors / csv ’) if not os . path . exists ( ’ output / ’+ imgName + ’/ errors / csv ’) :.
(47) 47 69 os . makedirs ( ’ output / ’+ imgName + ’/ errors / csv ’) 70 def plotter ( csvname ) : 71 # # Function to load data from CSV and create / save a plot 72 # # Building title for the Avg . plot 73 filename = os . path . splitext ( ntpath . basename ( csvname ) ) [0] 74 nameArr = filename . split ( ’_ ’) 75 title = ’ Avg . ’ + " " . join ( nameArr ) 76 # # Loading data from csv to dataframe 77 df = pd . read_csv ( csvname , sep = ’; ’) 78 # # Load data to plot 79 plt . axis ([0 , float ( df . tail (1) [ ’x ’ ]) , 0 , 1]) 80 plt . plot ( df .x , df . r5 , marker = ’ ’ , color = ’ darkred ’ , linewidth =1) 81 plt . plot ( df .x , df . r10 , marker = ’ ’ , color = ’ darkblue ’ , linewidth =1) 82 plt . plot ( df .x , df . r15 , marker = ’ ’ , color = ’ darkorange ’ , linewidth =1) 83 plt . plot ( df .x , df . r20 , marker = ’ ’ , color = ’ darkgreen ’ , linewidth =1) 84 plt . legend () 85 plt . title ( title , fontdict = None , loc = ’ center ’ , pad = None ) 86 # # Saving avg . image 87 plt . savefig ( ’ output / ’+ imgName + ’/ errors / plots / Avg_ ’ + filename + ’. png ’) 88 # # Clearing data and closing the plot 89 plt . cla () 90 plt . clf () 91 plt . close () 92 # # Building title for the precision plot 93 nameArr = os . path . splitext ( ntpath . basename ( csvname ) ) [0]. split ( ’_ ’) 94 title = ’ Precision ’ + " " . join ( nameArr ) 95 plt . axis ([0 , float ( df . tail (1) [ ’x ’ ]) , 0 , 1]) 96 plt . plot ( df .x , df .p , marker = ’ ’ , color = ’ darkblue ’ , linewidth =1) 97 plt . legend () 98 plt . title ( title , fontdict = None , loc = ’ center ’ , pad = None ) 99 # # Saving precision image 100 plt . savefig ( ’ output / ’+ imgName + ’/ errors / plots / Precision_ ’ + filename + ’. png ’) 101 # # Clearing data and closing the plot 102 plt . cla () 103 plt . clf () 104 plt . close ().
(48) 48. Anexo I. 105 # plt . show () # Draw plot in a new window 106 def writer ( transformation , name , algorithm , xArr , avgArr , pArr ) : 107 # # Function to convert all Error data into a CSV 108 # # Initializing file manager 109 path = ’ output / ’+ imgName + ’/ errors / csv / Error_ ’+ name + ’_ ’+ transformation + ’_ ’+ algorithm + ’. csv ’ 110 f = open ( path , " w + " ) 111 # # Writing column names 112 f . write ( " x ; r5 ; r10 ; r15 ; r20 ; p \ n " ) 113 # # Writing error data 114 for i in range ( len ( xArr ) ) : 115 f . write ( " %f; %f; %f; %f; %f; %f \ n " % ( xArr [ i ] , avgArr [ i ][0] , avgArr [ i ][1] , avgArr [ i ][2] , avgArr [ i ][3] , pArr [ i ]) ) 116 # # Close File Manager 117 f . close () 118 # # Draw and save data in plot format 119 plotter ( path ) 120 def writeCSV ( algorithm , k ) : 121 # Function to save all errors data to csv 122 writer ( ’ Rotated ’ , filename , algorithm + ’_ ’+k , rotateArr , avg_errorRotatedArr , precisionRotatedArr ) 123 writer ( ’ Scaled ’ , filename , algorithm + ’_ ’+k , scaleArr , avg_errorScaledArr , precisionScaledArr ) 124 writer ( ’ Comp ’ , filename , algorithm + ’_ ’+k , qualityArr , avg_errorCompArr , precisionCompArr ) 125 writer ( ’ Flip ’ , filename , algorithm + ’_ ’+k , flipArr , avg_errorFlipArr , precisionFlipArr ) 126 writer ( ’ GBlur ’ , filename , algorithm + ’_ ’+k , GBlurArr , avg_errorGBlurArr , precisionGBlurArr ) 127 writer ( ’ GNoise ’ , filename , algorithm + ’_ ’+k , GNoiseArr , avg_errorGNoiseArr , precisionGNoiseArr ) 128 def getFeatures ( algorithm , parameters ) : 129 # # # # # # # # ## # # ## # # ## # # ## # # # # # # ## # # # ## # # ## # # ## # # ## # 130 # Get image features # 131 # # # # # # # # ## # # ## # # ## # # ## # # # # # # ## # # # ## # # ## # # ## # # ## # 132 global features 133 global features_Rot 134 global features_Scaled 135 global features_Comp 136 global features_Flip 137 global features_GBlur 138 global features_GNoise 139 features = [] 140 features_Rot = [].
(49) 49 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172. features_Scaled = [] features_Comp = [] features_Flip = [] features_GBlur = [] features_GNoise = [] print ( " Calculating features . " ) if ( algorithm . lower () == ’ moravec ’) : features = moravec ( img , parameters [0]) for i in range ( len ( imgRotatedArr ) ) : features_Rot . append ( moravec ( imgRotatedArr [ i ] , parameters [0]) ) for i in range ( len ( imgScaledArr ) ) : features_Scaled . append ( moravec ( imgScaledArr [ i ] , parameters [0]) ) for i in range ( len ( imgCompArr ) ) : features_Comp . append ( moravec ( imgCompArr [ i ] , parameters [0]) ) for i in range ( len ( imgFlipArr ) ) : features_Flip . append ( moravec ( imgFlipArr [ i ] , parameters [0]) ) for i in range ( len ( imgGBlurArr ) ) : features_GBlur . append ( moravec ( imgGBlurArr [ i ] , parameters [0]) ) for i in range ( len ( imgGNoiseArr ) ) : features_GNoise . append ( moravec ( imgGNoiseArr [ i ] , parameters [0]) ) elif ( algorithm . lower () == ’ cornerharris ’) : features = cornerHarris ( img , parameters [0] , parameters [1]) for i in range ( len ( imgRotatedArr ) ) : features_Rot . append ( cornerHarris ( imgRotatedArr [ i ] , parameters [0] , parameters [1]) ) for i in range ( len ( imgScaledArr ) ) : features_Scaled . append ( cornerHarris ( imgScaledArr [ i ] , parameters [0] , parameters [1]) ) for i in range ( len ( imgCompArr ) ) : features_Comp . append ( cornerHarris ( imgCompArr [ i ] , parameters [0] , parameters [1]) ) for i in range ( len ( imgFlipArr ) ) : features_Flip . append ( cornerHarris ( imgFlipArr [ i ] , parameters [0] , parameters [1]) ) for i in range ( len ( imgGBlurArr ) ) : features_GBlur . append ( cornerHarris ( imgGBlurArr [ i ] , parameters [0] , parameters [1]) ).
(50) 50 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206. Anexo I for i in range ( len ( imgGNoiseArr ) ) : features_GNoise . append ( cornerHarris ( imgGNoiseArr [ i ] , parameters [0] , parameters [1]) ) elif ( algorithm . lower () == ’ shitomasi ’) : features = ShiTomasi ( img , parameters [0] , parameters [1] , parameters [2]) for i in range ( len ( imgRotatedArr ) ) : features_Rot . append ( ShiTomasi ( imgRotatedArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) for i in range ( len ( imgScaledArr ) ) : features_Scaled . append ( ShiTomasi ( imgScaledArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) for i in range ( len ( imgCompArr ) ) : features_Comp . append ( ShiTomasi ( imgCompArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) for i in range ( len ( imgFlipArr ) ) : features_Flip . append ( ShiTomasi ( imgFlipArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) for i in range ( len ( imgGBlurArr ) ) : features_GBlur . append ( ShiTomasi ( imgGBlurArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) for i in range ( len ( imgGNoiseArr ) ) : features_GNoise . append ( ShiTomasi ( imgGNoiseArr [ i ] , parameters [0] , parameters [1] , parameters [2]) ) # # # # # # # # ## # # ## # # ## # # ## # # # # # # ## # # # ## # # ## # # ## # # ## # # Get homographic features respecting # # the original image # # # # # # # # # ## # # ## # # ## # # ## # # # # # # ## # # # ## # # ## # # ## # # ## # global features_Rotated_R global features_Scaled_R global features_Flip_R features_Rotated_R = [] features_Scaled_R = [] features_Flip_R = [] # # Rotation for i in range ( len ( features_Rot ) ) : features_Rotated_R . append ( deRotateFeatures ( features_Rot [ i ] , img , rotateArr [ i ]) ) # # Scalation for i in range ( len ( features_Scaled ) ) : features_Scaled_R . append ( deScaleFeatures ( features_Scaled [ i ] , scaleArr [ i ]) ) # # Axis Symmetry for i in range ( len ( features_Flip ) ) :.
Documento similar
Además de aparecer en forma de volumen, las Memorias conocieron una primera difusión, a los tres meses de la muerte del autor, en las páginas de La Presse en forma de folletín,
Abstract: This paper reviews the dialogue and controversies between the paratexts of a corpus of collections of short novels –and romances– publi- shed from 1624 to 1637:
Después de una descripción muy rápida de la optimización así como los problemas en los sistemas de fabricación, se presenta la integración de dos herramientas existentes
por unidad de tiempo (throughput) en estado estacionario de las transiciones.. de una red de Petri
Por lo tanto, en base a su perfil de eficacia y seguridad, ofatumumab debe considerarse una alternativa de tratamiento para pacientes con EMRR o EMSP con enfermedad activa
The part I assessment is coordinated involving all MSCs and led by the RMS who prepares a draft assessment report, sends the request for information (RFI) with considerations,
Ciaurriz quien, durante su primer arlo de estancia en Loyola 40 , catalogó sus fondos siguiendo la división previa a la que nos hemos referido; y si esta labor fue de
Las manifestaciones musicales y su organización institucional a lo largo de los siglos XVI al XVIII son aspectos poco conocidos de la cultura alicantina. Analizar el alcance y