關於DPM(Deformable Part Model)演算法中模型結構的解釋
關於可變部件模型的描述在作者[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和解析降維。
明白了這些,初始化的過程就很容易看懂了,初始化的過程在下面的原始碼上有註釋:
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資料集上訓練自己的人體檢測模型
關於DPM(Deformable Part Model)演算法中模型結構的解釋
相關文章
- 關於DPM(Deformable Part Model)演算法中模型視覺化的解釋ORM演算法模型視覺化
- 在windows下執行Felzenszwalb的Deformable Part Model(DPM)原始碼voc-release3.1來訓練自己的模型WindowsORM原始碼模型
- 用DPM(Deformable Part Model,voc-release3.1)演算法在INRIA資料集上訓練自己的人體檢測模型ORM演算法模型
- 有關可變形部件模型(Deformable Part Model)的一些說明模型ORM
- 在Windows下執行Felzenszwalb的star-cascade DPM(Deformable Part Models)目標檢測Matlab原始碼WindowsORMMatlab原始碼
- 判別訓練的多尺度可變形部件模型 A Discriminatively Trained, Multiscale, Deformable Part Model模型AIORM
- DPM演算法演算法
- 關於Web開發中的“程式=資料結構+演算法”Web資料結構演算法
- 關於Web開發中“程式=資料結構+演算法”的思考Web資料結構演算法
- 轉 關於shell中if 語法結構的廣泛誤解
- 關於暴露業務模型(Exposed Domain Model Pattern)2模型AI
- 關於暴露業務模型(Exposed Domain Model Pattern)1模型AI
- 關於FFMPEG的解碼模型模型
- 關於若干選舉演算法的解釋與實現演算法
- 那些關於前端資料結構與演算法前端資料結構演算法
- 關於jdonframework-6.2.2中ModelUtil.isModel ()疑問Framework
- 專案中關於解構的常用用法
- 在Windows下執行Felzenszwalb的Deformable Part Models(voc-release4.01)目標檢測matlab原始碼WindowsORMMatlab原始碼
- 關於盒子模型的BFC總結模型
- jvm結構解釋JVM
- Linux上glibc的man手冊關於timeval結構解釋的錯誤(轉)Linux
- 關於三層架構中各層次的關係與實現模型 (轉)架構模型
- Oracle11gRAC中關於srvctl和crsctl的解釋?Oracle
- Google釋出pQRNN新NLP模型:基於投影的高效模型架構GoRNN模型架構
- 關於資料結構資料結構
- 關於培訓結構
- 關於微機結構
- Android架構元件:用ViewModelCommandLiveData處理ViewModel中的事件釋出Android架構元件ViewLiveData事件
- x86架構中的外部中斷結構-Part 1:中斷控制器的演化架構
- Laravel Database——Eloquent Model 更新關聯模型LaravelDatabase模型
- 關於elementUI樹狀結構的bugUI
- 關於Mysql索引的資料結構MySql索引資料結構
- 關於 Go 程式碼結構的思考Go
- css關於/deep/的解釋和用法CSS
- goldengate關於pump程式的解釋Go
- Nancy之ModelBinding(模型繫結)NaN模型
- 解說pytorch中的model=model.to(device)PyTorchdev
- 關於OracleRac體系結構Oracle