使用OpenCV進(jìn)行簡(jiǎn)單的對(duì)象跟蹤

對(duì)象跟蹤是以下過程:

1、獲取一組初始對(duì)象檢測(cè)(例如邊界框坐標(biāo)的輸入集)

2、為每個(gè)初始檢測(cè)創(chuàng)建唯一ID

3、然后在視頻中的幀周圍移動(dòng)時(shí)跟蹤每個(gè)對(duì)象,保持唯一ID的分配

此外,對(duì)象跟蹤允許我們?yōu)槊總€(gè)被跟蹤對(duì)象應(yīng)用唯一ID,使我們可以計(jì)算視頻中的唯一對(duì)象。對(duì)象跟蹤對(duì)于構(gòu)建人員計(jì)數(shù)器至關(guān)重要。

理想的對(duì)象跟蹤算法將:

僅需要對(duì)象檢測(cè)階段一次(即,最初檢測(cè)到對(duì)象時(shí));將非???- 比運(yùn)行實(shí)際物體探測(cè)器本身快得多;

能夠處理被跟蹤對(duì)象“消失”或移動(dòng)到視頻幀邊界之外的情況;對(duì)強(qiáng)大的閉合能力;能夠拾取它在幀之間“丟失”的對(duì)象;

對(duì)于任何計(jì)算機(jī)視覺或圖像處理算法而言,這是一個(gè)很高的要求,我們可以使用各種技巧來幫助改進(jìn)我們的對(duì)象跟蹤器。

但在我們構(gòu)建這樣一個(gè)強(qiáng)大的方法之前,我們首先需要研究對(duì)象跟蹤的基礎(chǔ)知識(shí)。

在今天的博客文章中,您將學(xué)習(xí)如何使用OpenCV實(shí)現(xiàn)質(zhì)心跟蹤,OpenCV是一種易于理解且高效的跟蹤算法。

在此對(duì)象跟蹤系列的未來帖子中,我將開始研究更高級(jí)的基于內(nèi)核和基于關(guān)聯(lián)的跟蹤算法。要了解如何開始使用OpenCV構(gòu)建第一個(gè)對(duì)象跟蹤,請(qǐng)繼續(xù)閱讀!

使用OpenCV進(jìn)行簡(jiǎn)單的對(duì)象跟蹤

我們將使用OpenCV庫實(shí)現(xiàn)一個(gè)簡(jiǎn)單的對(duì)象跟蹤算法。該對(duì)象跟蹤算法被稱為質(zhì)心跟蹤,因?yàn)樗蕾囉冢?)現(xiàn)有對(duì)象質(zhì)心(即,質(zhì)心跟蹤器之前已經(jīng)看到的對(duì)象)和(2)視頻中后續(xù)幀之間的新對(duì)象質(zhì)心之間的歐幾里德距離。

我們將在后續(xù)部分中更深入地回顧質(zhì)心算法。從那里我們將實(shí)現(xiàn)一個(gè)Python類來包含我們的質(zhì)心跟蹤算法,然后創(chuàng)建一個(gè)Python腳本來實(shí)際運(yùn)行對(duì)象跟蹤器并將其應(yīng)用于輸入視頻。

最后,我們將運(yùn)行我們的對(duì)象跟蹤器并檢查結(jié)果,同時(shí)注意算法的正面和缺點(diǎn)。

質(zhì)心跟蹤算法

質(zhì)心跟蹤算法是一個(gè)多步驟的過程。我們將審核本節(jié)中的每個(gè)跟蹤步驟。

一、接受邊界框坐標(biāo)并計(jì)算質(zhì)心


要使用質(zhì)心跟蹤構(gòu)建簡(jiǎn)單的對(duì)象跟蹤算法,第一步是接受來自對(duì)象檢測(cè)器的邊界框坐標(biāo)并使用它們來計(jì)算質(zhì)心。

質(zhì)心跟蹤算法假設(shè)我們?cè)诿總€(gè)幀中為每個(gè)檢測(cè)到的對(duì)象傳入一組邊界框(x,y) 坐標(biāo)。

這些邊界框可以由您想要的任何類型的物體探測(cè)器(color thresholding + contour extraction, Haar cascades, HOG + Linear SVM, SSDs, Faster R-CNNs, etc.)生成,只要它們是針對(duì)每個(gè)幀計(jì)算的在該視頻里。

一旦我們有了邊界框坐標(biāo),我們就必須計(jì)算“質(zhì)心”,或者更簡(jiǎn)單地說,計(jì)算邊界框的中心(x,y) 坐標(biāo)。上面的圖1演示了接受一組邊界框坐標(biāo)并計(jì)算質(zhì)心。

由于這些是我們的算法中提供的第一組初始邊界框,因此我們將為它們分配唯一ID。

計(jì)算新邊界框與現(xiàn)有對(duì)象界框之間的歐幾里德距離


此圖像中存在三個(gè)對(duì)象,用于使用Python和OpenCV進(jìn)行簡(jiǎn)單的對(duì)象跟蹤。我們需要計(jì)算每對(duì)原始質(zhì)心(紅色)和新質(zhì)心(綠色)之間的歐幾里德距離。

對(duì)于視頻流中的每個(gè)后續(xù)幀,我們應(yīng)用計(jì)算對(duì)象質(zhì)心的步驟#1;但是,我們首先需要確定是否可以將新對(duì)象質(zhì)心(黃色)與舊對(duì)象質(zhì)心(紫色)相關(guān)聯(lián),而不是為每個(gè)檢測(cè)到的對(duì)象分配新的唯一ID(這會(huì)破壞對(duì)象跟蹤的目的)。為了完成這個(gè)過程,我們計(jì)算每對(duì)現(xiàn)有對(duì)象質(zhì)心和輸入對(duì)象質(zhì)心之間的歐幾里德距離(用綠色箭頭突出顯示)。

從圖2中可以看出,我們這次在圖像中檢測(cè)到了三個(gè)對(duì)象。兩對(duì)靠近的是兩個(gè)現(xiàn)有對(duì)象。

然后我們計(jì)算每對(duì)原始質(zhì)心(黃色)和新質(zhì)心(紫色)之間的歐幾里德距離。但是,我們?nèi)绾问褂眠@些點(diǎn)之間的歐幾里德距離來實(shí)際匹配它們并將它們聯(lián)系起來?

答案在第3步。

步驟#3:更新(x,y) 現(xiàn)有對(duì)象的坐標(biāo)


我們的簡(jiǎn)單質(zhì)心對(duì)象跟蹤方法具有最小化對(duì)象距離的關(guān)聯(lián)對(duì)象。我們?nèi)绾翁幚碜笙路降奈矬w呢?

質(zhì)心跟蹤算法的主要假設(shè)是給定對(duì)象可能在后續(xù)幀之間移動(dòng),但幀F(xiàn)t和Ft+1的質(zhì)心之間的距離將小于對(duì)象之間的所有其他距離。

因此,如果我們選擇將質(zhì)心與后續(xù)幀之間的最小距離相關(guān)聯(lián),我們就可以構(gòu)建我們的對(duì)象跟蹤器。

在圖3中,您可以看到我們的質(zhì)心跟蹤器算法如何選擇關(guān)聯(lián)質(zhì)心,以最小化它們各自的歐幾里德距離。

但左下角的孤點(diǎn)呢?它沒有任何關(guān)聯(lián) - 我們用它做什么?

步驟#4:注冊(cè)新對(duì)象


在使用Python和OpenCV示例的對(duì)象跟蹤中,我們有一個(gè)與現(xiàn)有對(duì)象不匹配的新對(duì)象,因此它被注冊(cè)為對(duì)象ID#3。

如果有比跟蹤的現(xiàn)有對(duì)象更多的輸入檢測(cè)對(duì)象,我們需要注冊(cè)新對(duì)象?!白?cè)”只是意味著我們將新對(duì)象添加到我們的跟蹤對(duì)象列表中:

1、為其分配新的對(duì)象ID

2、存儲(chǔ)該對(duì)象的邊界框坐標(biāo)的質(zhì)心

然后我們可以回到步驟#2,為視頻流中的每一幀重復(fù)步驟流程。

圖4演示了使用最小歐幾里德距離關(guān)聯(lián)現(xiàn)有對(duì)象ID然后注冊(cè)新對(duì)象的過程。

步驟#5:取消注冊(cè)舊對(duì)象

任何合理的對(duì)象跟蹤算法都需要能夠處理對(duì)象丟失,消失或離開視野的時(shí)間。

確切地說,如何處理這些情況實(shí)際上取決于要部署對(duì)象跟蹤器的位置,但是對(duì)于此實(shí)現(xiàn),我們將在舊對(duì)象無法與任何現(xiàn)有對(duì)象匹配時(shí)在N個(gè)后續(xù)幀之后取消注冊(cè)。

對(duì)象跟蹤項(xiàng)目結(jié)構(gòu)

要在終端中查看今天的項(xiàng)目結(jié)構(gòu),只需使用tree命令:

centroidtracker.py包含CentroidTracker類的。

centroidTracker類是object_tracker.py驅(qū)動(dòng)程序腳本中使用的重要組件。

其余的.prototxt和.caffemodel文件是OpenCV深度學(xué)習(xí)面部檢測(cè)器的一部分。它們是今天的人臉檢測(cè)+跟蹤方法所必需的,但您可以輕松使用其他形式的檢測(cè)(稍后會(huì)詳細(xì)介紹)。

在繼續(xù)之前,請(qǐng)確保已安裝NumPy,SciPy和imutils:

除了安裝OpenCV 3.3+之外。如果你按照我的一個(gè)OpenCV安裝教程,請(qǐng)確保替換wget命令的尾端至少獲取OpenCV 3.3(并更新CMake命令中的路徑)。您需要3.3+才能確保擁有DNN模塊。

使用OpenCV實(shí)現(xiàn)質(zhì)心跟蹤

在我們將對(duì)象跟蹤應(yīng)用于輸入視頻流之前,我們首先需要實(shí)現(xiàn)質(zhì)心跟蹤算法。在您消化此質(zhì)心跟蹤器腳本時(shí),請(qǐng)記住上面的步驟1-5并根據(jù)需要查看步驟。

正如您將看到的,將步驟轉(zhuǎn)換為代碼需要相當(dāng)多的思考,而當(dāng)我們執(zhí)行所有步驟時(shí),由于我們各種數(shù)據(jù)結(jié)構(gòu)和代碼構(gòu)造的性質(zhì),它們不是線性的。

建議:閱讀上面的步驟;閱讀質(zhì)心跟蹤器的代碼說明;最后再次閱讀上述步驟。

這個(gè)過程將帶來一切完整的循環(huán),讓你頭腦圍繞算法。

一旦你確定你理解了質(zhì)心跟蹤算法中的步驟,打開pyimagesearch模塊中的centroidtracker.py并讓我們查看代碼:

在第2-4行,我們導(dǎo)入我們所需的包和模塊 - distance,OrderedDict和numpy。

我們的CentroidTracker類在第6行定義。構(gòu)造函數(shù)接受一個(gè)參數(shù),給定對(duì)象必須丟失/消失的最大連續(xù)幀數(shù),直到我們從跟蹤器中刪除它(第7行)。

我們的構(gòu)造函數(shù)構(gòu)建了四個(gè)類變量:

1、nextObjectID:用于為每個(gè)對(duì)象分配唯一ID的計(jì)數(shù)器(第12行)。在對(duì)象離開幀并且沒有返回maxDisappeared幀的情況下,將分配新的(下一個(gè))對(duì)象ID。

2、objects :字典使用對(duì)象ID作為鍵;質(zhì)心(x,y) 坐標(biāo)作為值(第13行)。

3、disappeared:保持特定對(duì)象ID(鍵)的連續(xù)幀數(shù)(值)已被標(biāo)記為“丟失”(第14行)。

4、maxDisappeared:在我們?nèi)∠?cè)對(duì)象之前,允許將對(duì)象標(biāo)記為“丟失/消失”的連續(xù)幀數(shù)。

讓我們定義一個(gè)注冊(cè)方法,它負(fù)責(zé)向跟蹤器添加新對(duì)象:

register方法在第21行定義。它接受質(zhì)心,然后使用下一個(gè)可用的對(duì)象ID將其添加到對(duì)象字典中。

在disappeared的字典中,對(duì)象消失的次數(shù)被初始化為0(第25行)。

最后,我們遞增nextObjectID,以便在新對(duì)象進(jìn)入視圖時(shí),它將與唯一ID相關(guān)聯(lián)(第26行)。

與我們的register方法類似,我們還需要一個(gè)deregister方法:

就像我們可以向跟蹤器添加新對(duì)象一樣,我們還需要能夠從輸入幀本身中刪除丟失或消失的舊對(duì)象。

deregister方法在第28行定義。它只是分別刪除objectID在objects和disappeared的字典中(第31和32行)。

我們的質(zhì)心跟蹤器實(shí)現(xiàn)的核心在于update方法:

在第34行定義的更新方法接受邊界框矩形的列表,可能來自對(duì)象檢測(cè)器(Haar cascade, HOG + Linear SVM, SSD, Faster R-CNN等)。 rects參數(shù)的格式假定為具有以下結(jié)構(gòu)的元組:(startX,startY,endX,endY)。

如果沒有檢測(cè),我們將遍歷所有objectIDs并遞增它們消失的計(jì)數(shù)(第37-41行)。我們還將檢查是否已達(dá)到給定對(duì)象被標(biāo)記為缺失的最大連續(xù)幀數(shù)。如果是這種情況,我們需要將其從跟蹤系統(tǒng)中刪除(第46和47行)。由于沒有更新的跟蹤信息,我們繼續(xù)在51號(hào)線提前返回。

否則,我們?cè)诟路椒ㄖ械南缕邆€(gè)代碼塊上要做很多工作:

在第54行,我們將初始化一個(gè)NumPy數(shù)組來存儲(chǔ)每個(gè)rect的質(zhì)心。

然后,我們遍歷邊界框矩形(第57行)并計(jì)算質(zhì)心并將其存儲(chǔ)在inputCentroids列表中(第59-61行)。

如果我們當(dāng)前沒有跟蹤的對(duì)象,我們將注冊(cè)每個(gè)新對(duì)象:

否則,我們需要根據(jù)最小化它們之間的歐幾里德距離的質(zhì)心位置更新任何現(xiàn)有對(duì)象(x,y) 坐標(biāo):

對(duì)現(xiàn)有被跟蹤對(duì)象的更新從第72行的else開始。目標(biāo)是跟蹤對(duì)象并保持正確的object IDs - 這個(gè)過程是通過計(jì)算所有objectCentroids和inputCentroids之間的歐幾里德距離,然后關(guān)聯(lián)來完成的。最小化歐幾里德距離的object IDs。

在第72行開始的else塊內(nèi),我們將:

1、獲取objectIDs和objectCentroid值(第74和75行)。

2、計(jì)算每對(duì)現(xiàn)有對(duì)象質(zhì)心和新輸入質(zhì)心之間的距離(第81行)。距離圖D的輸出NumPy數(shù)組形狀將是((# of object centroids, # of input centroids)。

3、要執(zhí)行匹配,我們必須(1)找到每行中的最小值,以及(2)根據(jù)最小值對(duì)行索引進(jìn)行排序(第88行)。我們對(duì)列執(zhí)行非常類似的過程,找到每列中的最小值,然后根據(jù)有序行對(duì)它們進(jìn)行排序(第93行)。我們的目標(biāo)是使索引值在列表的前面具有最小的相應(yīng)距離。

下一步是使用距離來查看我們是否可以關(guān)聯(lián)object IDs:

在上面的代碼塊中,我們:

1、初始化兩個(gè)集合以確定我們已經(jīng)使用了哪些行和列索引(第98和99行)。請(qǐng)記住,集合類似于列表,但它只包含唯一值。

2、然后我們遍歷(row,col)索引元組(第103行)的組合,以便更新我們的對(duì)象質(zhì)心:

如果我們已經(jīng)使用了這個(gè)行或列索引,請(qǐng)忽略它并繼續(xù)循環(huán)(第107和108行);

否則,我們找到了一個(gè)輸入質(zhì)心:

? ??1.與現(xiàn)有質(zhì)心的歐幾里得距離最小

????2.并沒有與任何其他物體相匹配

? ? 3.在這種情況下,我們更新對(duì)象質(zhì)心(第113-115行)并確保將行和列添加到它們各自的usedRows和usedCols集合中

我們的usedRows + usedCols集中可能存在索引,我們還沒有檢查過:

因此,我們必須確定尚未檢查的質(zhì)心索引,并將它們存儲(chǔ)在124和125行的兩個(gè)新的未使用集合(unusedRows和unusedCols)中。

我們的最終檢查處理任何丟失的物品或者它們可能已經(jīng)消失的物體:

完成:

如果對(duì)象質(zhì)心的數(shù)量大于或等于輸入質(zhì)心的數(shù)量(第131行):

????我們需要通過循環(huán)未使用的行索引來驗(yàn)證這些對(duì)象中是否有任何丟失或消失(第133行)。

????在循環(huán)中,我們將:

????????1.增加字典中消失的數(shù)量(第137行)。

????????2.檢查消失的計(jì)數(shù)是否超過maxDisappeared閾值(第142行),如果是,我們將取消注冊(cè)該對(duì)象(第143行)。

否則,輸入質(zhì)心的數(shù)量大于現(xiàn)有對(duì)象質(zhì)心的數(shù)量,因此我們有新的對(duì)象來注冊(cè)和跟蹤:

我們循環(huán)遍歷unusedCols索引(第149行)并注冊(cè)每個(gè)新的質(zhì)心(第150行)。最后,我們將把可跟蹤對(duì)象集返回給調(diào)用方法(第153行)。

質(zhì)心跟蹤距離關(guān)系

我們的質(zhì)心跟蹤實(shí)現(xiàn)很長(zhǎng),不可否認(rèn),算法中最令人困惑的方面是81-93行。

如果您在跟蹤代碼正在執(zhí)行的操作時(shí)遇到問題,則應(yīng)考慮打開Python shell并執(zhí)行以下實(shí)驗(yàn):

使用python命令在終端中啟動(dòng)Python shell后,導(dǎo)入距離和numpy,如第1行和第2行所示。

然后,設(shè)置種子以獲得再現(xiàn)性(第3行)并生成2個(gè)(隨機(jī)的)現(xiàn)有的objectCentroids(第4行)和3個(gè)inputCentroids(第5行)。

從那里,計(jì)算兩對(duì)之間的歐幾里德距離(第6行)并顯示結(jié)果(第7-9行)。結(jié)果是具有兩行(現(xiàn)有對(duì)象質(zhì)心的#)和三列(新輸入質(zhì)心的#)的距離矩陣D.

就像我們之前在腳本中所做的那樣,讓我們??找到每行中的最小距離,并根據(jù)此值對(duì)索引進(jìn)行排序:

首先,我們找到每行的最小值,允許我們找出哪個(gè)現(xiàn)有對(duì)象最接近新的輸入質(zhì)心(第10行和第11行)。然后對(duì)這些值進(jìn)行排序(第12行),我們可以獲得這些行的索引(第13行和第14行)。

在這種情況下,第二行(索引1)具有最小值,然后第一行(索引0)具有下一個(gè)最小值。

對(duì)列使用類似的過程:

我們首先檢查列中的值,并找到具有最小列的值的索引(第15行和第16行)。

然后,我們使用現(xiàn)有行(第17-19行)對(duì)這些值進(jìn)行排序。

讓我們打印結(jié)果并分析它們:

最后一步是使用zip(第20行)組合它們。結(jié)果列表打印在第21行。

分析結(jié)果,我們發(fā)現(xiàn):

1、D [1,2]具有最小的歐幾里德距離,暗示第二現(xiàn)有對(duì)象將與第三輸入質(zhì)心匹配。

2、并且D [0,1]具有下一個(gè)最小的歐幾里德距離,這意味著第一個(gè)現(xiàn)有對(duì)象將與第二個(gè)輸入質(zhì)心匹配。

我想在此重申,既然您已經(jīng)查看了代碼,那么您應(yīng)該回過頭來查看上一節(jié)中算法的步驟。從那里,您將能夠?qū)⒋a與此處概述的更線性的步驟相關(guān)聯(lián)。

實(shí)現(xiàn)對(duì)象跟蹤驅(qū)動(dòng)程序腳本

現(xiàn)在我們已經(jīng)實(shí)現(xiàn)了CentroidTracker類,讓我們使用對(duì)象跟蹤驅(qū)動(dòng)程序腳本。

驅(qū)動(dòng)程序腳本是您可以使用自己的首選對(duì)象檢測(cè)器的地方,前提是它生成一組邊界框。這可能是Haar Cascade, HOG + Linear SVM, YOLO, SSD, Faster R-CNN等。對(duì)于這個(gè)示例腳本,我正在使用OpenCV的深度學(xué)習(xí)面部檢測(cè)器,但隨意制作您自己的版本的實(shí)現(xiàn)不同檢測(cè)器的腳本。

在這個(gè)腳本中,我們將:

1、使用實(shí)時(shí)VideoStream對(duì)象從網(wǎng)絡(luò)攝像頭中抓取幀

2、加載并利用OpenCV的深度學(xué)習(xí)人臉檢測(cè)器

3、實(shí)例化我們的CentroidTracker并使用它來跟蹤視頻流中的面部對(duì)象

4、并顯示我們的結(jié)果,其中包括在框架上覆蓋的邊界框和對(duì)象ID注釋

當(dāng)你準(zhǔn)備好了,從今天的“下載”打開object_tracker.py并按照:

首先,我們指定我們的進(jìn)口。最值得注意的是,我們正在使用我們剛剛審核過的CentroidTracker類。我們還將使用imutils和OpenCV的VideoStream。

我們有三個(gè)命令行參數(shù),它們都與我們的深度學(xué)習(xí)面部檢測(cè)器有關(guān):

--prototxt:Caffe“部署”原型文件的路徑。

--model:預(yù)訓(xùn)練模型模型的路徑。

--confidence:我們過濾弱檢測(cè)的概率閾值。我發(fā)現(xiàn)默認(rèn)值為0.5就足夠了。

原型文件和模型文件來自O(shè)penCV的存儲(chǔ)庫,為方便起見,我將它們包含在“下載”中。

注意:如果您在本節(jié)開頭錯(cuò)過了它,我將重復(fù)您可以使用您想要的任何探測(cè)器。例如,我們使用深度學(xué)習(xí)面部檢測(cè)器來生成邊界框。隨意嘗試其他探測(cè)器,只要確保你有能力的硬件來跟上更復(fù)雜的探測(cè)器(有些可能最好用GPU,但今天的面部探測(cè)器可以很容易地在CPU上運(yùn)行)。

接下來,讓我們執(zhí)行初始化:

在上面的塊中,我們:

實(shí)例化我們的CentroidTracker,ct(第21行)?;叵胍幌律弦还?jié)中的解釋,該對(duì)象有三種方法:(1)寄存器,(2)注銷,(3)更新。我們只會(huì)使用update方法,因?yàn)樗鼤?huì)自動(dòng)注冊(cè)和取消注冊(cè)對(duì)象。我們還將H和W(我們的幀尺寸)初始化為None(第22行)。

使用OpenCV的DNN模塊(第26行)從磁盤加載我們的序列化深度學(xué)習(xí)人臉檢測(cè)器模型。

啟動(dòng)我們的VideoStream,vs(第30行)。使用vs方便,我們將能夠在下一個(gè)while循環(huán)中從我們的相機(jī)捕獲幀。我們將讓我們的相機(jī)在2.0秒內(nèi)預(yù)熱(第31行)。

現(xiàn)在讓我們開始我們的while循環(huán)并開始跟蹤面部對(duì)象:

我們?cè)诘?4-47行上循環(huán)幀并將它們調(diào)整為固定寬度(同時(shí)保留縱橫比)。我們根據(jù)需要抓取框架尺寸(第40和41行)。

然后我們將幀傳遞通過CNN對(duì)象檢測(cè)器以獲得預(yù)測(cè)和對(duì)象位置(第46-49行)。

我們初始化一個(gè)rects列表,我們?cè)诘?0行上的邊界框矩形。

從那里,讓我們處理檢測(cè):

我們遍歷從第53行開始的檢測(cè)。如果檢測(cè)超過我們的置信度閾值,指示有效檢測(cè),我們:

計(jì)算邊界框坐標(biāo)并將它們附加到rects列表(第59和60行)

在對(duì)象周圍繪制一個(gè)邊界框(第64-66行)

