miércoles, 9 de abril de 2014

La funcion Gaussiana en visión artificial II


Como decíamos en la anterior entrada dedicada a la gaussiana, su empleo  puede servir de ayuda para encontrar características en una imagen sin tener que preocuparnos por la escala. Para ver como funciona vamos a recordar un nuevo operador ampliamente conocido en el mundo de la física, se trata del operador laplanciano:


$\Delta f =\nabla^2f$

O en dos dimensiones y en coordenadas cartesianas:

$\Delta f =\nabla^2f = \frac{\partial^2f}{\partial x^2}+\frac{\partial^2f}{\partial y^2}$ 

Cuando es aplicado sobre imágenes, la función f es $I(x,y)$ y designa la intensidad del pixel de coordenadas x, y. En OpenCV podemos fácilmente calcular el resultado del operador laplanciano si tenemos en cuenta que este puede calcularse como una convolución con un kernel determinado. El siguiente ejemplo muestra lo que hace el operador laplanciano, en este caso con un kernel de 5x5:


Como puede verse la segunda derivada ofrece una gran sensibilidad al ruido. Si lo que se desea es calcular los bordes de los objetos el uso del operador laplanciano  pude ser de utilidad, pero la excesiva sensibilidad al ruido lo hace de difícil uso. No obstante podemos emplear, antes del operador laplanciano, un filtrado gaussiano. Esta nueva convolución es conocida como LoG. A grandes rasgos el filtrado LoG tendrá el siguiente comportamiento al aplicarlo a una imagen:

- Cero a lo largo de los contornos.
- Positivo justo a un lado del contorno.
- Negativo al otro lado del contorno.
- Cero en el interior del contorno.

Cuando se eligen valores de sigma pequeños el filtro LoG es capaz de captar los bordes que se encuentran a menos escala, mientras que con valores grandes se capturan los de mayor tamaño. El siguiente ejemplo muestra un LoG con un sigma de 3.


La parte correspondiente a la cabeza y al borde de las alas se distinguen con facilidad, sin embargo otras zonas mas sutiles son menos nítidas - las antenas, por ejemplo -. Si reducimos el valor de sigma, digamos a 1, tenemos el siguiente resultado:



Ahora logramos que otras características se hagan visibles. Aplicando este método, usando con cuidados los valores del tamaño del kernel y el de sigma, podemos descubrir muchas de las características notables de una imagen. Ahora bien, el LoG es costoso en tiempo de computación, aunque existe una solución si empleamos un camino opcional calculando las diferencias de convoluciones gaussianas con dos diferentes sigmas, por ejemplo $\sigma$ y $k\sigma$. Esto es una aproximación al cálculo de LoG más rápida. Esto se hace para varios valores de sigma, en forma piramidal y disminuyendo la escala - o aumentándola si partimos de un valor de sigma pequeño -. Una vez realizadas las diferencias se buscan los máximos comparándolos con 8 los píxeles vecinos, así como los 9 píxeles de los niveles de escala posteriores y anteriores. De esta forma se consiguen los extremos locales, que potencialmente pueden ser keypoints. Una vez obtenidos estos máximos locales se puede refinar aún más nuestro conjunto de keypoints desechando los que estén por debajo de un cierto umbral. Esta descripción corresponde al método SIFT, descrito en 2004, D.Lowe, University of British Columbia, Came up with a new algorithm, Scale Invariant Feature Transform. El algoritmo esta disponible en OpenCV por lo que no necesitamos implementarlo nosotros mismos. Ahora describimos en pocas líneas como usar SIFT en openCV desde Python:
 
sift = cv2.SIFT()
keypoints, descriptor = self.sift.detectAndCompute(image,None) 

Para representar los keypoints sobre la imagen podemos recurrir a  drawKeypoints, que si le añadimos DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS como flag, nos dibujará los keypoints  con su orientación y un radio proporcional a la "fuerza" del mismo. El resultado es el siguiente:





En la siguiente entrada veremos como podemos recurrir a un algoritmo aún más eficiente que el SIFT.

No hay comentarios:

Publicar un comentario