Coincidencia de características usando fuerza bruta en OpenCV

En este artículo, haremos coincidencias de características usando Brute Force en Python usando la biblioteca OpenCV.

Requisitos previos: OpenCV

OpenCV es una biblioteca de Python que se utiliza para resolver los problemas de visión por computadora.  

OpenCV es una biblioteca de visión artificial de código abierto. Entonces, la visión por computadora es una forma de enseñar inteligencia a las máquinas y hacer que vean cosas como los humanos.

En otras palabras, OpenCV es lo que permite que la computadora vea y procese datos visuales como los humanos.

Instalación:

Para instalar la biblioteca openCV, escriba el siguiente comando en su símbolo del sistema.

pip install opencv-python

Acercarse:

  • Importe la biblioteca OpenCV.
  • Cargue las imágenes usando la función i mread() y pase la ruta o el nombre de la imagen como parámetro.
  • Cree el detector ORB para detectar las características de las imágenes.
  • Usando el detector ORB encuentre los puntos clave y descriptores para ambas imágenes.
  • Ahora después de detectar las características de las imágenes. Ahora escriba Brute Force Matcher para hacer coincidir las características de las imágenes y guárdelo en la variable denominada » brute_force «.
  • Para hacer coincidir, usamos brute_force.match() y pasamos los descriptores de la primera imagen y los descriptores de la segunda imagen como parámetro.
  • Después de encontrar las coincidencias, tenemos que ordenar esas coincidencias de acuerdo con la distancia de tarareo entre las coincidencias, menor será la distancia de tarareo y mejor será la precisión de las coincidencias.
  • Ahora, después de ordenar según la distancia del zumbido, tenemos que dibujar las coincidencias de características para eso, usamos la función drawMatches() en la que pasamos la primera imagen y los puntos clave de la primera imagen, la segunda imagen y los puntos clave de la segunda imagen y las mejores coincidencias como parámetro y lo almacenamos en la variable nombrada como » output_image «.
  • Ahora, después de dibujar las coincidencias de características, tenemos que ver las coincidencias para las que usamos la función imshow() que viene en la biblioteca cv2 y pasamos el nombre de la ventana y la imagen de salida .
  • Ahora escribe la función waitkey() y escribe destroyAllWindows() para destruir todas las ventanas.

Detector breve orientado rápido y rotado (ORB)

ORB detector significa Oriented Fast and Rotated Brief, este es un algoritmo gratuito, el beneficio de este algoritmo es que no requiere GPU, puede calcular en una CPU normal.

ORB es básicamente la combinación de dos algoritmos involucrados FAST y BRIEF, donde FAST significa Características de la prueba de segmentos acelerados, mientras que BREVE significa Características elementales independientes robustas binarias.

El detector ORB primero usa el algoritmo FAST, este algoritmo FAST encuentra los puntos clave y luego aplica la medida de la esquina de Harries para encontrar los N números principales de puntos clave entre ellos, este algoritmo selecciona rápidamente los puntos clave comparando las regiones distintivas como las variaciones de intensidad.

Este algoritmo funciona en la coincidencia de puntos clave. El punto clave son regiones distintivas en una imagen como las variaciones de intensidad.

Ahora viene el papel del algoritmo BREVE, este algoritmo toma los puntos clave y los convierte en el descriptor binario/vector de características binarias que contiene la combinación de 0 y 1 solamente. 

Los puntos clave fundados por el algoritmo FAST y los descriptores creados por el algoritmo BRIEF juntos representan el objeto. BRIEF es el método más rápido para el cálculo de descriptores de características y también proporciona una alta tasa de reconocimiento a menos que haya una gran rotación en el plano.

Comparador de fuerza bruta

Brute Force Matcher se utiliza para hacer coincidir las características de la primera imagen con otra imagen.

Toma un descriptor de la primera imagen y coincide con todos los descriptores de la segunda imagen y luego va al segundo descriptor de la primera imagen y coincide con todos los descriptores de la segunda imagen y así sucesivamente.

Ejemplo 1: Leer/Importar las imágenes desde su ruta usando la biblioteca OpenCV .

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
  # reading the images from their using imread() function
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# main function
if __name__ == '__main__':
 # giving the path of both of the images
    first_image_path = 'C:/UsersPython(ds)/1611755129039.jpg'
    second_image_path = 'C:/Users/Python(ds)/1611755720390.jpg'
 
    # reading the image from there path by calling the function
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images by calling the function
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
    cv2.imshow('Gray scaled image 1',gray_pic1)
    cv2.imshow('Gray scaled image 2',gray_pic2)
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

