Detección de puntos característicos
Tutorial en video 16 - Detección y almacenamiento de puntos característicos: https://singtown.com/learn/50021/
Comparación entre la coincidencia de plantillas y la detección de puntos característicos:
Coincidencia de plantillas (find_temolate) utiliza el algoritmo ncc, que solo puede coincidir con patrones que sean básicamente del mismo tamaño y ángulo que la imagen de la plantilla. Las limitaciones son relativamente grandes. Si el patrón objetivo en el campo de visión es ligeramente más grande o más pequeño que la imagen de la plantilla, es posible que la coincidencia no se logre.
La coincidencia de plantillas es adecuada para situaciones en las que la distancia entre la cámara y el objeto objetivo es fija y no se requiere movimiento dinámico. Por ejemplo, es adecuada para la detección de objetos específicos en una línea de montaje, pero no para que el vehículo siga una pelota de voleibol en movimiento (porque la distancia entre la pelota de voleibol en movimiento y la cámara es dinámica, y el tamaño de la pelota de voleibol visto por la cámara cambiará, por lo que no será exactamente igual a la imagen de la plantilla).
Para la coincidencia con múltiples ángulos y tamaños, puedes intentar guardar varias plantillas y usar Coincidencia de múltiples plantillas.
Detección de puntos característicos (find_keypoint): si acabas de comenzar a ejecutar el programa, la rutina extrae la primera imagen como característica del objeto objetivo, y kpts1 guarda la característica del objeto objetivo. De forma predeterminada, hará coincidir múltiples escalas y ángulos de la característica objetivo, en lugar de guardar solo el tamaño y el ángulo de la característica objetivo. Es más flexible que la coincidencia de plantillas y no necesita guardar varias imágenes de plantilla como la coincidencia de múltiples plantillas.
La detección de puntos característicos también puede guardar las características objetivo con antelación. Esto no se recomendaba antes porque la interferencia de la luz ambiental y otras razones podían causar características diferentes bajo distinta luz cada vez que se ejecutaba el programa, lo que reducía el grado de coincidencia. Sin embargo, en la última versión del firmware se ha agregado el ajuste de la exposición, el balance de blancos y el valor de ganancia automática. El valor de exposición y el valor de balance de blancos se pueden definir manualmente, lo que reduce relativamente la interferencia de la luz. También puedes intentar guardar las características objetivo con antelación.
Detección de puntos característicos
Esta rutina es 09-feature-Detection-keypoints.py\ Esta rutina utiliza el algoritmo FAST/AGAST para la extracción de características y el seguimiento de objetivos, y solo admite imágenes en escala de grises.
Nota: esta rutina tomará el objeto que aparece durante los primeros diez segundos del programa como la característica objetivo. Coloca el objeto objetivo en el centro de la cámara al inicio del programa hasta que aparezca la esquina de la característica, lo que demuestra que la característica objetivo ha sido identificada y registrada.
Durante el proceso de coincidencia, si aparecen una cruz y un marco rectangular en la pantalla, se demuestra que la coincidencia fue exitosa
# Rutina de detección de un objeto específico mediante puntos característicos.
# Muestra un objeto a la cámara y luego ejecuta este script. Se extraerá un
# conjunto de puntos clave una vez, y luego
# se rastreará en los siguientes fotogramas. Si quieres un nuevo conjunto de
# puntos clave, vuelve a ejecutar el script.
# Nota: consulta la documentación para ajustar find_keypoints y match_keypoints.
import csi, time, image
csi0 = csi.CSI()
# Reset sensor
csi0.reset()
# Sensor settings
csi0.framesize(csi.VGA)
csi0.window((320, 240))
csi0.pixformat(csi.GRAYSCALE)
csi0.snapshot(time = 2000)
csi0.auto_gain(False)
#Dibuja los puntos característicos
def draw_keypoints(img, kpts):
if kpts:
print(kpts)
img.draw_keypoints(kpts)
img = csi0.snapshot()
time.sleep_ms(1000)
kpts1 = None
#kpts1 guarda la característica del objeto objetivo; se puede importar la característica desde un archivo, pero no se recomienda hacerlo.
#kpts1 = image.load_descriptor("/desc.orb")
#img = csi0.snapshot()
#draw_keypoints(img, kpts1)
clock = time.clock()
while (True):
clock.tick()
img = csi0.snapshot()
if (kpts1 == None):
#si se acaba de empezar a ejecutar el programa, extrae la primera imagen como la característica del objeto objetivo; kpts1 guarda la característica del objeto objetivo
#de forma predeterminada, hará coincidir varias escalas de tamaño de la característica objetivo, no solo el tamaño al momento de guardar la característica objetivo, lo cual es más flexible que la coincidencia de plantillas.
# NOTE: By default find_keypoints returns multi-scale keypoints extracted from an image pyramid.
kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
#image.find_keypoints(roi=Auto, threshold=20, normalized=False, scale_factor=1.5, max_keypoints=100, corner_detector=CORNER_AGAST)
#roi representa la región de reconocimiento, es una tupla (x,y,w,h); por defecto coincide con el tamaño de framesize.
#threshold es un umbral de 0 a 255 que se usa para controlar la cantidad de puntos de esquina detectados. Con la detección de puntos característicos AGAST predeterminada, este umbral es aproximadamente 20. Con la detección de puntos característicos FAST, este umbral es aproximadamente 60~80. Cuanto menor sea el umbral, más puntos de esquina se obtienen.
#normalized es un valor booleano, por defecto False, que permite coincidir con varios tamaños de la característica objetivo (más flexible que la coincidencia de plantillas ncc). Si se establece en True, se desactivan los resultados de detección en múltiples escalas, y solo se coincide con un tamaño de la característica objetivo (similar a la coincidencia de plantillas), pero la velocidad de cálculo será más rápida.
#scale_factor es un número de punto flotante mayor que 1.0. Cuanto mayor sea este valor, más rápida será la detección, pero la precisión de la coincidencia disminuirá. Generalmente lo óptimo está entre 1.35 y 1.5.
#max_keypoints es la cantidad máxima de puntos característicos que se pueden extraer de un objeto. Si un objeto tiene demasiados puntos característicos y hace que la memoria RAM se desborde, reduce este valor.
#corner_detector es el algoritmo utilizado para la detección de puntos característicos; por defecto es el algoritmo AGAST. El algoritmo FAST es más rápido pero la precisión disminuirá.
draw_keypoints(img, kpts1)
#dibuja la característica objetivo en este momento
else:
#al hacer coincidir con la característica objetivo inicial, por defecto se establece normalized=True, y solo se coincide con un tamaño de la característica objetivo.
# NOTE: When extracting keypoints to match the first descriptor, we use normalized=True to extract
# keypoints from the first scale only, which will match one of the scales in the first descriptor.
kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
#si se detecta el objeto característico
if (kpts2):
#hace coincidir la similitud entre la característica encontrada actualmente y la característica objetivo original
match = image.match_descriptor(kpts1, kpts2, threshold=85)
#image.match_descriptor(descritor0, descriptor1, threshold=70, filter_outliers=False). Esta función devuelve un objeto kptmatch.
#el umbral threshold establece la precisión de la coincidencia, usado para filtrar coincidencias ambiguas. Cuanto menor sea este valor, mayor será la precisión. El rango del umbral es 0~100, por defecto 70
#filter_outliers está desactivado por defecto.
#match.count es el número aproximado de puntos característicos coincidentes entre kpt1 y kpt2.
#si es mayor que 10, se demuestra que las dos características son similares y la coincidencia fue exitosa.
if (match.count>10):
# If we have at least n "good matches"
# Draw bounding rectangle and cross.
#dibuja una cruz y un marco rectangular en el centro de la característica objetivo encontrada.
img.draw_rectangle(match.rect)
img.draw_cross((match.cx, match.cy), size=10)
#match.theta es el ángulo de rotación del objeto característico encontrado con respecto al objeto objetivo.
print(kpts2, "matched:%d dt:%d"%(match.count, match.theta))
#no se recomienda usar draw_keypoints para dibujar los puntos de esquina característicos.
# NOTE: uncomment if you want to draw the keypoints
#img.draw_keypoints(kpts2, size=KEYPOINTS_SIZE, matched=True)
# Draw FPS
#imprime la velocidad de fotogramas.
img.draw_string((0, 0), "FPS:%.2f"%(clock.fps()))
El efecto de ejecutar el programa:

