關於可變部件模型的描寫敘述在作者[2010 PAMI]Object Detection with Discriminatively Trained Part Based Models的論文中已經有說明:
含有n個部件的目標模型能夠形式上定義為一個(n+2)元組:(F0,P1,..., Pn, b),F0是根濾波器,Pi是第i個部件的模型,b是表示偏差的實數值。每一個部件模型用一個三元組定義:(Fi,vi, di),Fi是第i個部件的濾波器;vi是一個二維向量,指定第i個濾波器的錨點位置(anchor position,即未發生形變時的標准位置) 相對於根的坐標;di是一個四維向量,指定了一個二次函數的參數,此二次函數表示部件的每一個可能位置相對於錨點位置的變形花費(deformation cost)。
可是有了這個說明我們在看源代碼時還是會有非常多不明確的地方,剛開始困擾我非常長時間,經過一段時間的分析,有了一定的理解,以下是我對這個模型的分析,如有不妥之處,請大家留言指正。
我分析的源代碼版本號是voc-release3.1,從第4版開始增加了語法模型,更加復雜了,這里不討論。
分析模型結構體主要看initmodel.m這個文件,通過看他怎樣初始化模型,我們能夠明確當中大多數字段的含義。
在這之前,我們能夠在matlab中打開一兩個源代碼中自帶的訓練好的模型m文件,看看是什么樣的。
inria_final.mat,Inria數據集上訓練的單組件模型
person_final.mat,VOC2007數據集上訓練的2組件人體模型
以下我會依次對各個字段做詳解
(1) sbin,整型標量
sbin是HOG特征中cell的尺寸,即cell的尺寸為sbin * sbin
定義cell是為了將像素級特征聚合成為基於cell的特征C(i,j),0<=i<=|(w-1)/k|,0<=j<=|(h-1)/k|,參見[2010 PAMI]論文6.1.2 空間聚合,這里的k就是cell尺寸sbin,這樣能夠更明白的理解sbin的用處。
(2) interval,整型標量
HOG金字塔每組的層數
(3) numblocks,整型標量
模型中總的數據塊的個數
(4) numcomponents,整型標量
組件的個數(含多少個組件模型)
(5) blocksizes,double數組,長度等於numblock
blocksizes[]數組的元素個數等於numblock,指明每一個數據塊的大小,
所以,想知道哪個數據的大小,就先找到他的數據塊標識,然后去blocksizes[]數組查找相應的數據塊大小。
(6) regmult,double數組,長度等於numblock
還不清楚干什么的
(7) learnmult,double數組,長度等於numblock
還不清楚干什么的
(8) lowerbounds,cell類型數組,長度等於numblock
每一個數據塊的數據值的下界,lowerbounds[]數組的元素個數等於numblock。
假如某個數據塊的數據是向量或矩陣的話,則相應的lowerbounds元素值也是一個下界向量或矩陣
(9) maxsize,二元組
全部組件的根濾波器的[高度 寬度]的最大值,maxsize是統計全部組件的根濾波器的尺寸獲得的。
(10) minsize,二元組
全部組件的根濾波器的[高度 寬度]的最小值,minsize是統計全部組件的根濾波器的尺寸獲得的。
(11) thresh,double類型標量
保證高召回率須要的得分閾值,依據訓練結果計算得到的。
也就是說,假設用此模型進行目標檢測時,將得分閾值設為thresh可以保證非常高的召回率(recall rate),可是同一時候精度肯定就低了。
(12) rootfilters,cell類型數組,長度為組件個數
根濾波器數組,其每一個元素表示一個組件模型的根濾波器的信息,每一個元素包含3個字段:
size:根濾波器的尺寸,以cell為單位,w*h
w:根濾波器的參數向量,維數為(w*h)*31
blocklabel:此根濾波器所在的數據塊標識
(13) partfilters,cell類型數組,長度為模型中全部組件的部件的個數之和
部件濾波器數組,其每一個元素表示一個部件濾波器的信息,每一個元素包含4個字段,注意:全部組件的部件是連續編號的
w:部件濾波器的參數向量,維數為(w*h)*31
partner:此部件相應的伙伴部件(對稱部件)的索引,假設partner的值為0,表示此部件沒有伙伴部件。
fake:是否假部件,值為1表示此部件是假部件,假部件不須要blocklabel
blocklabel:此部件濾波器所在的數據塊標識
(14) defs,cell類型數組,長度為模型中全部組件的部件的個數之和
部件的錨點數組 (變形信息數組),每一個元素表示相應部件的可變形信息。注意:全部組件的部件在defs中也是連續編號的。每一個元素包括3個字段:
anchor:部件的錨點坐標,即部件未變形時的左上角點坐標,參見論文[2010 PAMI]中的公式(3)中的vi變量
w:w是一個四維向量,指明部件的變形花費函數的參數,參見論文[2010 PAMI]中的公式(2)中的di變量
blocklabel:所在的數據塊標識
(15) offsets,cell類型數組,長度為組件個數
偏移量數組,每一個元素表示相應組件模型的偏移量,每一個元素又含有2個字段
w:組件的偏移量,是個實數值
blocklabel:所在的數據塊標識
(16) components,cell類型數組,長度為組件個數
組件信息數組,每一個元素存儲一個組件模型的信息,每一個元素又包括7個字段:
rootindex:根濾波器的索引,指出組件的根濾波器在rootfilters[]數組的位置
offsetindex:組件的偏移量索引,指出組件的偏移量在offsets[]數組的位置
part:組件的部件信息數組,長度為該組件的部件個數,每一個元素表示一個部件,每一個元素又有2個字段:
partindex:部件的索引,指出此部件在partfilters[]數組的位置,注意:全部組件的部件是連續編號的
defindex:部件的錨點數組索引,指出此部件的錨點在defs[]數組的位置,注意:全部組件的部件是連續編號的
dim:組件的維數(至於這個值詳細是怎么計算來的,我如今還不清楚,弄清楚了來更新)
numblocks:組件所占的數據塊個數(須要多少個數據塊來存儲此組件模型)
x1,y1,x2,y2:包圍盒預測參數
一些須要解釋的地方
關於模型中的blocklabel的理講解明:
模型中有好多數組,比如rootfilters[],partfilters[],defs[],offsets[],這些數組的數據是以塊block為單位進行存儲的,通過塊標識blocklabel來識別哪個數據位於哪個塊上,所以上述數組的每一個成員都有一個blocklabel域,來指明此數據所在的塊。numblock是總的數據塊個數。blocksizes[]數組的元素個數等於numblock,指明每一個數據塊的大小,
所以,想知道哪個數據的大小,就先找到他的數據塊標識,然后去blocksizes[]數組查找相應的數據塊大小。
關於部件的伙伴partner的解釋:
在voc-release3.1中,模型是關於中軸對稱的,所以就有了伙伴部件(或稱為對稱部件)的概念。注意:從第4版開始模型不再要求是對稱的。一個部件存在伙伴,就說明有和此部件對稱的部件。伙伴部件的參數向量和此部件的參數向量w全然同樣,一個部件和其伙伴部件是關於模型的中軸對稱的,所以不須要反復存儲參數向量w,這樣,就產生了一些假(fake)部件,它們僅僅有一個空殼。假部件(fake=1)沒有blocklabel,由於它們不須要數據塊來存儲信息,它們的信息存儲在相應的伙伴部件中。假設partner的值為0,表示此部件沒有伙伴部件。
關於偏移量offset的解釋:
偏移量offset就是加在每一個組件模型的得分公式最后的一個實數值,參見論文[2010 PAMI]中的公式(2)中的b值。
關於錨點數組defs的解釋:
一開始我以為def是定義definition的縮寫,但解釋不通,如今知道了,def是可變形deformable的縮寫,所以defs數組中存儲的是全部部件的變形參數。anchor,錨點坐標,是部件未發生移動時的坐標,即理想狀況下的位置,更具體的說,anchor是部件未變形時的左上角點坐標。w,是個4維向量,指明部件i的變形花費函數的參數,參見論文[2010 PAMI]中的公式(2)中的di變量。通過分析源代碼發現w中4個參數分別相應這4個偏移量[Δx^2, Δx, Δy^2, Δy](分析可視化變形花費的代碼時確定的,在文件visualizemodel.m中)。
關於每一個cell的特征向量的維數為什么是31維的解釋:
設C是聚合有9個對照度不敏感方向的像素級特征映射而獲得的基於cell的特征映射,D是聚合有18個對照度敏感方向的像素級特征而獲得的基於cell的特征映射。用4種不同的歸一化方法對C(i,j)和D(i,j)進行歸一化和截斷(限幅),能夠獲得一個4*(9+18)=108維的特征向量F(i,j)。實際中我們使用此108維向量的一個解析投影,此投影由以下幾個統計量定義:27個在不同歸一化因子上的累加和(即列的和),F中的每一個方向通道相應一個;以及4個在不同方向(9維對照度不敏感方向)上的累加和(即行的和),每一個歸一化因子相應一個。cell尺寸k=8,截斷(限幅)閾值α=0.2。終於的特征映射是31維向量G(i,j),當中27維相應不同的方向通道(9個對照度不敏感方向和18個對照度敏感方向),剩下4維表示(i,j)周圍4個cell組成的block的梯度能量。詳見[2010 PAMI]論文中6.2節 PCA和解析降維。
明確了這些,初始化的過程就非常easy看懂了,初始化的過程在以下的源代碼上有凝視:
function model = initmodel(pos, sbin, size) % 初始化模型結構 % 參數 % pos:用來訓練此模型的正樣本數組 % sbin:HOG特征的最小單位,cell的長度 % size:根濾波器尺寸 % 假設不提供根濾波器的尺寸,則依據正樣本的長寬比統計信息計算得出 % % model = initmodel(pos, sbin, size) % Initialize model structure. % If not supplied,the dimensions of the model template are computed from statistics in the postive examples. % % 關於cell尺寸sbin的解釋: % 將像素級特征聚合成為基於cell的特征C(i,j),0<=i<=|(w-1)/k|,0<=j<=|(h-1)/k|,參見[2010 PAMI]論文6.1.2 空間聚合, % 這里的k就是cell尺寸sbin,這樣能夠更明白的理解sbin的用處 % % 關於部件的伙伴partner的解釋: % 在voc-release3.1中,模型是關於中軸對稱的,所以就有了伙伴部件(或稱為對稱部件)的概念。注意:從第4版開始模型不再要求是對稱的。 % 一個部件存在伙伴,就說明有和此部件對稱的部件。伙伴部件的參數向量和此部件的參數向量w全然同樣,一個部件和其伙伴部件是關於模型的中軸對稱的, % 所以不須要反復存儲參數向量w,這樣,就產生了一些假(fake)部件,它們僅僅有一個空殼。假部件(fake=1)沒有blocklabel,由於它們不須要數據塊來存儲信息, % 它們的信息存儲在相應的伙伴部件中。假設partner的值為0,表示此部件沒有伙伴部件。 % % 關於每一個cell的特征向量的維數為什么是31維的解釋: % 設C是聚合有9個對照度不敏感方向的像素級特征映射而獲得的基於cell的特征映射,D是聚合有18個對照度敏感方向的像素級特征而獲得的基於cell的特征映射。 % 用4種不同的歸一化方法對C(i,j)和D(i,j)進行歸一化和截斷(限幅),能夠獲得一個4*(9+18)=108維的特征向量F(i,j)。 % 實際中我們使用此108維向量的一個解析投影,此投影由以下幾個統計量定義: % 27個在不同歸一化因子上的累加和(即列的和),F中的每一個方向通道相應一個;以及4個在不同方向(9維對照度不敏感方向)上的累加和(即行的和),每一個歸一化因子相應一個。 % cell尺寸k=8,截斷(限幅)閾值α=0.2。終於的特征映射是31維向量G(i,j),當中27維相應不同的方向通道(9個對照度不敏感方向和18個對照度敏感方向), % 剩下4維表示(i,j)周圍4個cell組成的block的梯度能量。詳見[2010 PAMI]論文中6.2節 PCA和解析降維 % % 關於模型中的blocklabel的理講解明: % 模型中有好多數組,比如rootfilters[],partfilters[],defs[],offsets[],這些數組的數據是以塊block為單位進行存儲的, % 通過塊標識blocklabel來識別哪個數據位於哪個塊上,所以上述數組的每一個成員都有一個blocklabel域,來指明此數據所在的塊。 % numblock是總的數據塊個數(注意不是總的部件個數,剛開始理解錯了),blocksizes[]數組的元素個數等於numblock,指明每一個數據塊的大小, % 所以,想知道哪個數據的大小,就先找到他的數據塊標識,然后去blocksizes[]數組查找相應的數據塊大小。 % % 關於偏移量offset的解釋: % 偏移量offset就是加在每一個組件模型的得分公式最后的一個實數值,參見論文[2010 PAMI]中的公式(2)中的b值 % % 關於錨點坐標數組defs[]的解釋: % 一開始我以為def是定義definition的縮寫,但解釋不通,如今知道了,def是可變形deformable的縮寫,所以defs數組中存儲的是全部部件的變形參數 % anchor,錨點坐標,是部件未發生移動時的坐標,即理想狀況下的位置,更具體的說,anchor是部件未變形時的左上角點坐標 % w,是個4維向量,指明部件i的變形花費函數的參數,參見論文[2010 PAMI]中的公式(2)中的di變量 % 通過分析源代碼發現w中4個參數分別相應這4個偏移量[Δx^2, Δx, Δy^2, Δy](分析可視化變形花費的代碼時確定的,在文件visualizemodel.m中) % % model.sbin HOG cell的尺寸 % model.interval 金字塔每組的層數 % model.numblocks 總的數據塊個數 % model.numcomponents 組件的個數(含多少個組件模型) % model.blocksizes 每一個數據塊的大小,blocksizes[]數組的元素個數等於numblock % model.regmult % model.learnmult % model.lowerbounds 每一個數據塊的數據值的下界,lowerbounds[]數組的元素個數等於numblock %假如某個數據塊的數據是向量或矩陣的話,則相應的lowerbounds元素值也是一個下界向量或矩陣 % model.maxsize 全部組件的根濾波器的[高度 寬度]的最大值 % model.minsize 全部組件的根濾波器的[高度 寬度]的最小值 % model.rootfilters{i} 組件i的根濾波器,根濾波器數組的長度等於組件個數 % .size 組件i的根濾波器的尺寸(以cell為單位),w*h % .w 組件i的根濾波器向量,維數為(w*h)*31 % .blocklabel 組件i的根濾波器所在的數據塊標識 % model.partfilters{i} 第i個部件濾波器,部件濾波器數組的長度等於全部組件的部件個數的總和,注意:全部組件模型的part是連續編號的 % .w 第i個部件濾波器向量,維數為(w*h)*31 % .blocklabel 第i個部件濾波器所在的數據塊標識 % model.defs{i} 第i個部件的錨點,部件錨點數組的長度等於全部組件的部件個數的總和,全部組件模型的part是連續編號的 % .anchor 第i個部件的錨點坐標,即部件i未變形時的左上角點坐標,參見論文[2010 PAMI]中的公式(3)中的vi變量 % .w w是一個四維向量,指明部件i的變形花費函數的參數,參見論文[2010 PAMI]中的公式(2)中的di變量 % .blocklabel 第i個部件的錨點所在的數據塊標識 % model.offsets{i} 第i個組件的偏移量,偏移量數組的長度等於組件個數 % .w 第i個組件的偏移量,是個實數值 % .blocklabel 第i個組件的偏移量所在的數據塊標識 % model.components{i} 第i個組件的信息 % .rootindex 第i個組件的根濾波器的索引,指出組件i的根濾波器在rootfilters[]數組的位置 % .parts{j} 第i個組件的第j個部件的信息 % .partindex 第i個組件的第j個部件的部件濾波器數組索引,指出在partfilters[]數組的位置,注意:全部組件模型的part是連續編號的 % .defindex 第i個組件的第j個部件的錨點坐標數組索引,指出在defs[]數組的位置,注意:全部組件模型的part是連續編號的 % .offsetindex 第i個組件的偏移量的索引,指出在offsets[]數組的位置 % .dim 第i個組件的維數 % .numblocks 第i個組件模型的數據塊個數(須要多少個數據塊來存儲組件模型i),全部組件的numblocks之和等於整個模型的numblocks % 計算此組正樣本典型的高寬比aspect % pick mode of aspect ratios h = [pos(:).y2]' - [pos(:).y1]' + 1; % 全部正樣本的高度數組 w = [pos(:).x2]' - [pos(:).x1]' + 1; % 全部正樣本的寬度數組 xx = -2:.02:2; filter = exp(-[-100:100].^2/400); aspects = hist(log(h./w), xx); aspects = convn(aspects, filter, 'same'); [peak, I] = max(aspects); aspect = exp(xx(I)); % 選擇根濾波器的面積(以像素為單位) % pick 20 percentile area areas = sort(h.*w); % 對面積從小到大排序 area = areas(floor(length(areas) * 0.2)); % 選擇從小到大20%處的面積 area = max(min(area, 5000), 3000); % 面積最大值5000,最小值3000 % 依據以上計算出的高寬比和面積,得到根濾波器的高度和寬度(以像素為單位) % pick dimensions w = sqrt(area/aspect); % 根的寬度(以像素為單位),area=w*h,aspect=h/w,所以area/aspect = (w*h)*(w/h) = w^2 h = w*aspect; % 根的高度(以像素為單位) % HOG cell的尺寸,默覺得8 % size of HOG features if nargin < 4 model.sbin = 8; else model.sbin = sbin; end % 設定根濾波器尺寸(以cell為單位) % size of root filter if nargin < 5 model.rootfilters{1}.size = [round(h/model.sbin) round(w/model.sbin)]; % 以像素為單位的根的尺寸除以cell的尺寸,等於以cell為單位的根的尺寸 else model.rootfilters{1}.size = size; end % 初始化偏移量數組 % 偏移量offset就是加在每一個組件模型的得分公式最后的一個實數值,參見論文[2010 PAMI]中的公式(2)中的b值 model.offsets{1}.w = 0; % 組件1的偏移量的初始值設為0 model.offsets{1}.blocklabel = 1; % 組件1的偏移量的塊標識,值為1表明組件1的偏移量是模型中的第一個數據塊 model.blocksizes(1) = 1; % 第一個數據塊的大小,值為1,由於僅僅用來存儲組件1的偏移量,即一個實數值 model.regmult(1) = 0; model.learnmult(1) = 20; model.lowerbounds{1} = -100; % 第一個數據塊的數據值的下界,-100 % 初始化根濾波器數組 model.rootfilters{1}.w = zeros([model.rootfilters{1}.size 31]); % 組件1的初始根濾波器的向量值為全0 height = model.rootfilters{1}.size(1); % 組件1的根濾波器的高度 % root filter is symmetric 注意:根濾波器是左右對稱的 width = ceil(model.rootfilters{1}.size(2)/2); % 組件1的根濾波器的寬度的一半 model.rootfilters{1}.blocklabel = 2; % 組件1的根濾波器的塊標識 model.blocksizes(2) = width * height * 31; % 存儲組件1的根濾波器的數據塊(第二個數據塊)的大小,由於根濾波器是左右對稱的,所以是h*(w/2)*31 model.regmult(2) = 1; model.learnmult(2) = 1; model.lowerbounds{2} = -100*ones(model.blocksizes(2),1); % 第二個數據塊的值的下界,-100 % 初始化組件模型 % set up one component model model.components{1}.rootindex = 1; % 組件1的根濾波器數組索引 model.components{1}.offsetindex = 1; % 組件1的偏移量數組索引 model.components{1}.parts = {}; % 組件1的部件信息,當前為空 model.components{1}.dim = 2 + model.blocksizes(1) + model.blocksizes(2); % 組件1的模型參數向量維數 model.components{1}.numblocks = 2; % 組件1的數據塊個數 % 初始化剩下的模型參數 % initialize the rest of the model structure model.interval = 10; % 金字塔每組的層數 model.numcomponents = 1; % 模型的組件個數 model.numblocks = 2; % 模型的總的數據塊個數 model.partfilters = {}; % 部件濾波器數組 model.defs = {}; % 部件錨點數組 model.maxsize = model.rootfilters{1}.size; % 全部組件的根濾波器的最大值 model.minsize = model.rootfilters{1}.size; % 全部組件的根濾波器的最小值
相關鏈接
Deformable Part Model 相關網頁:http://www.cs.berkeley.edu/~rbg/latent/index.html
Pedro Felzenszwalb的個人主頁:http://cs.brown.edu/~pff/
PASCAL VOC 目標檢測挑戰:http://pascallin.ecs.soton.ac.uk/challenges/VOC/
A Discriminatively Trained, Multiscale, Deformable Part Model [CVPR 2008] 中文翻譯
Object Detection with Discriminatively Trained Part Based Models [PAMI 2010]中文翻譯
有關可變形部件模型(Deformable Part Model)的一些說明
在Windows下執行Felzenszwalb的Deformable Part Models(voc-release4.01)目標檢測matlab源代碼
在Windows下執行Felzenszwalb的star-cascade DPM(Deformable Part Models)目標檢測Matlab源代碼
在windows下執行Felzenszwalb的Deformable Part Model(DPM)源代碼voc-release3.1來訓練自己的模型
用DPM(Deformable Part Model,voc-release3.1)算法在INRIA數據集上訓練自己的人體檢測模型