Ejemplo 2: Crear un detector ORB para encontrar las características en las imágenes.

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# function to detect the features by finding key points and descriptors from the image
def detector(image1,image2):
    # creating ORB detector
    detect = cv2.ORB_create()
 
    # finding key points and descriptors of both images using detectAndCompute() function
    key_point1,descrip1 = detect.detectAndCompute(image1,None)
    key_point2,descrip2 = detect.detectAndCompute(image2,None)
    return (key_point1,descrip1,key_point2,descrip2)
 
# main function
if __name__ == '__main__':
 # giving the path of both of the images
    first_image_path = 'C:/Users/Python(ds)//1611755129039.jpg'
    second_image_path = 'C:/Users/Python(ds)/1611755720390.jpg'
 
    # reading the image from there paths
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
 
    # storing the finded key points and descriptors of both of the images
    key_pt1,descrip1,key_pt2,descrip2 = detector(gray_pic1,gray_pic2)
 
    # showing the images with their key points finded by the detector
    cv2.imshow("Key points of Image 1",cv2.drawKeypoints(gray_pic1,key_pt1,None))
    cv2.imshow("Key points of Image 2",cv2.drawKeypoints(gray_pic2,key_pt2,None))
 
    # printing descriptors of both of the images
    print(f'Descriptors of Image 1 {descrip1}')
    print(f'Descriptors of Image 2 {descrip2}')
    print('------------------------------')
 
    # printing the Shape of the descriptors
    print(f'Shape of descriptor of first image {descrip1.shape}')
    print(f'Shape of descriptor of second image {descrip2.shape}')
 
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

La primera imagen de salida muestra los puntos clave dibujados de ambas imágenes. 

Los KeyPoints son el punto de interés, en palabras simples significa que cuando el humano verá la imagen en ese momento, las características que nota en esa imagen, de manera similar, cuando la máquina lee la imagen, ve algunos puntos de interés conocidos como Puntos clave .

La segunda imagen de salida muestra los descriptores y la forma de los descriptores.

Estos Descriptores son básicamente una array o contenedor de números. Estos se usan para describir las características, usando estos descriptores podemos hacer coincidir las dos imágenes diferentes.

En la segunda imagen de salida, podemos ver la forma del descriptor de la primera imagen y la forma del descriptor de la segunda imagen es (467, 32) y (500,32) respectivamente. Por lo tanto, el detector ORB (Oriented Fast and Rotated Brief) intenta encontrar 500 características en la imagen de forma predeterminada y, para cada descriptor, describirá 32 valores.

Entonces, ahora, ¿cómo usaremos estos descriptores ahora? Podemos usar un Brute Force Matcher (como se discutió anteriormente en el artículo) para unir estos descriptores y encontrar cuántas similitudes tenemos.

Ejemplo 3: Coincidencia de características utilizando Brute Force Matcher.

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# function to detect the features by finding key points
# and descriptors from the image
def detector(image1,image2):
    # creating ORB detector
    detect = cv2.ORB_create()
 
    # finding key points and descriptors of both images using
    # detectAndCompute() function
    key_point1,descrip1 = detect.detectAndCompute(image1,None)
    key_point2,descrip2 = detect.detectAndCompute(image2,None)
    return (key_point1,descrip1,key_point2,descrip2)
 
# function to find best detected features using brute force
# matcher and match them according to there humming distance
def BF_FeatureMatcher(des1,des2):
    brute_force = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
    no_of_matches = brute_force.match(des1,des2)
 
    # finding the humming distance of the matches and sorting them
    no_of_matches = sorted(no_of_matches,key=lambda x:x.distance)
    return no_of_matches
 
# function displaying the output image with the feature matching
def display_output(pic1,kpt1,pic2,kpt2,best_match):
 
    # drawing the feature matches using drawMatches() function
    output_image = cv2.drawMatches(pic1,kpt1,pic2,kpt2,best_match,None,flags=2)
    cv2.imshow('Output image',output_image)
 
