Détection des points caractéristiques
Tutoriel vidéo 16 - Détection et enregistrement des points caractéristiques : https://singtown.com/learn/50021/
Comparaison de la correspondance de modèles et de la détection des points caractéristiques :
Correspondance de modèle (find_temolate) utilise l'algorithme ncc, qui ne peut faire correspondre que des motifs qui ont fondamentalement la même taille et le même angle que l'image du modèle. Les limitations sont relativement importantes. Si le motif cible dans le champ de vision est légèrement plus grand ou plus petit que l'image modèle, la correspondance peut ne pas réussir.
La correspondance de modèles convient aux situations dans lesquelles la distance entre la caméra et l'objet cible est déterminée et où aucun mouvement dynamique n'est requis. Par exemple, il convient à la détection d'objets spécifiques sur la chaîne de montage, mais ne convient pas à la voiture pour suivre un volley-ball en mouvement (car la distance entre le volley-ball en mouvement et la caméra est dynamique, la taille du volley-ball vu par le la caméra changera et ne sera pas exactement la même que l'image du modèle).
Pour une correspondance multi-angles et multi-tailles, vous pouvez essayer d'enregistrer plusieurs modèles et d'utiliser Correspondance de modèles multiples.
Détection de point caractéristique (find_keypoint) : si vous venez de commencer à exécuter le programme, la routine extrait la première image en tant que caractéristique de l'objet cible et kpts1 enregistre la caractéristique de l'objet cible. Par défaut, il correspondra à plusieurs proportions, tailles et angles de l'entité cible, pas seulement à la taille et à l'angle lors de l'enregistrement de l'entité cible. Il est plus flexible que la correspondance de modèles et ne nécessite pas l'enregistrement de plusieurs images de modèle comme la correspondance multi-modèles.
Pour la détection des points caractéristiques, vous pouvez également enregistrer les caractéristiques cibles à l'avance. Cela n'était pas recommandé auparavant, car les interférences de la lumière ambiante et d'autres raisons peuvent provoquer des caractéristiques différentes de différentes lumières à chaque fois que vous exécutez le programme, et le degré de correspondance sera réduit. Cependant, dans la dernière version du micrologiciel, des ajustements des valeurs d'exposition, de balance des blancs et de gain automatique ont été ajoutés. Les valeurs d'exposition et les valeurs de balance des blancs peuvent être définies artificiellement, ce qui affaiblira relativement les interférences de la lumière. . Vous pouvez également essayer d'enregistrer les entités cibles à l'avance.
Détection des points caractéristiques
Cette routine est 09-feature-Detection-keypoints.py\ Cette routine utilise l'algorithme FAST/AGAST pour l'extraction de caractéristiques et le suivi de cible, et ne prend en charge que les images en niveaux de gris.
Remarque : Cette routine utilisera les objets qui apparaissent dans les dix premières secondes du programme comme caractéristiques cibles. Veuillez placer l'objet cible au centre de la caméra pour identification au tout début du programme jusqu'à ce que le coin des caractéristiques apparaisse, prouvant que. la cible a été identifiée et enregistrée.
Pendant le processus de correspondance, si des croix et des cases rectangulaires apparaissent à l'écran, cela prouve que la correspondance est réussie.
# 利用特征点检测特定物体例程。
# 向相机显示一个对象,然后运行该脚本。 一组关键点将被提取一次,然后
# 在以下帧中进行跟踪。 如果您想要一组新的关键点,请重新运行该脚本。
# 注意:请参阅文档以调整find_keypoints和match_keypoints。
import sensor, time, image
# Reset sensor
sensor.reset()
# Sensor settings
sensor.set_framesize(sensor.VGA)
sensor.set_windowing((320, 240))
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.skip_frames(time = 2000)
sensor.set_auto_gain(False)
#画出特征点
def draw_keypoints(img, kpts):
if kpts:
print(kpts)
img.draw_keypoints(kpts)
img = sensor.snapshot()
time.sleep_ms(1000)
kpts1 = None
#kpts1保存目标物体的特征,可以从文件导入特征,但是不建议这么做。
#kpts1 = image.load_descriptor("/desc.orb")
#img = sensor.snapshot()
#draw_keypoints(img, kpts1)
clock = time.clock()
while (True):
clock.tick()
img = sensor.snapshot()
if (kpts1 == None):
#如果是刚开始运行程序,提取最开始的图像作为目标物体特征,kpts1保存目标物体的特征
#默认会匹配目标特征的多种比例大小,而不仅仅是保存目标特征时的大小,比模版匹配灵活。
# 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表示识别的区域,是一个元组(x,y,w,h),默认与framsesize大小一致。
#threshold是0~255的一个阈值,用来控制特征点检测的角点数量。用默认的AGAST特征点检测,这个阈值大概是20。用FAST特征点检测,这个阈值大概是60~80。阈值越低,获得的角点越多。
#normalized是一个布尔数值,默认是False,可以匹配目标特征的多种大小(比ncc模版匹配效果灵活)。如果设置为True,关闭特征点检测的多比例结果,仅匹配目标特征的一种大小(类似于模版匹配),但是运算速度会更快一些。
#scale_factor是一个大于1.0的浮点数。这个数值越高,检测速度越快,但是匹配准确率会下降。一般在1.35~1.5左右最佳。
#max_keypoints是一个物体可提取的特征点的最大数量。如果一个物体的特征点太多导致RAM内存爆掉,减小这个数值。
#corner_detector是特征点检测采取的算法,默认是AGAST算法。FAST算法会更快但是准确率会下降。
draw_keypoints(img, kpts1)
#画出此时的目标特征
else:
#当与最开始的目标特征进行匹配时,默认设置normalized=True,只匹配目标特征的一种大小。
# 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)
#如果检测到特征物体
if (kpts2):
#匹配当前找到的特征和最初的目标特征的相似度
match = image.match_descriptor(kpts1, kpts2, threshold=85)
#image.match_descriptor(descritor0, descriptor1, threshold=70, filter_outliers=False)。本函数返回kptmatch对象。
#threshold阈值设置匹配的准确度,用来过滤掉有歧义的匹配。这个值越小,准确度越高。阈值范围0~100,默认70
#filter_outliers默认关闭。
#match.count()是kpt1和kpt2的匹配的近似特征点数目。
#如果大于10,证明两个特征相似,匹配成功。
if (match.count()>10):
# If we have at least n "good matches"
# Draw bounding rectangle and cross.
#在匹配到的目标特征中心画十字和矩形框。
img.draw_rectangle(match.rect())
img.draw_cross(match.cx(), match.cy(), size=10)
#match.theta()是匹配到的特征物体相对目标物体的旋转角度。
print(kpts2, "matched:%d dt:%d"%(match.count(), match.theta()))
#不建议draw_keypoints画出特征角点。
# NOTE: uncomment if you want to draw the keypoints
#img.draw_keypoints(kpts2, size=KEYPOINTS_SIZE, matched=True)
# Draw FPS
#打印帧率。
img.draw_string(0, 0, "FPS:%.2f"%(clock.fps()))
Effet de l'exécution du programme :