最后,讓我們?cè)谖覀兊馁|(zhì)心跟蹤器對(duì)象上調(diào)用update,ct:

第70行的ct.update調(diào)用使用Python和OpenCV腳本處理簡(jiǎn)單對(duì)象跟蹤器中的繁重工作。

如果我們不關(guān)心可視化,我們將在這里完成并準(zhǔn)備好回到頂部。

但那沒什么好玩的!

在第73-79行,我們將質(zhì)心顯示為填充圓和唯一對(duì)象ID號(hào)文本。現(xiàn)在,我們將能夠可視化結(jié)果并檢查我們的CentroidTracker是否通過將正確的ID與視頻流中的對(duì)象相關(guān)聯(lián)來正確跟蹤我們的對(duì)象。

我們將在第82行顯示幀,直到按下退出鍵(“q”)(第83-87行)。如果按下退出鍵,我們只需中斷并執(zhí)行清理(第87-91行)。

質(zhì)心對(duì)象跟蹤結(jié)果

要使用此博客文章的“下載”部分查看我們的質(zhì)心跟蹤器,請(qǐng)下載源代碼和OpenCV人臉檢測(cè)器。從那里,打開一個(gè)終端并執(zhí)行以下命令:

您可以在下面看到一個(gè)被檢測(cè)和跟蹤的單個(gè)臉部(我的臉)的示例:

第二個(gè)示例包括正確檢測(cè)和跟蹤的兩個(gè)對(duì)象:

請(qǐng)注意,一旦我將書籍封面移到相機(jī)視圖之外,即使第二張臉“丟失”,我們的物體追蹤也能夠在視線進(jìn)入時(shí)再次拾起臉部。如果面部在視野外存在超過50幀,則該對(duì)象將被取消注冊(cè)。

此處的最終示例動(dòng)畫演示了跟蹤三個(gè)唯一對(duì)象:

同樣,盡管對(duì)象ID#2在某些幀之間未被成功檢測(cè)到,但我們的對(duì)象跟蹤算法能夠再次找到它并將其與其原始質(zhì)心相關(guān)聯(lián)。

限制和缺點(diǎn)

雖然我們的質(zhì)心跟蹤器在此示例中運(yùn)行良好,但此對(duì)象跟蹤算法存在兩個(gè)主要缺點(diǎn)。

首先,它要求在輸入視頻的每一幀上運(yùn)行對(duì)象檢測(cè)步驟。

對(duì)于必須在每個(gè)輸入幀上運(yùn)行檢測(cè)器的非??斓奈矬w檢測(cè)器(即,顏色閾值和Haar級(jí)聯(lián))可能不是問題。

但是如果你(1)在(2)資源受限的設(shè)備上使用計(jì)算成本更高的物體檢測(cè)器(如HOG +線性SVM或基于深度學(xué)習(xí)的檢測(cè)器),那么您的幀處理流程將會(huì)大大減慢,因?yàn)槟鷮⒒ㄙM(fèi)整個(gè)管道運(yùn)行一個(gè)非常慢的探測(cè)器。

第二個(gè)缺點(diǎn)與質(zhì)心跟蹤算法本身的基本假設(shè)有關(guān) - 質(zhì)心必須在后續(xù)幀之間靠近在一起。

這個(gè)假設(shè)通常都有,但請(qǐng)記住,我們用2D幀表示我們的3D世界 - 當(dāng)一個(gè)物體與另一個(gè)物體重疊時(shí)會(huì)發(fā)生什么?

答案是可能發(fā)生對(duì)象ID切換。

如果兩個(gè)或更多個(gè)對(duì)象彼此重疊到它們的質(zhì)心相交的點(diǎn)并且相反具有到另一個(gè)相應(yīng)對(duì)象的最小距離,則算法可以(在不知不覺中)交換對(duì)象ID。

重要的是要理解重疊/遮擋對(duì)象問題不是特定于質(zhì)心跟蹤 - 它也適用于許多其他對(duì)象跟蹤器,包括高級(jí)跟蹤器。

然而,質(zhì)心跟蹤問題更為明顯,因?yàn)槲覀儑?yán)格依賴于質(zhì)心之間的歐幾里德距離而沒有額外的度量,啟發(fā)式或?qū)W習(xí)模式。

只要您在使用質(zhì)心跟蹤時(shí)記住這些假設(shè)和限制,算法將為您精彩地工作。

總結(jié)

在今天的博客文章中,您學(xué)習(xí)了如何使用稱為質(zhì)心跟蹤的算法使用OpenCV執(zhí)行簡(jiǎn)單的對(duì)象跟蹤。

質(zhì)心跟蹤算法的工作原理是:

接受每幀中每個(gè)對(duì)象的邊界框坐標(biāo)(可能是由某個(gè)對(duì)象檢測(cè)器)。

計(jì)算輸入邊界框的質(zhì)心與我們已經(jīng)檢查過的現(xiàn)有對(duì)象的質(zhì)心之間的歐幾里德距離。

基于具有最小歐幾里德距離的新質(zhì)心,將跟蹤對(duì)象質(zhì)心更新為其新質(zhì)心位置。

如有必要,將對(duì)象標(biāo)記為“消失”或完全取消注冊(cè)。

我們的質(zhì)心跟蹤器在本示例教程中表現(xiàn)良好,但有兩個(gè)主要缺點(diǎn):

它要求我們?yōu)橐曨l的每一幀運(yùn)行一個(gè)物體探測(cè)器 - 如果你的物體探測(cè)器運(yùn)行成本很高,你就不想使用這種方法。

它不能很好地處理重疊物體,并且由于質(zhì)心之間的歐幾里德距離的性質(zhì),我們的質(zhì)心實(shí)際上可能“交換ID”,這遠(yuǎn)非理想。

盡管存在缺點(diǎn),但質(zhì)心跟蹤可以用于很多物體跟蹤應(yīng)用程序中。(1)您的環(huán)境受到一定程度的控制,您不必?fù)?dān)心可能重疊的物體。(2)您的物體探測(cè)器本身可以在實(shí)際中運(yùn)行-時(shí)間。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文主要是翻譯人數(shù)統(tǒng)計(jì)器。感謝Adrian Rosebrock分享視頻人數(shù)統(tǒng)計(jì)的技術(shù)。先上圖看效果,再做技術(shù)分享。...
    華葉6018閱讀 4,903評(píng)論 1 5
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,441評(píng)論 6 13
  • 我們通過實(shí)現(xiàn)一種稱為“質(zhì)心跟蹤”的簡(jiǎn)單對(duì)象跟蹤算法來解決問題。今天,我們將采取下一步,看看內(nèi)置于OpenCV中的八...
    華葉6018閱讀 2,978評(píng)論 0 4
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,668評(píng)論 1 32
  • 你身披著月光 雪隔著窗對(duì)望 我夢(mèng)見星空顛倒,一樣的山川 琵琶曲子掀起濫觴 腳踏著流水和閃亮的光芒 你說閉上眼,夢(mèng)就...
    時(shí)光微醺閱讀 224評(píng)論 0 1

友情鏈接更多精彩內(nèi)容