# main function
if __name__ == '__main__':
    # giving the path of both of the images
    first_image_path = 'C:/Users/Python(ds)/1611755129039.jpg'
    second_image_path = 'C:/Users/Python(ds)/1611755720390.jpg'
 
    # reading the image from there paths
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
 
    # storing the finded key points and descriptors of both of the images
    key_pt1,descrip1,key_pt2,descrip2 = detector(gray_pic1,gray_pic2)
 
    # sorting the number of best matches obtained from brute force matcher
    number_of_matches = BF_FeatureMatcher(descrip1,descrip2)
    tot_feature_matches = len(number_of_matches)
 
    # printing total number of feature matches found
    print(f'Total Number of Features matches found are {tot_feature_matches}')
 
    # after drawing the feature matches displaying the output image
    display_output(gray_pic1,key_pt1,gray_pic2,key_pt2,number_of_matches)
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

Obtenemos un total de 178 coincidencias destacadas. Se dibujan un total de 178 coincidencias, pero están ordenadas según su distancia de zumbido en orden ascendente, lo que significa que la distancia de la característica 178 es mayor que la primera característica, por lo que la coincidencia de la primera característica es más precisa que la coincidencia de la característica 178.

Parece desordenado porque todas las 178 coincidencias de características están dibujadas, dibujemos las quince características principales (por el bien de la visibilidad).

Ejemplo 4: Coincidencia de características de las primeras/quince principales utilizando Brute Force Matcher.

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# function to detect the features by finding key points
# and descriptors from the image
def detector(image1,image2):
 
    # creating ORB detector
    detect = cv2.ORB_create()
 
    # finding key points and descriptors of both images
    # using detectAndCompute() function
    key_point1,descrip1 = detect.detectAndCompute(image1,None)
    key_point2,descrip2 = detect.detectAndCompute(image2,None)
    return (key_point1,descrip1,key_point2,descrip2)
 
# function to find best detected features using
# brute force matcher and match them according to there humming distance
def BF_FeatureMatcher(des1,des2):
    brute_force = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
    no_of_matches = brute_force.match(des1,des2)
 
    # finding the humming distance of the matches and sorting them
    no_of_matches = sorted(no_of_matches,key=lambda x:x.distance)
    return no_of_matches
 
# function displaying the output image with the feature matching
def display_output(pic1,kpt1,pic2,kpt2,best_match):
    # drawing first fifteen best feature matches using drawMatches() function
    output_image = cv2.drawMatches(pic1,kpt1,pic2,
                                   kpt2,best_match[:15],None,flags=2)
    cv2.imshow('Output image',output_image)
 
# main function
if __name__ == '__main__':
    # giving the path of both of the images
    first_image_path = 'C:/Users/Python(ds)/1611755129039.jpg'
    second_image_path = 'C:/Users/Python(ds)/1611755720390.jpg'
 
    # reading the image from there paths
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
 
    # storing the finded key points and descriptors of both of the images
    key_pt1,descrip1,key_pt2,descrip2 = detector(gray_pic1,gray_pic2)
 
    # sorting the number of best matches obtained from brute force matcher
    number_of_matches = BF_FeatureMatcher(descrip1,descrip2)
 
    # after drawing the feature matches displaying the output image
    display_output(gray_pic1,key_pt1,gray_pic2,key_pt2,number_of_matches)
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

La imagen de salida muestra la primera o las quince mejores coincidencias de características con Brute Force Matcher.

Del resultado anterior, podemos ver que estas coincidencias son más precisas que todas las coincidencias de características restantes.

Tomemos otro ejemplo de coincidencia de características.

Ejemplo 5: coincidencia de características usando fuerza bruta.

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# function to detect the features by finding key points and
# descriptors from the image
def detector(image1,image2):
 
    # creating ORB detector
    detect = cv2.ORB_create()
    # finding key points and descriptors of both images
    # using detectAndCompute() function
    key_point1,descrip1 = detect.detectAndCompute(image1,None)
    key_point2,descrip2 = detect.detectAndCompute(image2,None)
    return (key_point1,descrip1,key_point2,descrip2)
 
# function to find best detected features using brute
# force matcher and match them according to there humming distance
def BF_FeatureMatcher(des1,des2):
    brute_force = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
    no_of_matches = brute_force.match(des1,des2)
 
    # finding the humming distance of the matches and sorting them
    no_of_matches = sorted(no_of_matches,key=lambda x:x.distance)
    return no_of_matches
 
# function displaying the output image with the feature matching
def display_output(pic1,kpt1,pic2,kpt2,best_match):
    # drawing the feature matches using drawMatches() function
    output_image = cv2.drawMatches(pic1,kpt1,pic2,kpt2,
                                   best_match[:30],None,flags=2)
    cv2.imshow('Output image',output_image)
 
