SIFT usando OpenCV en Python

Manav Narula 15 febrero 2024
  1. Algoritmo SIFT para extracción de características
  2. Use la clase SIFT para implementar SIFT usando OpenCV en Python
  3. Haga coincidir dos imágenes implementando el algoritmo SIFT usando OpenCV en Python
  4. Conclusión
SIFT usando OpenCV en Python

La extracción de características es un proceso integral en el procesamiento de imágenes y el aprendizaje automático. Se refiere a convertir datos sin procesar en información mediante la extracción de valiosos fragmentos de información.

En el procesamiento de imágenes encontramos puntos clave válidos y sus descriptores.

En Python, usamos la biblioteca OpenCV para procesar y operar imágenes. Podemos aplicar diferentes técnicas y algoritmos predefinidos utilizando esta biblioteca.

Este tutorial demostrará cómo implementar el algoritmo SIFT usando OpenCV y usarlo para la coincidencia de funciones en Python. También aprenderemos a hacer coincidir dos imágenes usando el algoritmo SIFT usando OpenCV en Python.

Algoritmo SIFT para extracción de características

SIFT (Scale Invariant Feature Transform) es una técnica de extracción de características compleja y útil. Supera el problema de otros algoritmos que pueden ser variantes de rotación o variantes de escala, lo que significa que la información extraída puede variar si la imagen se gira o se escala a un tamaño diferente.

El algoritmo SIFT evita todo esto al extraer puntos clave válidos y sus descriptores. Es invariante a escala y rotación.

Ya hemos discutido la extracción de características. Analicemos ahora los pasos involucrados en el algoritmo SIFT para la extracción de características.

Hay cinco etapas en total.

Detección de extremos de espacio a escala

La primera etapa se llama Scale-space Extrema Detection.

Como se discutió, necesitamos características que estén presentes en todas las escalas. Para escalas más grandes, requerimos ventanas más grandes.

Esta etapa implica el uso de un parámetro de escala diferente y el cálculo de la diferencia de gaussianas, es decir, la diferencia de desenfoque gaussiano con valores de parámetros de escala variables. Seleccionará una coordenada usando un valor de escala dado y verificará si existe con valores de escala más altos y más bajos.

Localización de puntos clave

Pasemos ahora a la etapa dos, que es la localización de puntos clave. Esta etapa filtrará los puntos clave seleccionados.

Utilizará la expansión de escala de la serie Taylor para obtener puntos clave más refinados y encontrar sus intensidades. Si la intensidad es inferior al umbral especificado, se rechaza.

Asignación de orientación

La siguiente etapa se llama Asignación de Orientación. Como se discutió, los puntos clave son invariantes a la rotación, y esta etapa asegura lo mismo.

Tomará las regiones circundantes de un punto clave para calcular gradientes y sus direcciones. Se crean treinta y seis contenedores y se trazan en un histograma para representar los 360 grados, y los picos superiores al 80 % se consideran nuevos puntos clave y se utilizan para determinar la orientación del punto clave seleccionado.

Descriptor de punto clave

La cuarta etapa tiene como objetivo crear un Keypoint Descriptor tomando un bloque de 16x16 vecino al keypoint y dividiéndolo en 16 bloques de 4x4. Se construye un histograma de orientación para cada bloque que contiene 8 contenedores.

Todos estos valores se representan como un vector descriptor de punto clave.

Coincidencia de puntos clave

La etapa final implica la coincidencia de puntos clave. Coincide con dos puntos clave al encontrar a sus vecinos.

Esto se utiliza para eliminar coincidencias falsas.

Ahora hemos discutido el algoritmo SIFT en detalle. Veamos cómo implementar esto usando la biblioteca OpenCV de Python.

Use la clase SIFT para implementar SIFT usando OpenCV en Python

El objeto constructor SIFT_create() se puede utilizar para crear un objeto de la clase SIFT que puede detectar los puntos clave de una imagen.

Podemos especificar diferentes parámetros, aunque cada parámetro tiene algún valor por defecto. Los parámetros son: nfeatures, nOctaveLayers, contrastThreshold, edgeThreshold, sigma y descriptorType.

El parámetro nfeatures puede especificar el número de mejores características para seleccionar del resultado. Las capas en cada octava se pueden especificar usando el parámetro nOctaveLayers, que tiene un valor predeterminado de 3.

Los valores contrastThreshold y edgeThreshold filtran las características débiles y similares a los bordes. El sigma de Gaussian se especifica utilizando el parámetro sigma, que se puede reducir para imágenes en las que se hace clic con una lente blanda.

El parámetro final especifica el tipo de descriptores que pueden ser CV_32F o CV_8U.

Veamos cómo usar este método.

import numpy as np
import cv2 as cv

i = cv.imread("obj.png")
g = cv.cvtColor(i, cv.COLOR_BGR2GRAY)

sift_ob = cv.SIFT_create()
kp = sift_ob.detect(g, None)
img = cv.drawKeypoints(g, kp, i)

cv.imshow("Output", img)
cv.waitKey(0)
cv.destroyAllWindows()

Producción:

Detectar y dibujar puntos clave usando SIFT en OpenCV Python

Tratemos de entender el ejemplo anterior.

Leemos la imagen usando la función imread(). Luego, convertimos esta imagen a escala de grises usando el método cvtColor que puede cambiar el espacio de color de cualquier imagen.

El algoritmo funciona bien con imágenes en escala de grises.

Creamos un objeto usando la función SIFT_create() con los valores predeterminados. Usamos la función detect() con el objeto creado para identificar los puntos en la imagen dada; devuelve una tupla que almacena el resultado.

Dibujamos los puntos clave sobre la imagen para una mejor representación visual usando la función drawKeypoints(). Pasamos la tupla y la imagen en esta función.

La imagen final se muestra usando la función imshow().

La función waitKey() impedía que la ventana de salida se cerrara automáticamente, esperando a que el usuario pulsara alguna tecla. Cerramos la ventana usando la función destroyAllWindows().

SIFT existía anteriormente en la biblioteca OpenCV Contrib y se agregó a OpenCV cuando expiró su patente en 2020. Ya no está disponible en OpenCV versión 3.4.2.16.

Analicemos ahora cómo hacer coincidir dos imágenes implementando el algoritmo SIFT usando OpenCV en Python.

Haga coincidir dos imágenes implementando el algoritmo SIFT usando OpenCV en Python

Como se discutió anteriormente, podemos detectar varios puntos clave y descriptores usando el algoritmo SIFT. Para esto, podemos usar un comparador de fuerza bruta.

Un comparador de fuerza bruta tomará un punto clave y su descriptor a la vez e intentará hacerlo coincidir con un conjunto de características de otra imagen, devolviendo la coincidencia más cercana.

Entonces, crearemos un objeto de comparación de fuerza bruta usando el constructor BFMatcher(). Este objeto acepta dos parámetros.

El primer parámetro es el parámetro normType, que es la distancia utilizada. Para cadenas basadas, deberíamos usar NORM_HAMMING, pero para nuestro caso (SIFT), podemos usar NORM_L1 o NORM_l2.

El segundo parámetro es crossCheck, que, si se establece en True, solo devolverá las coincidencias correspondientes en cualquiera de los conjuntos. Después de crear el objeto BFMatcher, podemos usar la función match() para pasar los dos conjuntos de descriptores para hacer coincidir.

Después de esto, podemos usar la función drawMatches() para dibujar las respectivas coincidencias en las dos imágenes. Las imágenes se colocan una al lado de la otra y los puntos clave coincidentes se unen mediante una línea.

Cada línea tiene un color único para identificar la característica. Veamos un ejemplo de esto.

Haremos coincidir las características de las siguientes dos imágenes del Qutub Minar.

Imagen 1:

Imagen a combinar 1

Imagen 2:

Imagen a combinar 2

Código:

import cv2
import matplotlib.pyplot as plt

# %matplotlib inline

i1 = cv2.imread("q3.jpeg")
i2 = cv2.imread("q4.jpeg")

img1 = cv2.cvtColor(i1, cv2.COLOR_BGR2GRAY)
img2 = cv2.cvtColor(i2, cv2.COLOR_BGR2GRAY)

sift = cv2.SIFT_create()

k_1, des_1 = sift.detectAndCompute(img1, None)
k_2, des_2 = sift.detectAndCompute(img2, None)

bf = cv2.BFMatcher(cv2.NORM_L1, crossCheck=True)

matches = bf.match(des_1, des_2)
matches = sorted(matches, key=lambda x: x.distance)

img3 = cv2.drawMatches(img1, k_1, img2, k_2, matches[:50], img2, flags=2)
cv2.imshow("Output", img3)
cv2.waitKey(0)
cv2.destroyAllWindows()

Producción:

Coincidencia de características de imagen usando SIFT en Python OpenCV

En el ejemplo anterior, emparejamos las características de dos imágenes utilizando el algoritmo SIFT y el comparador de fuerza bruta.

Primero, extrajimos las características de las dos imágenes usando el algoritmo SIFT. Luego emparejamos estas características usando el objeto de emparejamiento Brute-Force.

Las coincidencias resultantes se dibujaron en ambas imágenes utilizando la función drawMatches().

Conclusión

Este tutorial demostró la implementación del algoritmo SIFT para la extracción de características usando OpenCV en Python. La teoría detrás del algoritmo SIFT se discutió en detalle y se destacaron sus ventajas sobre otras técnicas.

Se detallaron las cinco etapas de este algoritmo. Estos fueron Detección de extremos de espacio de escala, Localización de puntos clave, Asignación de orientación, Descriptores de puntos clave y Coincidencia de puntos clave.

Discutimos la implementación de esta técnica creando un objeto de la clase SIFT usando el objeto SIFT_create(). Destacamos el uso del método detect() de esta clase y dibujamos los puntos clave usando la función drawKeypoints().

También discutimos la coincidencia de dos imágenes usando el Algoritmo SIFT usando OpenCV en Python. Para ello, en primer lugar, extrajimos las características mediante el algoritmo SIFT; luego, creamos un objeto de Brute-Force matcher.

Pasamos los descriptores al atributo match() del objeto para encontrar las coincidencias. El resultado se dibujó en ambas imágenes para dar una representación visual utilizando la función drawMatches().

Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn

Artículo relacionado - Python OpenCV