AGAST 角點檢測器和 FAST 角點檢測器:
兩者都是計算機視覺中快速檢測圖像角點的算法,核心目的是高效找到圖像中 "有辨識度的點",但細節略有不同:
(1)FAST 角點檢測器
? 特點:速度極快,專門為實時場景設計(比如攝像頭實時跟蹤)。
? 原理:判斷一個點是否為角點時,只看它周圍 16 個像素(形成一個圓)。如果其中連續 12 個以上的像素,要么都比它亮很多,要么都比它暗很多,就判定為角點。
? 優勢:計算簡單,速度快,適合嵌入式設備(如 OpenMV 攝像頭)。
? 缺點:對噪聲較敏感(可能誤判一些不是角點的點)。
(2)AGAST 角點檢測器(
? 特點:FAST 算法的改進版,更靈活,適應性更強。
? 原理:在 FAST 基礎上優化了判斷邏輯,不需要固定檢查 16 個像素,而是根據圖像局部特征動態調整檢查的像素數量和位置。
? 優勢:在保持速度的同時,減少了誤判,對不同類型的圖像(比如明暗差異大或小的場景)適應性更好。
core_detector用來控制使用的角點檢測的算法,默認是AGAST角點檢測
normalized是布爾值。若為True,在多分辨率下關閉提取鍵點。
#normalized=True 表示 “歸一化提取”,即只從圖像的原始尺度(不進行多尺度縮放)中提取關鍵點。
#這是為了讓 kpts2 的提取方式與 kpts1 中的某一尺度保持一致,確保兩者能正確匹配(避免因縮放差異導致特征點無法對應)
image.match_descriptor(kpts1, kpts2, threshold=85)
LBP描述符,這個函數返回的是一個體現兩個描述符之間區別的整數
如果返回值越小,證明兩者越匹配
對于ORB描述符來說,這個函數返回的是一個kptmatch對象,
kptmatch.rect()返回矩形元組(匹配到的物體特征的外界矩形的框框)
import sensor
import time
import image
# Reset sensor
sensor.reset()
# Sensor settings
sensor.set_contrast(3)
sensor.set_gainceiling(16)
sensor.set_framesize(sensor.VGA)#640*480
sensor.set_windowing((320, 240))
sensor.set_pixformat(sensor.GRAYSCALE)
sensor.skip_frames(time=2000)
sensor.set_auto_gain(False, gain_db=100)
def draw_keypoints(img, kpts):
if kpts:
print(kpts) # 在控制臺打印這些特征點的具體數據
# (比如每個點的坐標是多少,長什么樣,計算機能看懂的信息)
img.draw_keypoints(kpts)# 在畫面上把這些特征點畫出來
# (會在每個特征點的位置畫個小圓圈或十字,我們肉眼就能看到了)
img = sensor.snapshot()
time.sleep_ms(1000)
kpts1 = None
#因為程序剛啟動時還沒看到任何物體,所以先設為空,等攝像頭捕捉到第一幀圖像后,再從中提取特征點存入kpts1
#不建議從文件中導入特征
#因為每次運行的時候,環境不一樣,背景不一樣,光線不一樣
clock = time.clock()
while True:
clock.tick()
img = sensor.snapshot()
if kpts1 is None:
# 判斷:是不是第一次運行?(kpts1還是空的)
# 如果是第一次,就從當前畫面中"提取物體的特征點" ? ?
kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2)
draw_keypoints(img, kpts1)
else:
kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True)
# 變量 kpts2 用來存儲當前幀圖像中提取的關鍵點,和初始幀的 kpts1 對應。
if kpts2:
match = image.match_descriptor(kpts1, kpts2, threshold=85)
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)
? ? ? ? ? ? print(kpts2, "matched:%d dt:%d" % (match.count(), match.theta()))
# Draw FPS
img.draw_string(0, 0, "FPS:%.2f" % (clock.fps()))