# main function
if __name__ == '__main__':
    # giving the path of both of the images
    first_image_path = 'C:/Users/Python(ds)/Titan_1.jpg'
    second_image_path = 'C:/Users/Python(ds)/Titan_nor.jpg'
 
    # reading the image from there paths
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
 
    # storing the finded key points and descriptors of both of the images
    key_pt1,descrip1,key_pt2,descrip2 = detector(gray_pic1,gray_pic2)
 
    # sorting the number of best matches obtained from brute force matcher
    number_of_matches = BF_FeatureMatcher(descrip1,descrip2)
    tot_feature_matches = len(number_of_matches)
    print(f'Total Number of Features matches found are {tot_feature_matches}')
 
    # after drawing the feature matches displaying the output image
    display_output(gray_pic1,key_pt1,gray_pic2,key_pt2,number_of_matches)
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

En el ejemplo anterior, obtenemos un total de 147 mejores coincidencias de funciones, entre ellas, estamos dibujando solo las 30 mejores coincidencias para que podamos ver las coincidencias correctamente.

Ejemplo 6: Coincidencia de características utilizando Brute Force Matcher al tomar una imagen de tren rotada.

Python

# importing openCV library
import cv2
 
# function to read the images by taking there path
def read_image(path1,path2):
    read_img1 = cv2.imread(path1)
    read_img2 = cv2.imread(path2)
    return (read_img1,read_img2)
 
# function to convert images from RGB to gray scale
def convert_to_grayscale(pic1,pic2):
    gray_img1 = cv2.cvtColor(pic1,cv2.COLOR_BGR2GRAY)
    gray_img2 = cv2.cvtColor(pic2,cv2.COLOR_BGR2GRAY)
    return (gray_img1,gray_img2)
 
# function to detect the features by finding key points
# and descriptors from the image
def detector(image1,image2):
    # creating ORB detector
    detect = cv2.ORB_create()
 
    # finding key points and descriptors of both images
    # using detectAndCompute() function
    key_point1,descrip1 = detect.detectAndCompute(image1,None)
    key_point2,descrip2 = detect.detectAndCompute(image2,None)
    return (key_point1,descrip1,key_point2,descrip2)
 
# function to find best detected features using brute
# force matcher and match them according to there humming distance
def BF_FeatureMatcher(des1,des2):
    brute_force = cv2.BFMatcher(cv2.NORM_HAMMING,crossCheck=True)
    no_of_matches = brute_force.match(des1,des2)
 
    # finding the humming distance of the matches and sorting them
    no_of_matches = sorted(no_of_matches,key=lambda x:x.distance)
    return no_of_matches
 
# function displaying the output image with the feature matching
def display_output(pic1,kpt1,pic2,kpt2,best_match):
    # drawing the feature matches using drawMatches() function
    output_image = cv2.drawMatches(pic1,kpt1,pic2,
                                   kpt2,best_match[:30],None,flags=2)
    cv2.imshow('Output image',output_image)
 
# main function
if __name__ == '__main__':
    # giving the path of both of the images
    first_image_path = 'C:/Users/Python(ds)/Titan_1.jpg'
    second_image_path = 'C:/Users/Python(ds)/Titan_rotated.jpg'
 
    # reading the image from there paths
    img1, img2 = read_image(first_image_path,second_image_path)
 
    # converting the readed images into the gray scale images
    gray_pic1, gray_pic2 = convert_to_grayscale(img1,img2)
 
    # storing the finded key points and descriptors of both of the images
    key_pt1,descrip1,key_pt2,descrip2 = detector(gray_pic1,gray_pic2)
 
    # sorting the number of best matches obtained from brute force matcher
    number_of_matches = BF_FeatureMatcher(descrip1,descrip2)
    tot_feature_matches = len(number_of_matches)
    print(f'Total Number of Features matches found are {tot_feature_matches}')
 
    # after drawing the feature matches displaying the output image
    display_output(gray_pic1,key_pt1,gray_pic2,key_pt2,number_of_matches)
    cv2.waitKey()
    cv2.destroyAllWindows()

Producción:

En este ejemplo, cuando tomamos la imagen del tren rotado, encontramos que hay poca diferencia en el número total de coincidencias de mejores características, es decir, 148.

En la primera imagen de salida, solo hemos dibujado las treinta mejores coincidencias de características.

Publicación traducida automáticamente

Artículo escrito por srishivansh5404 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *