日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

TLD(Tracking-Learning-Detection)学习与源码理解之(三)

發(fā)布時(shí)間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TLD(Tracking-Learning-Detection)学习与源码理解之(三) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

TLDTracking-Learning-Detection)學(xué)習(xí)與源碼理解之(三)

zouxy09@qq.com

http://blog.csdn.net/zouxy09

?

?????? 下面是自己在看論文和這些大牛的分析過(guò)程中,對(duì)代碼進(jìn)行了一些理解,但是由于自己接觸圖像處理和機(jī)器視覺(jué)沒(méi)多久,另外由于自己編程能力比較弱,所以分析過(guò)程可能會(huì)有不少的錯(cuò)誤,希望各位不吝指正。而且,因?yàn)榫幊毯芏嗟胤讲欢?#xff0c;所以注釋得非常亂,還海涵。

?

從main()函數(shù)切入,分析整個(gè)TLD運(yùn)行過(guò)程如下:

(這里只是分析工作過(guò)程,全部注釋的代碼見(jiàn)博客的更新)

1、分析程序運(yùn)行的命令行參數(shù);

./run_tld -p ../parameters.yml -s ../datasets/06_car/car.mpg -b ../datasets/06_car/init.txt –r

?

2、讀入初始化參數(shù)(程序中變量)的文件parameters.yml;

?

3、通過(guò)文件或者用戶(hù)鼠標(biāo)框選的方式指定要跟蹤的目標(biāo)的Bounding Box;

?

4、用上面得到的包含要跟蹤目標(biāo)的Bounding? Box和第一幀圖像去初始化TLD系統(tǒng),

?? tld.init(last_gray, box, bb_file); 初始化包含的工作如下:

?

4.1、buildGrid(frame1, box);

檢測(cè)器采用掃描窗口的策略:掃描窗口步長(zhǎng)為寬高的 10%,尺度縮放系數(shù)為1.2;此函數(shù)構(gòu)建全部的掃描窗口grid,并計(jì)算每一個(gè)掃描窗口與輸入的目標(biāo)box的重疊度;重疊度定義為兩個(gè)box的交集與它們的并集的比;

?

4.2、為各種變量或者容器分配內(nèi)存空間;

?

4.3、getOverlappingBoxes(box, num_closest_init);

此函數(shù)根據(jù)傳入的box(目標(biāo)邊界框),在整幀圖像中的全部掃描窗口中(由上面4.1得到)尋找與該box距離最小(即最相似,重疊度最大)的num_closest_init(10)個(gè)窗口,然后把這些窗口歸入good_boxes容器。同時(shí),把重疊度小于0.2的,歸入bad_boxes容器;相當(dāng)于對(duì)全部的掃描窗口進(jìn)行篩選。并通過(guò)BBhull函數(shù)得到這些掃描窗口的最大邊界。

???

4.5、classifier.prepare(scales);

準(zhǔn)備分類(lèi)器,scales容器里是所有掃描窗口的尺度,由上面的buildGrid()函數(shù)初始化;

TLD的分類(lèi)器有三部分:方差分類(lèi)器模塊、集合分類(lèi)器模塊和最近鄰分類(lèi)器模塊;這三個(gè)分類(lèi)器是級(jí)聯(lián)的,每一個(gè)掃描窗口依次全部通過(guò)上面三個(gè)分類(lèi)器,才被認(rèn)為含有前景目標(biāo)。這里prepare這個(gè)函數(shù)主要是初始化集合分類(lèi)器模塊;

集合分類(lèi)器(隨機(jī)森林)基于n個(gè)基本分類(lèi)器(共10棵樹(shù)),每個(gè)分類(lèi)器(樹(shù))都是基于一個(gè)pixel comparisons(共13個(gè)像素比較集)的,也就是說(shuō)每棵樹(shù)有13個(gè)判斷節(jié)點(diǎn)(組成一個(gè)pixel comparisons),輸入的圖像片與每一個(gè)判斷節(jié)點(diǎn)(相應(yīng)像素點(diǎn))進(jìn)行比較,產(chǎn)生0或者1,然后將這13個(gè)0或者1連成一個(gè)13位的二進(jìn)制碼x(有2^13種可能),每一個(gè)x對(duì)應(yīng)一個(gè)后驗(yàn)概率P(y|x)= #p/(#p+#n) (也有2^13種可能),#p和#n分別是正和負(fù)圖像片的數(shù)目。那么整一個(gè)集合分類(lèi)器(共10個(gè)基本分類(lèi)器)就有10個(gè)后驗(yàn)概率了,將10個(gè)后驗(yàn)概率進(jìn)行平均,如果大于閾值(一開(kāi)始設(shè)經(jīng)驗(yàn)值0.65,后面再訓(xùn)練優(yōu)化)的話(huà),就認(rèn)為該圖像片含有前景目標(biāo);

