本例程利用 FAST/AGAST 算法進行特征提取,並且進行目標追蹤,僅支持灰度圖。
注意:本例程會把程序運行最開始的十秒左右出現的物體作為目標特征,請在程序運行的最開始,將目標物體放在攝像頭中央識別,直至出現特征角點,證明已經識別記錄目標特征。
匹配過程中,如果畫面出現十字和矩形框,證明匹配成功。
1 # Object tracking with keypoints example. 2 # Show the camera an object and then run the script. A set of keypoints will be extracted 3 # once and then tracked in the following frames. If you want a new set of keypoints re-run 4 # the script. NOTE: see the docs for arguments to tune find_keypoints and match_keypoints. 5 import sensor, time, image 6 7 # Reset sensor 8 sensor.reset() 9 10 # Sensor settings 11 sensor.set_contrast(3) 12 sensor.set_gainceiling(16) 13 sensor.set_framesize(sensor.VGA) 14 sensor.set_windowing((320, 240)) 15 sensor.set_pixformat(sensor.GRAYSCALE) 16 17 sensor.skip_frames(time = 2000) 18 sensor.set_auto_gain(False, value=100) 19 20 def draw_keypoints(img, kpts): 21 if kpts: 22 print(kpts) 23 img.draw_keypoints(kpts) 24 img = sensor.snapshot() 25 time.sleep(1000) 26 27 kpts1 = None 28 # NOTE: uncomment to load a keypoints descriptor from file 29 #kpts1 = image.load_descriptor("/desc.orb") 30 #img = sensor.snapshot() 31 #draw_keypoints(img, kpts1) 32 33 clock = time.clock() 34 while (True): 35 clock.tick() 36 img = sensor.snapshot() 37 if (kpts1 == None): 38 # NOTE: By default find_keypoints returns multi-scale keypoints extracted from an image pyramid. 39 kpts1 = img.find_keypoints(max_keypoints=150, threshold=10, scale_factor=1.2) 40 draw_keypoints(img, kpts1) 41 else: 42 # NOTE: When extracting keypoints to match the first descriptor, we use normalized=True to extract 43 # keypoints from the first scale only, which will match one of the scales in the first descriptor. 44 kpts2 = img.find_keypoints(max_keypoints=150, threshold=10, normalized=True) 45 if (kpts2): 46 match = image.match_descriptor(kpts1, kpts2, threshold=85) 47 if (match.count()>10): 48 # If we have at least n "good matches" 49 # Draw bounding rectangle and cross. 50 img.draw_rectangle(match.rect()) 51 img.draw_cross(match.cx(), match.cy(), size=10) 52 53 print(kpts2, "matched:%d dt:%d"%(match.count(), match.theta())) 54 # NOTE: uncomment if you want to draw the keypoints 55 #img.draw_keypoints(kpts2, size=KEYPOINTS_SIZE, matched=True) 56 57 # Draw FPS 58 img.draw_string(0, 0, "FPS:%.2f"%(clock.fps()))
sensor.
reset
()
初始化相機傳感器。
sensor.
snapshot
()
使用相機拍攝一張照片,並返回 image
對象。 OpenMV有兩個圖像存儲區。用於正常MicroPython處理的經典堆棧/堆區可以將小圖像存儲在堆中。 但是,MicroPython堆只有大約100KB,這不足以存儲更大的圖像。因此,您的OpenMV Cam有一個輔助幀緩沖存儲區, 用於存儲 sensor.snapshot()
所拍攝的圖像。 圖像存儲在該存儲區域的底部。 剩下的任何內存都可供幀緩沖區堆棧使用,OpenMV Cam的固件使用它來保存用於圖像處理算法的大型臨時數據結構。
如果你需要空間來容納多個幀,你可以通過調用 sensor.alloc_extra_fb()
來“偷走”幀緩沖區空間。
sensor.
skip_frames
([n, time])
使用 n
個快照,讓相機圖像在改變相機設置后穩定下來。 n
作為普通參數傳輸, 例如: skip_frames(10)
跳過 10
幀。您應在改變相機設置后調用該函數。
或者,您可通過關鍵字參數 time
來跳過幾毫秒的幀數,例如: kip_frames(time = 2000)
,跳過2000毫秒的幀。
若 n
和 time
皆未指定,該方法跳過300毫秒的幀。
若二者皆指定,該方法會跳過 n
數量的幀,但將在 time
毫秒后超時。
sensor.
set_pixformat
(pixformat)
設置相機模塊的像素模式。
sensor.GRAYSCALE
: 8-bits per pixel.sensor.RGB565
: 16-bits per pixel.sensor.BAYER
: 8-bits per pixel bayer pattern.
-
sensor.
set_pixformat
(pixformat) -
設置相機模塊的像素模式。
sensor.GRAYSCALE
: 8-bits per pixel.sensor.RGB565
: 16-bits per pixel.sensor.BAYER
: 8-bits per pixel bayer pattern.
-
sensor.
set_framesize
(framesize) -
設置相機模塊的幀大小。
sensor.QQCIF
: 88x72sensor.QCIF
: 176x144sensor.CIF
: 352x288sensor.QQSIF
: 88x60sensor.QSIF
: 176x120sensor.SIF
: 352x240sensor.QQQQVGA
: 40x30sensor.QQQVGA
: 80x60sensor.QQVGA
: 160x120sensor.QVGA
: 320x240sensor.VGA
: 640x480sensor.HQQQVGA
: 80x40sensor.HQQVGA
: 160x80sensor.HQVGA
: 240x160sensor.B64X32
: 64x32 (for use withimage.find_displacement()
)sensor.B64X64
: 64x64 (for use withimage.find_displacement()
)sensor.B128X64
: 128x64 (for use withimage.find_displacement()
)sensor.B128X128
: 128x128 (for use withimage.find_displacement()
)sensor.LCD
: 128x160 (for use with the lcd shield)sensor.QQVGA2
: 128x160 (for use with the lcd shield)sensor.WVGA
: 720x480sensor.WVGA2
:752x480sensor.SVGA
: 800x600 (only in JPEG mode for the OV2640 sensor)sensor.SXGA
: 1280x1024 (only in JPEG mode for the OV2640 sensor)sensor.UXGA
: 1600x1200 (only in JPEG mode for the OV2640 sensor)
-
sensor.
set_windowing
(roi) -
將相機的分辨率設置為當前分辨率的子分辨率。例如:將分辨率設置為
sensor.VGA
,然后將windowing設置為(120, 140, 200, 200), 設置sensor.snapshot()
以捕捉由相機傳感器輸出的VGA分辨率的200x200中心像素。您可使用窗口來獲得定制的分辨率。另外, 當你在更大分辨率下使用窗口時,實際上是進行數字縮放。roi
是矩形區域元組 (x, y, w, h). 然而,你可以只傳遞 (w,h),而roi
將會在圖像中居中。
-
sensor.
set_gainceiling
(gainceiling) -
設置相機圖像增益上限。2, 4, 8, 16, 32, 64, 128。
-
sensor.
set_contrast
(constrast) -
設置相機圖像對比度。-3至+3
sensor.
set_auto_gain
(enable[, gain_db=-1[, gain_db_ceiling]])
enable
打開(True)或關閉(False)自動增益。默認打開。 value
強迫增益值。更多細節請參見攝像頭數據表。
如果 enable
為False,則可以使用 gain_db
設置固定增益,單位為分貝。
如果 enable
為True,您可以使用``gain_db_ceiling``設置自動增益控制算法的最大增益上限,以分貝為單位。
注解
若您想追蹤顏色,則需關閉白平衡。
image.
draw_keypoints
(keypoints[, color[, size=10[, thickness=1[, fill=False]]]])
在圖像上畫出一個特征點對象的各個點。
color
是用於灰度或RGB565圖像的RGB888元組。默認為白色。但是,您也可以傳遞灰度圖像的基礎像素值(0-255)或RGB565圖像的字節反轉RGB565值。
size
控制特征點的大小。
thickness
控制線的粗細像素。
將 fill
設置為True以填充特征點。
返回圖像對象,以便您可以使用 .
表示法調用另一個方法。
不支持壓縮圖像和bayer圖像。
mage.
find_keypoints
([roi[, threshold=20[, normalized=False[, scale_factor=1.5[, max_keypoints=100[, corner_detector=image.CORNER_AGAST]]]]]])
從ROI元組(x, y, w, h)中提取ORB鍵點。您可以使用 image.match_descriptor
函數來比較兩組關鍵點,以獲取匹配區域。若未發現關鍵點,則返回None。
roi
是感興趣區域的矩形元組(x,y,w,h)。如果未指定,ROI即整個圖像的圖像矩形。 操作范圍僅限於 roi
區域內的像素。
threshold
是控制提取的數量的數字(取值0-255)。對於默認的AGAST角點檢測器,該值應在20左右。 對於FAST角點檢測器,該值約為60-80。閾值越低,您提取的角點越多。
normalized
是布爾值。若為True,在多分辨率下關閉提取鍵點。 若您不關心處理擴展問題,且希望算法運行更快,就將之設置為True。
scale_factor
是一個必須大於1.0的浮點數。較高的比例因子運行更快,但其圖像匹配相應較差。理想值介於1.35-1.5之間。
max_keypoints
是一個鍵點對象所能容納的鍵點最大數量。若鍵點對象過大導致內存問題,請降低該值。
corner_detector
是從圖像中提取鍵點所使用的角點檢測器算法。 可為 image.CORNER_FAST
或 image.CORNER_AGAST
。FAST角點檢測器運行速度更快,但其准確度較低。
僅支持灰度圖像
image.
match_descriptor
(descritor0, descriptor1[, threshold=70[, filter_outliers=False]])
對於LBP描述符來說,這個函數返回的是一個體現兩個描述符之間區別的整數。這一距離測度尤為必要。這個距離是對相似度的一個度量。這個測度值越接近0,LBPF特征點匹配得就越好。
對於ORB描述符來說,這個函數返回的是kptmatch對象。見上。
threshold
是用來為ORB鍵點過濾不明確匹配服務的。
一個較低的 threshold
值將緊扣關鍵點匹配算法。 threshold
值位於0-100 (int)。默認值為70。
filter_outliers
是用來為ORB鍵點過濾異常值服務的。 特征點允許用戶提高 threshold
值。默認設置為False。
模板匹配和特征點檢測的比較:
-
模板匹配(find_temolate)采用的是ncc算法,只能匹配與模板圖片大小和角度基本一致的圖案。局限性相對來說比較大,視野中的目標圖案稍微比模板圖片大一些或者小一些就可能匹配不成功。
-
模板匹配適應於攝像頭與目標物體之間距離確定,不需要動態移動的情況。比如適應於流水線上特定物體的檢測,而不適應於小車追蹤一個運動的排球(因為運動的排球與攝像頭的距離是動態的,攝像頭看到的排球大小會變化,不會與模板圖片完全一樣)。
-
多角度多大小匹配可以嘗試保存多個模板,采用多模板匹配。
-
特征點檢測(find_keypoint): 如果是剛開始運行程序,例程提取最開始的圖像作為目標物體特征,kpts1保存目標物體的特征。默認會匹配目標特征的多種比例大小和角度,而不僅僅是保存目標特征時的大小角度,比模版匹配靈活,也不需要像多模板匹配一樣保存多個模板圖像。
-
特征點檢測,也可以提前保存目標特征,之前是不推薦這么做的,因為環境光線等原因的干擾,可能導致每次運行程序光線不同特征不同,匹配度會降低。但是最新版本的固件中,增加了對曝光度、白平衡、自動增益值的調節,可以人為的定義曝光值和白平衡值,相對來說會減弱光線的干擾。也可以嘗試提前保存目標特征。