国产免费无码又爽又刺激高潮_国产亚洲欧美在线人成aaaa_亚洲av永久无码精品尤物_专区久久五月天_国内精品久久人妻无码妲己影院

專題欄目:ARVRMR虛擬現(xiàn)實

Anchor | Anchor是什么意思?

Anchor,為 錨點。

定義:錨點描述了在現(xiàn)實世界中一個固定的位置和方向,當用戶想要放置一個虛擬物體時在平面上時,需要定義一個錨點來確保AR可以跟蹤虛擬物體隨用戶運動推移所在的相對位置?;阱^點可以將虛擬物體錨定在現(xiàn)實空間中某一特定位置,進而實現(xiàn)用戶可以從不同位置和角度進行觀察。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1、選擇性搜索(Selective Search)

先介紹一下傳統(tǒng)的人臉識別算法,是怎么檢測出圖片中的人臉的?

以下圖為例,如果我們要檢測圖中小女孩的人臉位置,一個比較簡單暴力的方法就是滑窗,我們使用不同大小、不同長寬比的候選框在整幅圖像上進行窮盡式的滑窗,然后提取窗口內的特征(例如Haar、LBP、Hog等特征),再送入分類器(SVM、Adaboost等)判斷該窗口內包含的是否為人臉。這種方法簡單易理解,但是這類方法受限于手動設計的特征,召回率和準確率通常不是很高。

大名鼎鼎的RCNN 和 Fast RCNN依舊依賴滑窗來產生候選框,也就是Selective Search算法,該算法優(yōu)化了候選框的生成策略,但仍舊會產生大量的候選框,導致即使Fast RCNN算法,在GPU上的速度也只有三、四幀每秒。

直到Faster RCNN的出現(xiàn),提出了RPN網絡(Region Proposal Network),使用RPN直接預測出候選框的位置。用RPN代替Fast RCNN中Selective Search,RPN與object detection network共享卷積層,節(jié)省了大量選擇候選區(qū)域的時間。

RPN網絡一個最重要的概念就是anchor,啟發(fā)了后面的SSD和YOLOv2等算法,雖然SSD算法稱之為default box,也有算法叫做prior box,其實都是同一個概念,他們都是anchor的別稱。


2、什么是Anchor ?

2.1 Anchor

anchor到底是什么呢?如果我們用一句話概括——就是在圖像上預設好的不同大小,不同長寬比的參照框。(其實非常類似于上面的滑窗法所設置的窗口大?。?/p>

假設一個256x256大小的圖片,經過64、128和256倍下采樣,會產生4x4、2x2、1x1大小的特征圖,我們在這三個特征圖上每個點上都設置三個不同大小的anchor。

當然,這只是一個例子,實際的SSD模型,在300x300的輸入下,anchor數(shù)量也特別多,其在38x38、19x19、10x10、5x5、3x3、1x1的六個特征圖上,每個點分別設置4、6、6、6、6、4個不同大小和長寬比的anchor,所以一共有38x38x4+ 19x19x6+ 10x10x6+ 5x5x6+ 3x3x4+ 1x1x4= 8732個anchor。

在SSD中6層卷積層的每個特征圖的每個中心點會產生2個不同大小的正方形默認框,另外每設置一個aspect_ratio則會增加兩個長方形默認框,而文中代碼對于6層的aspect_ratio個數(shù)分別為1、2、2、2、1、1,所以這也就是為什么會產生4、6、6、6、4、4個默認框了。

aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]] 。paper中所給出的ar={1,2,3,1/2,1/3},這個比例是計算出來的。

我們不再需要計算Haar、Hog等特征,直接讓神經網絡輸出,每個anchor是否包含物體(anchor與物體Bounding Box有較大重疊,交并比IoU(Intersection-over-Union,IoU)較大),以及被檢測物體相對本anchor的中心點偏移以及長寬比例。

1、每個anchor認為自己是否含有物體的概率,
2、物體中心點與anchor自身的中心點位置的偏移量,
3、以及相對于anchor寬高的比例。


一般的目標檢測網絡可能有成千上萬個anchor,例如標準SSD在300x300輸入下有8732個anchor,在500x500下anchor數(shù)量過萬。

因為anchor的位置都是固定的,所以就可以很容易的換算出來實際物體的位置。以圖中的小貓為例,紅色的anchor就以99%的概率認為它是一只貓,并同時給出了貓的實際位置相對于該anchor的偏移量,這樣,我們將輸出解碼后就得到了實際貓的位置,如果它能通過NMS(非最大抑制,non-maximum suppression)篩選,它就能順利的輸出來。但是,綠色的anchor就認為它是貓的概率就很小,紫色的anchor雖然與貓有重疊,但是概率只有26%。