后驗(yàn)概率P(y|x)= #p/(#p+#n)的產(chǎn)生方法:初始化時(shí),每個(gè)后驗(yàn)概率都得初始化為0;運(yùn)行時(shí)候以下面方式更新:將已知類(lèi)別標(biāo)簽的樣本(訓(xùn)練樣本)通過(guò)n個(gè)分類(lèi)器進(jìn)行分類(lèi),如果分類(lèi)結(jié)果錯(cuò)誤,那么相應(yīng)的#p和#n就會(huì)更新,這樣P(y|x)也相應(yīng)更新了。

pixel comparisons的產(chǎn)生方法:先用一個(gè)歸一化的patch去離散化像素空間,產(chǎn)生所有可能的垂直和水平的pixel comparisons,然后我們把這些pixel comparisons隨機(jī)分配給n個(gè)分類(lèi)器,每個(gè)分類(lèi)器得到完全不同的pixel comparisons(特征集合),這樣,所有分類(lèi)器的特征組統(tǒng)一起來(lái)就可以覆蓋整個(gè)patch了。

特征是相對(duì)于一種尺度的矩形框而言的,TLD中第s種尺度的第i個(gè)特征features[s][i] = Feature(x1, y1, x2, y2);是兩個(gè)隨機(jī)分配的像素點(diǎn)坐標(biāo)(就是由這兩個(gè)像素點(diǎn)比較得到0或者1的)。每一種尺度的掃描窗口都含有totalFeatures = nstructs * structSize個(gè)特征;nstructs為樹(shù)木(由一個(gè)特征組構(gòu)建,每組特征代表圖像塊的不同視圖表示)的個(gè)數(shù);structSize為每棵樹(shù)的特征個(gè)數(shù),也即每棵樹(shù)的判斷節(jié)點(diǎn)個(gè)數(shù);樹(shù)上每一個(gè)特征都作為一個(gè)決策節(jié)點(diǎn);

prepare函數(shù)的工作就是先給每一個(gè)掃描窗口初始化了對(duì)應(yīng)的pixel comparisons(兩個(gè)隨機(jī)分配的像素點(diǎn)坐標(biāo));然后初始化后驗(yàn)概率為0;

?

4.6、generatePositiveData(frame1, num_warps_init);

此函數(shù)通過(guò)對(duì)第一幀圖像的目標(biāo)框box(用戶(hù)指定的要跟蹤的目標(biāo))進(jìn)行仿射變換來(lái)合成訓(xùn)練初始分類(lèi)器的正樣本集。具體方法如下:先在距離初始的目標(biāo)框最近的掃描窗口內(nèi)選擇10個(gè)bounding box(已經(jīng)由上面的getOverlappingBoxes函數(shù)得到,存于good_boxes里面了,還記得不?),然后在每個(gè)bounding box的內(nèi)部,進(jìn)行±1%范圍的偏移,±1%范圍的尺度變化,±10%范圍的平面內(nèi)旋轉(zhuǎn),并且在每個(gè)像素上增加方差為5的高斯噪聲(確切的大小是在指定的范圍內(nèi)隨機(jī)選擇的),那么每個(gè)box都進(jìn)行20次這種幾何變換,那么10個(gè)box將產(chǎn)生200個(gè)仿射變換的bounding box,作為正樣本。具體實(shí)現(xiàn)如下:

getPattern(frame(best_box), pEx, mean, stdev);此函數(shù)將frame圖像best_box區(qū)域的圖像片歸一化為均值為0的15*15大小的patch,存于pEx(用于最近鄰分類(lèi)器的正樣本)正樣本中(最近鄰的box的Pattern),該正樣本只有一個(gè)。

generator(frame, pt, warped, bbhull.size(), rng);此函數(shù)屬于PatchGenerator類(lèi)的構(gòu)造函數(shù),用來(lái)對(duì)圖像區(qū)域進(jìn)行仿射變換,先RNG一個(gè)隨機(jī)因子,再調(diào)用()運(yùn)算符產(chǎn)生一個(gè)變換后的正樣本。

classifier.getFeatures(patch, grid[idx].sidx, fern);函數(shù)得到輸入的patch的特征fern(13位的二進(jìn)制代碼);

pX.push_back(make_pair(fern, 1));?? //positive ferns <features, labels=1>然后標(biāo)記為正樣本,存入pX(用于集合分類(lèi)器的正樣本)正樣本庫(kù);

以上的操作會(huì)循環(huán) num_warps * good_boxes.size()即20 * 10 次,這樣,pEx就有了一個(gè)正樣本,而pX有了200個(gè)正樣本了;

?

4.7、meanStdDev(frame1(best_box), mean, stdev);

統(tǒng)計(jì)best_box的均值和標(biāo)準(zhǔn)差,var = pow(stdev.val[0],2) * 0.5;作為方差分類(lèi)器的閾值。

?

4.8、generateNegativeData(frame1);

???? 由于TLD僅跟蹤一個(gè)目標(biāo),所以我們確定了目標(biāo)框了,故除目標(biāo)框外的其他圖像都是負(fù)樣本,無(wú)需仿射變換;具體實(shí)現(xiàn)如下:

???? 由于之前重疊度小于0.2的,都?xì)w入 bad_boxes了,所以數(shù)量挺多,把方差大于var*0.5f的bad_boxes都加入負(fù)樣本,同上面一樣,需要classifier.getFeatures(patch, grid[idx].sidx, fern);和nX.push_back(make_pair(fern, 0));得到對(duì)應(yīng)的fern特征和標(biāo)簽的nX負(fù)樣本(用于集合分類(lèi)器的負(fù)樣本);

??? 然后隨機(jī)在上面的bad_boxes中取bad_patches(100個(gè))個(gè)box,然后用 getPattern函數(shù)將frame圖像bad_box區(qū)域的圖像片歸一化到15*15大小的patch,存在nEx(用于最近鄰分類(lèi)器的負(fù)樣本)負(fù)樣本中。

這樣nEx和nX都有負(fù)樣本了;(box的方差通過(guò)積分圖像計(jì)算)

?

4.9、然后將nEx的一半作為訓(xùn)練集nEx,另一半作為測(cè)試集nExT;同樣,nX也拆分為訓(xùn)練集nX和測(cè)試集nXT;

?

4.10、將負(fù)樣本nX和正樣本pX合并到ferns_data[]中,用于集合分類(lèi)器的訓(xùn)練;

?

4.11、將上面得到的一個(gè)正樣本pEx和nEx合并到nn_data[]中,用于最近鄰分類(lèi)器的訓(xùn)練;

?

4.12、用上面的樣本訓(xùn)練集訓(xùn)練 集合分類(lèi)器(森林) 和 最近鄰分類(lèi)器:

? classifier.trainF(ferns_data, 2); //bootstrap = 2

對(duì)每一個(gè)樣本ferns_data[i] ,如果樣本是正樣本標(biāo)簽,先用measure_forest函數(shù)返回該樣本所有樹(shù)的所有特征值對(duì)應(yīng)的后驗(yàn)概率累加值,該累加值如果小于正樣本閾值(0.6* nstructs,這就表示平均值需要大于0.6(0.6* nstructs / nstructs),0.6是程序初始化時(shí)定的集合分類(lèi)器的閾值,為經(jīng)驗(yàn)值,后面會(huì)用測(cè)試集來(lái)評(píng)估修改,找到最優(yōu)),也就是輸入的是正樣本,卻被分類(lèi)成負(fù)樣本了,出現(xiàn)了分類(lèi)錯(cuò)誤,所以就把該樣本添加到正樣本庫(kù),同時(shí)用update函數(shù)更新后驗(yàn)概率。對(duì)于負(fù)樣本,同樣,如果出現(xiàn)負(fù)樣本分類(lèi)錯(cuò)誤,就添加到負(fù)樣本庫(kù)。

? classifier.trainNN(nn_data);

???? 對(duì)每一個(gè)樣本nn_data,如果標(biāo)簽是正樣本,通過(guò)NNConf(nn_examples[i], isin, conf, dummy);計(jì)算輸入圖像片與在線(xiàn)模型之間的相關(guān)相似度conf,如果相關(guān)相似度小于0.65 ,則認(rèn)為其不含有前景目標(biāo),也就是分類(lèi)錯(cuò)誤了;這時(shí)候就把它加到正樣本庫(kù)。然后就通過(guò)pEx.push_back(nn_examples[i]);將該樣本添加到pEx正樣本庫(kù)中;同樣,如果出現(xiàn)負(fù)樣本分類(lèi)錯(cuò)誤,就添加到負(fù)樣本庫(kù)。

?

4.13、用測(cè)試集在上面得到的 集合分類(lèi)器(森林) 和 最近鄰分類(lèi)器中分類(lèi),評(píng)價(jià)并修改得到最好的分類(lèi)器閾值。

? classifier.evaluateTh(nXT, nExT);

?? 對(duì)集合分類(lèi)器,對(duì)每一個(gè)測(cè)試集nXT,所有基本分類(lèi)器的后驗(yàn)概率的平均值如果大于thr_fern(0.6),則認(rèn)為含有前景目標(biāo),然后取最大的平均值(大于thr_fern)作為該集合分類(lèi)器的新的閾值。

?? 對(duì)最近鄰分類(lèi)器,對(duì)每一個(gè)測(cè)試集nExT,最大相關(guān)相似度如果大于nn_fern(0.65),則認(rèn)為含有前景目標(biāo),然后取最大的最大相關(guān)相似度(大于nn_fern)作為該最近鄰分類(lèi)器的新的閾值。

?

5、進(jìn)入一個(gè)循環(huán):讀入新的一幀,然后轉(zhuǎn)換為灰度圖像,然后再處理每一幀processFrame;

?

6、processFrame(last_gray, current_gray, pts1, pts2, pbox, status, tl, bb_file);逐幀讀入圖片序列,進(jìn)行算法處理。processFrame共包含四個(gè)模塊(依次處理):跟蹤模塊、檢測(cè)模塊、綜合模塊和學(xué)習(xí)模塊;

?

6.1、跟蹤模塊:track(img1, img2, points1, points2);

track函數(shù)完成前一幀img1的特征點(diǎn)points1到當(dāng)前幀img2的特征點(diǎn)points2的跟蹤預(yù)測(cè);

?

6.1.1、具體實(shí)現(xiàn)過(guò)程如下:

(1)先在lastbox中均勻采樣10*10=100個(gè)特征點(diǎn)(網(wǎng)格均勻撒點(diǎn)),存于points1:

bbPoints(points1, lastbox);

(2)利用金字塔LK光流法跟蹤這些特征點(diǎn),并預(yù)測(cè)當(dāng)前幀的特征點(diǎn)(見(jiàn)下面的解釋)、計(jì)算FB error和匹配相似度sim,然后篩選出 FB_error[i] <= median(FB_error) 和 sim_error[i] > median(sim_error) 的特征點(diǎn)(舍棄跟蹤結(jié)果不好的特征點(diǎn)),剩下的是不到50%的特征點(diǎn)

tracker.trackf2f(img1, img2, points, points2);

(3)利用剩下的這不到一半的跟蹤點(diǎn)輸入來(lái)預(yù)測(cè)bounding box在當(dāng)前幀的位置和大小 tbb:

bbPredict(points, points2, lastbox, tbb);

(4)跟蹤失敗檢測(cè):如果FB error的中值大于10個(gè)像素(經(jīng)驗(yàn)值),或者預(yù)測(cè)到的當(dāng)前box的位置移出圖像,則認(rèn)為跟蹤錯(cuò)誤,此時(shí)不返回bounding box:

if (tracker.getFB()>10 || tbb.x>img2.cols ||? tbb.y>img2.rows || tbb.br().x < 1 || tbb.br().y <1)

(5)歸一化img2(bb)對(duì)應(yīng)的patch的size(放縮至patch_size = 15*15),存入pattern:

getPattern(img2(bb),pattern,mean,stdev);

(6)計(jì)算圖像片pattern到在線(xiàn)模型M的保守相似度:

classifier.NNConf(pattern,isin,dummy,tconf);

(7)如果保守相似度大于閾值,則評(píng)估本次跟蹤有效,否則跟蹤無(wú)效:

if (tconf>classifier.thr_nn_valid) tvalid =true;

?

6.1.2、TLD跟蹤模塊的實(shí)現(xiàn)原理和trackf2f函數(shù)的實(shí)現(xiàn):

?? TLD跟蹤模塊的實(shí)現(xiàn)是利用了Media Flow 中值光流跟蹤和跟蹤錯(cuò)誤檢測(cè)算法的結(jié)合。中值流跟蹤方法是基于Forward-Backward Error和NNC的。原理很簡(jiǎn)單:從t時(shí)刻的圖像的A點(diǎn),跟蹤到t+1時(shí)刻的圖像B點(diǎn);然后倒回來(lái),從t+1時(shí)刻的圖像的B點(diǎn)往回跟蹤,假如跟蹤到t時(shí)刻的圖像的C點(diǎn),這樣就產(chǎn)生了前向和后向兩個(gè)軌跡,比較t時(shí)刻中 A點(diǎn)和C點(diǎn)的距離,如果距離小于一個(gè)閾值,那么就認(rèn)為前向跟蹤是正確的;這個(gè)距離就是FB_error;

bool LKTracker::trackf2f(const Mat& img1, const Mat& img2, vector<Point2f> &points1, vector<cv::Point2f> &points2)

函數(shù)實(shí)現(xiàn)過(guò)程如下:

(1)先利用金字塔LK光流法跟蹤預(yù)測(cè)前向軌跡:

? calcOpticalFlowPyrLK( img1,img2, points1, points2, status, similarity, window_size, level, term_criteria, lambda, 0);

(2)再往回跟蹤,產(chǎn)生后向軌跡:

? calcOpticalFlowPyrLK( img2,img1, points2, pointsFB, FB_status,FB_error, window_size, level, term_criteria, lambda, 0);

(3)然后計(jì)算 FB-error:前向與 后向 軌跡的誤差:

? for( int i= 0; i<points1.size(); ++i )

??????? FB_error[i] = norm(pointsFB[i]-points1[i]);? ???

(4)再?gòu)那耙粠彤?dāng)前幀圖像中(以每個(gè)特征點(diǎn)為中心)使用亞象素精度提取10x10象素矩形(使用函數(shù)getRectSubPix得到),匹配前一幀和當(dāng)前幀中提取的10x10象素矩形,得到匹配后的映射圖像(調(diào)用matchTemplate),得到每一個(gè)點(diǎn)的NCC相關(guān)系數(shù)(也就是相似度大小)。

normCrossCorrelation(img1, img2, points1, points2);

(5)然后篩選出 FB_error[i] <= median(FB_error) 和 sim_error[i] > median(sim_error) 的特征點(diǎn)(舍棄跟蹤結(jié)果不好的特征點(diǎn)),剩下的是不到50%的特征點(diǎn);

filterPts(points1, points2);

?

6.2、檢測(cè)模塊:detect(img2);

TLD的檢測(cè)分類(lèi)器有三部分:方差分類(lèi)器模塊、集合分類(lèi)器模塊和最近鄰分類(lèi)器模塊;這三個(gè)分類(lèi)器是級(jí)聯(lián)的。當(dāng)前幀img2的每一個(gè)掃描窗口依次通過(guò)上面三個(gè)分類(lèi)器,全部通過(guò)才被認(rèn)為含有前景目標(biāo)。具體實(shí)現(xiàn)過(guò)程如下:

先計(jì)算img2的積分圖,為了更快的計(jì)算方差:

integral(frame,iisum,iisqsum);

然后用高斯模糊,去噪:

? GaussianBlur(frame,img,Size(9,9),1.5);?

下一步就進(jìn)入了方差檢測(cè)模塊:

?

6.2.1、方差分類(lèi)器模塊:getVar(grid[i],iisum,iisqsum) >= var

利用積分圖計(jì)算每個(gè)待檢測(cè)窗口的方差,方差大于var閾值(目標(biāo)patch方差的50%)的,則認(rèn)為其含有前景目標(biāo),通過(guò)該模塊的進(jìn)入集合分類(lèi)器模塊:

?

6.2.2、集合分類(lèi)器模塊:

集合分類(lèi)器(隨機(jī)森林)共有10顆樹(shù)(基本分類(lèi)器),每棵樹(shù)13個(gè)判斷節(jié)點(diǎn),每個(gè)判斷節(jié)點(diǎn)經(jīng)比較得到一個(gè)二進(jìn)制位0或者1,這樣每棵樹(shù)就對(duì)應(yīng)得到一個(gè)13位的二進(jìn)制碼x(葉子),這個(gè)二進(jìn)制碼x對(duì)應(yīng)于一個(gè)后驗(yàn)概率P(y|x)。那么整一個(gè)集合分類(lèi)器(共10個(gè)基本分類(lèi)器)就有10個(gè)后驗(yàn)概率了,將10個(gè)后驗(yàn)概率進(jìn)行平均,如果大于閾值(一開(kāi)始設(shè)經(jīng)驗(yàn)值0.65,后面再訓(xùn)練優(yōu)化)的話(huà),就認(rèn)為該圖像片含有前景目標(biāo);具體過(guò)程如下:

(1)先得到該patch的特征值(13位的二進(jìn)制代碼):

classifier.getFeatures(patch,grid[i].sidx,ferns);

(2)再計(jì)算該特征值對(duì)應(yīng)的后驗(yàn)概率累加值:

conf = classifier.measure_forest(ferns);???????????

(3)若集合分類(lèi)器的后驗(yàn)概率的平均值大于閾值fern_th(由訓(xùn)練得到),就認(rèn)為含有前景目標(biāo):

if (conf > numtrees * fern_th)? dt.bb.push_back(i);?

(4)將通過(guò)以上兩個(gè)檢測(cè)模塊的掃描窗口記錄在detect structure中;

(5)如果順利通過(guò)以上兩個(gè)檢測(cè)模塊的掃描窗口數(shù)大于100個(gè),則只取后驗(yàn)概率大的前100個(gè);

nth_element(dt.bb.begin(), dt.bb.begin()+100, dt.bb.end(),

CComparator(tmp.conf));

進(jìn)入最近鄰分類(lèi)器:

?

6.2.3、最近鄰分類(lèi)器模塊

(1)先歸一化patch的size(放縮至patch_size = 15*15),存入dt.patch[i];

getPattern(patch,dt.patch[i],mean,stdev);?

(2)計(jì)算圖像片pattern到在線(xiàn)模型M的相關(guān)相似度和保守相似度:

classifier.NNConf(dt.patch[i],dt.isin[i],dt.conf1[i],dt.conf2[i]);

(3)相關(guān)相似度大于閾值,則認(rèn)為含有前景目標(biāo):

if (dt.conf1[i]>nn_th) ?dbb.push_back(grid[idx]);

到目前為止,檢測(cè)器檢測(cè)完成,全部通過(guò)三個(gè)檢測(cè)模塊的掃描窗口存在dbb中;

?

6.3、綜合模塊:

TLD只跟蹤單目標(biāo),所以綜合模塊綜合跟蹤器跟蹤到的單個(gè)目標(biāo)和檢測(cè)器可能檢測(cè)到的多個(gè)目標(biāo),然后只輸出保守相似度最大的一個(gè)目標(biāo)。具體實(shí)現(xiàn)過(guò)程如下:

(1)先通過(guò) 重疊度 對(duì)檢測(cè)器檢測(cè)到的目標(biāo)bounding box進(jìn)行聚類(lèi),每個(gè)類(lèi)的重疊度小于0.5:

clusterConf(dbb, dconf, cbb, cconf);

(2)再找到與跟蹤器跟蹤到的box距離比較遠(yuǎn)的類(lèi)(檢測(cè)器檢測(cè)到的box),而且它的相關(guān)相似度比跟蹤器的要大:記錄滿(mǎn)足上述條件,也就是可信度比較高的目標(biāo)box的個(gè)數(shù):

if (bbOverlap(tbb, cbb[i])<0.5 && cconf[i]>tconf) confident_detections++;

(3)判斷如果只有一個(gè)滿(mǎn)足上述條件的box,那么就用這個(gè)目標(biāo)box來(lái)重新初始化跟蹤器(也就是用檢測(cè)器的結(jié)果去糾正跟蹤器):

if (confident_detections==1)? bbnext=cbb[didx];

(4)如果滿(mǎn)足上述條件的box不只一個(gè),那么就找到檢測(cè)器檢測(cè)到的box與跟蹤器預(yù)測(cè)到的box距離很近(重疊度大于0.7)的所以box,對(duì)其坐標(biāo)和大小進(jìn)行累加:

