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:
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