SSD的推理很簡單,根據(jù)anchor進行位置解碼,然后進行NMS過程,就完成了。

設置IoU閾值,例如大于0.5就認為是正樣本,否則是負樣本,(SSD算法中會給它強行分配一個IoU最大的anchor,即使IoU只有0.3)。因為anchor非常密集,所以SSD算法中,會有多個anchor與物體的IoU大于閾值,所以可能多個anchor都是對應同一個物體的正樣本。圖中的貓已經有了2個匹配的正樣本(藍色框)。

注意:在訓練的時候,anchor的大小和長寬比應與待檢測的物體尺度基本一致。


2.2 anchor_sizes從何而來?

2.2.1 FasterRCNN

FasterRCNN的RPN網絡部分,anchor為三個尺度{128, 256, 512},三個比例{1:1, 1:2, 2:1},所以一共9組anchor。

2.2.2 SSD

在SSD論文中,作者使用6組定位層,(6個用于分類和回歸的特征層(feature map),分別是'conv4_3', 'fc7', 'conv6_2', 'conv7_2', 'conv8_2', 'conv9_2'。每個定位層分別有6個anchor(不過第一和最后一個定位層只有4個)。一個尺度,分別有1:1、1:2、2:1、1:3、3:1五個不同寬高比,再加一個后面特征圖的anchor尺度與該特征圖的尺度相乘再開根號,也就是:

同樣是1:1比例,所以一共5+1=6組anchor。

但是,大家查看SSD開源的代碼,作者給出的得anchor大小并不是這么計算得到的。而是30、60、111、162、213、264(再加一個315)這7個尺度。

ssd_pascal.py

“#參數(shù)生成先驗。
#輸入圖像的最小尺寸
min_dim = 300 #######維度
# conv4_3 ==> 38 x 38
# fc7 ==> 19 x 19
# conv6_2 ==> 10 x 10
# conv7_2 ==> 5 x 5
# conv8_2 ==> 3 x 3
# conv9_2 ==> 1 x 1
mbox_source_layers = ['conv4_3', 'fc7', 'conv6_2', 'conv7_2', 'conv8_2', 'conv9_2'] #####prior_box來源層,可以更改。很多改進都是基于此處的調整。
# in percent %
min_ratio = 20 ####這里即是論文中所說的Smin=0.2,Smax=0.9的初始值,經過下面的運算即可得到min_sizes,max_sizes。具體如何計算以及兩者代表什么,請關注我的博客SSD詳解。這里產生很多改進。
max_ratio = 90
####math.floor()函數(shù)表示:求一個最接近它的整數(shù),它的值小于或等于這個浮點數(shù)。
step = int(math.floor((max_ratio - min_ratio) / (len(mbox_source_layers) - 2)))####取一個間距步長,即在下面for循環(huán)給ratio取值時起一個間距作用。可以用一個具體的數(shù)值代替,這里等于17。
min_sizes = [] ###經過以下運算得到min_sizes和max_sizes。
max_sizes = []
for ratio in xrange(min_ratio, max_ratio + 1, step): ####從min_ratio至max_ratio+1每隔step=17取一個值賦值給ratio。注意xrange函數(shù)的作用。
########min_sizes.append()函數(shù)即把括號內部每次得到的值依次給了min_sizes。
min_sizes.append(min_dim * ratio / 100.)
max_sizes.append(min_dim * (ratio + step) / 100.)
min_sizes = [min_dim * 10 / 100.] + min_sizes
max_sizes = [min_dim * 20 / 100.] + max_sizes
steps = [8, 16, 32, 64, 100, 300] ###這一步要仔細理解,即計算卷積層產生的prior_box距離原圖的步長,先驗框中心點的坐標會乘以step,相當于從feature map位置映射回原圖位置,比如conv4_3輸出特征圖大小為38*38,而輸入的圖片為300*300,所以38*8約等于300,所以映射步長為8。這是針對300*300的訓練圖片。
aspect_ratios = [[2], [2, 3], [2, 3], [2, 3], [2], [2]] #######這里指的是橫縱比,六種尺度對應六個產生prior_box的卷積層。具體可查看生成的train.prototxt文件一一對應每層的aspect_ratio參數(shù),此參數(shù)在caffe.proto中有定義,關于aspect_ratios如何把其內容傳遞給了aspect_ratio,在model_libs.py文件中有詳細定義。
##在此我們要說明一個事實,就是文中的長寬比是如何產生的,這里請讀者一定要參看博主博文《SSD詳解(一)》中的第2部分內容,關于prior_box的產生。”

(1)對ssd產生的默認框的大小計算首先要計算參數(shù)min_sizes和max_sizes

step的作用,其實就是取一個間隔

首先定義數(shù)組min_sizes[]和max_sizes[]用來存放計算結果,沒有初始化說明默認為0,。然后計算conv4_3產生的min_sizes和max_sizes。根據(jù)代碼中的公式計算:

·min_sizes=[min_dim*10/100]+min_sizes
·max_sizes=[min_dim*20/100]+max_sizes

得到結果為min_sizes=[300*10/100]+0=30,而max_sizes=[300*20/100]+0=60。這樣conv4_3的計算公式被計算分別為30和60。

在min_ratio和max_ratio之間即20-90之間以step=17為間隔產生一組數(shù)據(jù)賦值給ratio,最終ratio=[20,37,54,71,88]。所以對于剩余5層所產生的min_sizes和max_sizes分別為:

fc7:min_sizes=min_dim*ratio/100=300*20/100=60,max_sizes=min_dim*(ratio+step)/100=300*(20+17)/100=111;

conv6_2:min_sizes=min_dim*ratio/100=300*37/100=111,max_sizes=min_dim*(ratio+step)/100=300*(37+17)/100=162;

conv7_2:min_sizes=min_dim*ratio/100=300*54/100=162,max_sizes=min_dim*(ratio+step)/100=300*(54+17)/100=213;

conv8_2:min_sizes=min_dim*ratio/100=300*71/100=213,max_sizes=min_dim*(ratio+step)/100=300*(71+17)/100=264;

conv9_2:min_sizes=min_dim*ratio/100=300*88/100=213,max_sizes=min_dim*(ratio+step)/100=300*(88+17)/100=315;

結果:7個數(shù)據(jù),6個區(qū)間段

(2)產生的默認框的大小計算

·正方形小邊長=min_size
·而大正方形邊長=sqrt(min_size*max_size)
·width=sqrt(aspect_ratio)*min_size
·height=1/sqrt(aspect_ratio)*min_size

對其高和寬翻轉后得到另一個面積相同但寬高相互置換的長方形(width和height公式對調)。

現(xiàn)在我們可以計算6層中每個特征圖的每個中心點所產生的默認框的大小,分別如下:

conv4_3:

小正方形邊長=min_size=30,大正方形邊長=sqrt(min_size*max_size)=sprt(30*60)=42.42;

長方形的寬=sqrt(aspect_ratio)*min_size=sqrt(2)*30,高=1/sqrt(aspect_ratio)*min_size=30/sqrt(2),寬高比剛好為2:1;

將以上寬高旋轉90度產生另一個長方形,寬高比變?yōu)?:2。

fc7:

小正方形邊長=min_size=60,大正方形邊長=sqrt(min_size*max_size)=sprt(60*111)=81.6;

第1組長方形的寬=sqrt(aspect_ratio)*min_size=sqrt(2)*60,高=1/sqrt(aspect_ratio)*min_size=60/sqrt(2),寬高比剛好為2:1;

將以上寬高旋轉90度產生另一個長方形,寬高比變?yōu)?:2。

第2組長方形的寬=sqrt(aspect_ratio)*min_size=sqrt(3)*60,高=1/sqrt(aspect_ratio)*min_size=60/sqrt(3),寬高比剛好為3:1;

將以上寬高旋轉90度產生另一個長方形,寬高比變?yōu)?:3。

conv6_2:

小正方形邊長=min_size=111,大正方形邊長=sqrt(min_size*max_size)=sprt(111*162);

第1組長方形的寬=sqrt(aspect_ratio)*min_size=sqrt(2)*111,高=1/sqrt(aspect_ratio)*min_size=111/sqrt(2),寬高比剛好為2:1;

將以上寬高旋轉90度產生另一個長方形,寬高比變?yōu)?:2。

第2組長方形的寬=sqrt(aspect_ratio)*min_size=sqrt(3)*111,高=1/sqrt(aspect_ratio)*min_size=111/sqrt(3),寬高比剛好為3:1;

將以上寬高旋轉90度產生另一個長方形,寬高比變?yōu)?:3。

1、anchor_size, 這個參數(shù)直接決定了當前特征層的box 的大小, 可以看出越靠近輸入層, box越小, 越靠近輸出層, box越大, 所以 SSD的底層用于檢測小目標, 高層用于檢測大目標。
2、conv7_2、conv8_2、conv9_2我們這里就不再計算了,具體實現(xiàn)的步驟請大家參考腳本prior_box_layer.cpp
3、另外先驗框與ground truth框的匹配通過函數(shù)CHECK_GT()函數(shù)實現(xiàn),具體在bbox_util.cpp腳本中實現(xiàn)

附:tensorflow實現(xiàn)的SSD的源碼:

default_params = SSDParams(
img_shape=(300, 300),
num_classes=21,
no_annotation_label=21,
feat_layers=['block4', 'block7', 'block8', 'block9', 'block10', 'block11'],
feat_shapes=[(38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1)],
# anchor_size_bounds=[0.15, 0.90],
anchor_size_bounds=[0.20, 0.90],
#anchor_sizes=[(21., 45.),
# (45., 99.),
# (99., 153.),
# (153., 207.),
# (207., 261.),
# (261., 315.)],
anchor_sizes=[(30., 60.),
(60., 111.),
(111., 162.),
(162., 213.),
(213., 264.),
(264., 315.)],
anchor_ratios=[[2, .5],
[2, .5, 3, 1./3],
[2, .5, 3, 1./3],
[2, .5, 3, 1./3],
[2, .5],
[2, .5]],
anchor_steps=[8, 16, 32, 64, 100, 300],
anchor_offset=0.5,
normalizations=[20, -1, -1, -1, -1, -1],
prior_scaling=[0.1, 0.1, 0.2, 0.2]
)

2.2.3 YOLOv3

在三個不同尺度,每個尺度三個不同大小的anchor,一共九組。

2.3 anchor_ratios???????

anchor_ratios,定義了anchor的寬高比,這里設置anchor_rations = [0.5, 1, 2]。

需要注意的是寬高比變化的同時保持面積不變。對于 base_size = 16 的情況下:

·ratio為0.5時,尺寸為 (16/sqrt(2)) x (16*sqrt(2)),即 11 x 22;(寬 × 高)
·ratio為1時,anchor尺寸為16 x 16;
·ratio為2時,尺寸為 23 x 12 。


得到的anchor如下圖所示,藍色點代表feature map中的特征點,每種顏色框代表一種長寬比,同一顏色不同大小的矩形框代表不同的尺度:

紅色:ration = 2

藍色:ration = 1

綠色:ration = 0.5

坐標順序為:左下右上。

 

附:anchors 的生成過程(generate_anchors源碼解析)

import numpy as np
import time

def generate_anchors(base_size=16, ratios=[0.5, 1, 2], scales=2**np.arange(3, 6)):
"""
Generate anchor (reference) windows by enumerating aspect ratios X
scales wrt a reference (0, 0, 15, 15) window.
scales = [8, 16, 32]
16x16的區(qū)域變成(16*8)*(16*8)=128*128的區(qū)域,(16*16)*(16*16)=256*256的區(qū)域,(16*32)*(16*32)=512*512的區(qū)域
"""

# 表示最基本的一個大小為16x16的區(qū)域,四個值,分別代表這個區(qū)域的左上角和右下角的點的坐標。
base_anchor = np.array([1, 1, base_size, base_size]) - 1
print ("base anchors", base_anchor)

# 這一句是將前面的16x16的區(qū)域進行ratio變化,也就是輸出三種寬高比的anchors,這里調用了_ratio_enum函數(shù)
ratio_anchors = _ratio_enum(base_anchor, ratios)
print ("anchors after three ratio \n", ratio_anchors)

anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales)
for i in range(ratio_anchors.shape[0])])
print ("achors after ration and scale \n", anchors)

return anchors

def _ratio_enum(anchor, ratios):
'''
Enumerate a set of anchors for each aspect ratio wrt an anchor.

Parameters:
anchor : A list contains coordinates of the upper left and lower right corners.
ratios : A list contains different aspect ratios.
Return:
anchors : Coordinates with different aspect ratios.
'''
w, h, x_ctr, y_ctr = _whctrs(anchor)

size = w * h #size:16*16=256
size_ratios = size / np.array(ratios) #256/ratios[0.5,1,2]=[512,256,128]
ws = np.round(np.sqrt(size_ratios)) #ws:[23 16 11]
hs = np.round(ws * ratios) #hs:[12 16 22],ws和hs一一對應。as:23*12、16*16、11*22,(高 × 寬)

# print(hs)
# print(ws.shape)
# 給定一組寬高向量,輸出各個預測窗口,也就是將(寬,高,中心點橫坐標,中心點縱坐標)的形式,轉成四個坐標值的形式
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)

return anchors

def _whctrs(anchor):
"""
主要作用是將輸入的anchor的四個坐標值[0, 0, 15, 15]轉化成(寬,高,中心點橫坐標,中心點縱坐標)的形式。
Return width, height, x center, and y center for an anchor (window).
"""
w = anchor[2] - anchor[0] + 1# w = 16
h = anchor[3] - anchor[1] + 1# h = 16
x_ctr = anchor[0] + 0.5 * (w - 1)# 7.5
y_ctr = anchor[1] + 0.5 * (h - 1)# 7.5
return w, h, x_ctr, y_ctr

def _mkanchors(ws, hs, x_ctr, y_ctr):
"""
Getting coordinates of different window width ratios around the same center.

Parameters:
ws : A sist of X coordinates in the upper left corner of a anchor.
hs : A sist of Y coordinates in the upper left corner of a anchor.
x_ctr : X-coordinates of the center of a anchor.
y_ctr : Y-coordinates of the center of a anchor.
Return:
anchors : Coordinates with different aspect ratios.
"""
ws = ws[:, np.newaxis]# ws的維度變?yōu)閇3,1],即[[23]
# [16]
# [11]]
# print(ws)
# print(ws.shape)
hs = hs[:, np.newaxis]# hs同理
anchors = np.hstack((x_ctr - 0.5 * (ws - 1),
y_ctr - 0.5 * (hs - 1),
x_ctr + 0.5 * (ws - 1),
y_ctr + 0.5 * (hs - 1)))
return anchors

def _scale_enum(anchor, scales):
"""
_enum表示枚舉,以_ratio_enum(...)得到的3個anchor,得到其中心點和寬、高值,并將寬、高值與3個scale相乘(保持中心點不變),
最終得到9個在scaled圖像中(0,0)位置的base anchors,被generate_anchors(...)調用

Enumerate(枚舉) a set of anchors for each scale wrt an anchor.

Parameters:
anchor : Orginal anchor.
scales : Scaling factor.
Return:
Scaled coordinates of anchor.
"""
w, h, x_ctr, y_ctr = _whctrs(anchor)
ws = w * scales
hs = h * scales
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
return anchors

if __name__ == '__main__':
import time
t = time.time()
a = generate_anchors() #最主要的就是這個函數(shù)
print("it takes time:", time.time() - t)

補充:

SSD中min_size&max_size的另一種計算方法(來自網上,不知道是否正確):

在SSD中,作者提到了anchor尺度大?。╯cale)的計算方法,也就是從最小的0.2,到最大的0.9,中間四個定位層的大小是等間隔采樣得到的。

Sk是每個特征層的先驗框大小與原圖片大小之比,Smax和Smin分別是最大,最小的比例.

m是就是特征層的個數(shù),按理說分母應該是6-1=5,但是這里是5-1=4.很神奇。

k是第幾個特征層的意思,注意k的范圍是1~m, 也就是1~6.

需要向下取整

將m=5, Smin, Smax=(0.2, 0.9) 就是anchor_size_bounds=[0.20, 0.90],帶入之后,得到S1~S6: 20, 37, 54, 71, 88, 105, 其實就是挨個+17。此時還需要將其除以100還原回來,也就是:0.2, 0.37, 0.54, 0.71, 0.88, 1.05。然后,我們這個是比例,我們需要得到其在原圖上的尺寸,所以需要依次乘以300,得到:60, 111, 162, 213, 264, 315。

最后,你會問: 30呢? 這就要說到S1’了,S1’=0.5*S1, 就是0.1, 再乘以300, 就是30.

有七個數(shù), 6個區(qū)間段, 目的還是為了得到上面那6組min_size和max_size. 就可以計算每個特征層的anchor_box 的尺寸了。

我想這應該是作者根據(jù)數(shù)據(jù)集的物體框大小的分布而設置的。因為上面我們介紹了,anchor只有跟你要檢測的物體的大小和長寬比更貼近,才能讓模型的效果更好。

延伸閱讀來源:https://blog.csdn.net/weixin_44285715/article/details/105124650

發(fā)表評論

相關文章