if(bbOverlap(tbb,dbb[i])>0.7)? cx += dbb[i].x;……

(5)對(duì)與跟蹤器預(yù)測(cè)到的box距離很近的box 和 跟蹤器本身預(yù)測(cè)到的box 進(jìn)行坐標(biāo)與大小的平均作為最終的目標(biāo)bounding box,但是跟蹤器的權(quán)值較大:

bbnext.x = cvRound((float)(10*tbb.x+cx)/(float)(10+close_detections));……

(6)另外,如果跟蹤器沒(méi)有跟蹤到目標(biāo),但是檢測(cè)器檢測(cè)到了一些可能的目標(biāo)box,那么同樣對(duì)其進(jìn)行聚類(lèi),但只是簡(jiǎn)單的將聚類(lèi)的cbb[0]作為新的跟蹤目標(biāo)box(不比較相似度了??還是里面已經(jīng)排好序了??),重新初始化跟蹤器:

bbnext=cbb[0];

至此,綜合模塊結(jié)束。

?

6.4、學(xué)習(xí)模塊:learn(img2);

??? 學(xué)習(xí)模塊也分為如下四部分:

6.4.1、檢查一致性:

(1)歸一化img(bb)對(duì)應(yīng)的patch的size(放縮至patch_size = 15*15),存入pattern:

? getPattern(img(bb), pattern, mean, stdev);

(2)計(jì)算輸入圖像片(跟蹤器的目標(biāo)box)與在線(xiàn)模型之間的相關(guān)相似度conf:

? classifier.NNConf(pattern,isin,conf,dummy);

(3)如果相似度太小了或者如果方差太小了或者如果被被識(shí)別為負(fù)樣本,那么就不訓(xùn)練了;

if (conf<0.5)……或if (pow(stdev.val[0], 2)< var)……或if(isin[2]==1)……

?

6.4.2、生成樣本:

先是集合分類(lèi)器的樣本:fern_examples:

(1)先計(jì)算所有的掃描窗口與目前的目標(biāo)box的重疊度:

grid[i].overlap = bbOverlap(lastbox, grid[i]);

(2)再根據(jù)傳入的lastbox,在整幀圖像中的全部窗口中尋找與該lastbox距離最小(即最相似,重疊度最大)的num_closest_update個(gè)窗口,然后把這些窗口歸入good_boxes容器(只是把網(wǎng)格數(shù)組的索引存入)同時(shí),把重疊度小于0.2的,歸入 bad_boxes 容器:

? getOverlappingBoxes(lastbox, num_closest_update);

(3)然后用仿射模型產(chǎn)生正樣本(類(lèi)似于第一幀的方法,但只產(chǎn)生10*10=100個(gè)):

generatePositiveData(img, num_warps_update);?

(4)加入負(fù)樣本,相似度大于1??相似度不是出于0和1之間嗎?

idx=bad_boxes[i];

if (tmp.conf[idx]>=1) fern_examples.push_back(make_pair(tmp.patt[idx],0));

然后是最近鄰分類(lèi)器的樣本:nn_examples:

if (bbOverlap(lastbox,grid[idx]) < bad_overlap)

??????? nn_examples.push_back(dt.patch[i]);

?

6.4.3、分類(lèi)器訓(xùn)練:

classifier.trainF(fern_examples,2);

classifier.trainNN(nn_examples);

?

6.4.4、把正樣本庫(kù)(在線(xiàn)模型)包含的所有正樣本顯示在窗口上

classifier.show();

至此,tld.processFrame函數(shù)結(jié)束。

?

7、如果跟蹤成功,則把相應(yīng)的點(diǎn)和box畫(huà)出來(lái):

??? if (status){

????? drawPoints(frame,pts1);

????? drawPoints(frame,pts2,Scalar(0,255,0));? //當(dāng)前的特征點(diǎn)用藍(lán)色點(diǎn)表示

????? drawBox(frame,pbox);

????? detections++;

}

?

8、然后顯示窗口和交換圖像幀,進(jìn)入下一幀的處理:

??? imshow("TLD", frame);

swap(last_gray, current_gray);

至此,main()函數(shù)結(jié)束(只分析了框架)。

總結(jié)

以上是生活随笔為你收集整理的TLD(Tracking-Learning-Detection)学习与源码理解之(三)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。