MSER代碼編譯:
matlabroot
%如果是VS2010則解壓VS2010MEX支持文件到MATLAB根目錄
unzip(
'E:\Software\develop Tools\VS2010MEXSupport.zip'
,matlabroot)
mex
-setup
%設置代碼文件夾編譯路徑
cd(
'E:\Koder Quelle\Image process Package\mser-0.5'
)
mser_compile
%生成PDB文件供調試用
mex
-g
mser.mex.c
-output
'mser.mex.pdb'
%編譯MEX文件
mex
-g
mser.mex.c
-output
'mser'
mex
-g
erfill.mex.c
-output
'erfill'
MSER的原理介紹:
圖像I為一個映射

1. S是全序的,例如存在滿足自反性,反對稱性和傳遞性的二元關系“小於等於”。論文里考慮到的范圍僅是S={0,1,2,...,255},但是極值區域可以被定義在實值圖像上(S=R)。
2.鄰域關系的定義為
(
備注,這里集合的乘積為笛卡爾積),這里只用到了4鄰域,例如
是相鄰的(用
表示),那么當且僅當滿足
的時候它們才是鄰域關系。





區域Q是D的連續子集,例如 對每個
這里存在一個序列
並且



這個性質表示區域Q為單連通的。
區域的邊界(外部的)
,例如Q的邊界
是這樣一個像素集合,它至少有一個像素是屬於Q的鄰域像素但是不屬於區域Q。


極值區域
是這樣的一個區域:對於所有
[
最大亮度區域]或者
[
最小亮度區域]。



最大穩定極值區域(MSER)。令
為嵌套的極值區域,例如
,當且僅當
在
時存在局部最小值,極值區域
才是最大穩定的(|.|表示集合的勢,對於離散圖像來說就是像素面積),
屬於方法參數






Component Tree原理
當前元素和所有周圍鄰近當前區域的元素並且小於當前元素的區域都屬於該區域
從最小值
Xi
像素開始建立一個region,如果Xi的鄰域亮度值等於該像素的亮度值,則將
Xi
合並進
鄰域像素
所在的region(且父節點是鄰域像素父節點),如果Xi鄰域的像素值小於Xi的像素值,則將鄰域像素歸入當前region,並將當前region作為鄰域像素region的根節點(
且鄰域像素父節點指向當前像素的父節點
),直到遍歷完所有像素為止。
Component Tree 代碼解讀:
4 4 4 4 4 4 4
4 2 2 4 2 1 4
4 2 2 4 1 2 4
4 3 3 4 3 3 4
4 2 2 4 4 3 4
4 1 1 2 4 3 4
4 4 4 4 4 4 4
4 2 2 4 2 1 4
4 2 2 4 1 2 4
4 3 3 4 3 3 4
4 2 2 4 4 3 4
4 1 1 2 4 3 4
4 4 4 4 4 4 4
Extremal regions: 8
ner: 0. value:1,area: 2, parent: 3
ner: 1. value:1,area: 2, parent: 4
ner: 2. value:2,area: 4, parent: 5
ner: 3. value:2,area: 5, parent: 5
ner: 4. value:2,area: 4, parent: 6
ner: 5. value:3,area: 11, parent: 7
ner: 6. value:3,area: 8, parent: 7
ner: 7. value:4,area: 49, parent: 7
ner: 0. value:1,area: 2, parent: 3
ner: 1. value:1,area: 2, parent: 4
ner: 2. value:2,area: 4, parent: 5
ner: 3. value:2,area: 5, parent: 5
ner: 4. value:2,area: 4, parent: 6
ner: 5. value:3,area: 11, parent: 7
ner: 6. value:3,area: 8, parent: 7
ner: 7. value:4,area: 49, parent: 7
從像素值是1的像素開始:
節點0,1屬於節點3
節點2,3屬於節點5
節點4屬於節點6
節點5,6屬於節點7
反之則有:
1 1 1 1 1 1 1
1 3 3 2 3 4 1
1 3 3 2 3 4 1
1 1 1 1 1 3 1
1 3 4 2 1 1 1
1 4 3 2 2 2 1
1 1 1 1 1 1 1
1 3 3 2 3 4 1
1 3 3 2 3 4 1
1 1 1 1 1 3 1
1 3 4 2 1 1 1
1 4 3 2 2 2 1
1 1 1 1 1 1 1
ner: 0. value:1,area: 30, parent: 1
ner: 1. value:2,area: 36, parent: 2
ner: 2. value:3,area: 45, parent: 3
ner: 3. value:4,area: 49, parent: 3
ner: 1. value:2,area: 36, parent: 2
ner: 2. value:3,area: 45, parent: 3
ner: 3. value:4,area: 49, parent: 3
從像素值是1的像素開始,剛開始只有節點0一個區域,將像素2的區域並入0后形成節點1,將像素3並入節點1后形成節點2,最后全部合並形成整個區域作為父節點.
Component Tree的步驟:
1.在計算開始之前首先對所有像素按照亮度大小進行排序。
2.
for (i = 0; i < pixel_numbers; i++)
{
1.彈出當前像素的索引和值
2.將鄰結點的索引指向當前索引
3.將當前像素結點插入到樹中
4.while(依次處理以該像素為中心的8鄰域像素)
{
a.鄰域像素在圖像邊界以內
b.鄰域像素不是自身
c.鄰域像素已經在樹中了,也就是說這個像素已經被處理過了
if(滿足a,b,c)
{
1.將當前此節點,以及當前此節點的上一層父節點,..., 直到根節點的所有鏈路節點的shortcut都置為根節點
2.將此鄰域節點,以及此鄰域節點的上一層父節點,..., 直到根節點的所有鏈路節點的shortcut都置為根節點
i. 如果當前節點的根節點等於鄰域像素的根節點,這種情況下兩個樹已經加入了同一個樹當中了
ii. 如果當前節點的根節點的亮度等於鄰域像素的根節點的亮度,此種情況索引將被擴展到具有相同亮度的一個極值區域,因為鄰域像素的根節點不會是整個圖像的一個極值區域;當前索引的根節點能夠安全的被添加到鄰域像素的根節點作為鄰域像素的孩子結點。
iii.如果當前節點的根節點的亮度大於鄰域像素的根節點的亮度並且當前節點是一個極值區域,這時僅僅增加它的層數。這種情況下鄰域像素根節點將會是最終整個圖像的一個極值區域並且只有唯一的可能性作為添加到當前像素所屬的樹中當前像素的孩子
}
}
}
{
1.彈出當前像素的索引和值
2.將鄰結點的索引指向當前索引
3.將當前像素結點插入到樹中
4.while(依次處理以該像素為中心的8鄰域像素)
{
a.鄰域像素在圖像邊界以內
b.鄰域像素不是自身
c.鄰域像素已經在樹中了,也就是說這個像素已經被處理過了
if(滿足a,b,c)
{
1.將當前此節點,以及當前此節點的上一層父節點,..., 直到根節點的所有鏈路節點的shortcut都置為根節點
2.將此鄰域節點,以及此鄰域節點的上一層父節點,..., 直到根節點的所有鏈路節點的shortcut都置為根節點
i. 如果當前節點的根節點等於鄰域像素的根節點,這種情況下兩個樹已經加入了同一個樹當中了
ii. 如果當前節點的根節點的亮度等於鄰域像素的根節點的亮度,此種情況索引將被擴展到具有相同亮度的一個極值區域,因為鄰域像素的根節點不會是整個圖像的一個極值區域;當前索引的根節點能夠安全的被添加到鄰域像素的根節點作為鄰域像素的孩子結點。
iii.如果當前節點的根節點的亮度大於鄰域像素的根節點的亮度並且當前節點是一個極值區域,這時僅僅增加它的層數。這種情況下鄰域像素根節點將會是最終整個圖像的一個極值區域並且只有唯一的可能性作為添加到當前像素所屬的樹中當前像素的孩子
}
}
}
MSER區域的橢圓擬合(注意! 這里是二值圖像):


X,X correlation[X,X]
X,Y correlation[X,Y]
Y,Y correlation[Y,Y]








其中E(x),E(y)分別為擬合橢圓的中心點坐標,D(x),D(y),COV(x,y)分別為該區域內所有點的橫坐標方差,縱坐標方差和橫縱坐標協方差
橢圓擬合的代碼:
1 /* ----------------------------------------------------------------- 2 * Fit ellipses 3 * -------------------------------------------------------------- */ 4 ell_pt = 0 ; 5 if (nout >= 1) { 6 int midx = 1 ; 7 int d, index, j ; 8 9 verbose && mexPrintf("Fitting ellipses...\n") ; 10 11 /* enumerate maxstable regions */ 12 for(i = 0 ; i < ner ; ++i) { 13 if(! regions_pt [i].maxstable) continue ; 14 regions_pt [i].maxstable = midx++ ; 15 } 16 17 /* allocate space */ 18 acc_pt = mxMalloc(sizeof(acc_t) * nel) ; 19 ell_pt = mxMalloc(sizeof(acc_t) * gdl * nmer) ; 20 21 /* clear accumulators */ 22 memset(ell_pt, 0, sizeof(int) * gdl * nmer) ; 23 for(index = 0 ; index < nel ; ++ index){ 24 mexPrintf("%d\t",joins_pt[index]) ; 25 if( 0 == (index+1)%dims[0]) mexPrintf("\n"); 26 } 27 28 for(index = 0 ; index < nel ; ++ index){ 29 mexPrintf("%d\t",forest_pt [ index ].parent) ; 30 if( 0 == (index+1)%dims[0]) mexPrintf("\n"); 31 } 32 33 /* for each gdl */ 34 for(d = 0 ; d < gdl ; ++d) { 35 /* initalize parameter */ 36 memset(subs_pt, 0, sizeof(int) * ndims) ; 37 38 //注意這里的0和1下標不是0階矩和1階矩,而是表示X和Y之間的均值,相關系數 39 //例如(0,0)表示corr(X,X), (0,1)表示corr(X,Y),(1,0)表示corr(Y,X),(1,1)表示corr(Y,Y)不要搞混!!! by frisch 40 if(d < ndims) { 41 //圖像每個像素的行[0], 列坐標[1]坐標, x方向和y方向的均值,by frisch 42 verbose && mexPrintf(" mean %d\n",d) ; 43 for(index = 0 ; index < nel ; ++ index) { 44 acc_pt[index] = subs_pt[d] ; 45 adv(dims, ndims, subs_pt) ; 46 47 } 48 49 } else { 50 51 //圖像每個像素的行[0], 列坐標[1]的相關度計算, by frisch 52 //corr[0,0](行與行), corr[1,0](行與列), corr[0,1](列與行), corr[1,1](列與列), by frisch 53 /* decode d-ndims into a (i,j) pair */ 54 i = d-ndims ; 55 j = 0 ; 56 while(i > j) { 57 i -= j + 1 ; 58 j ++ ; 59 } 60 61 verbose && mexPrintf(" corr (%d,%d)\n",i,j) ; 62 63 /* add x_i * x_j */ 64 //計算相關值,將其放入二維數組 65 for(index = 0 ; index < nel ; ++ index){ 66 acc_pt[index] = subs_pt[i]*subs_pt[j] ; 67 mexPrintf("(%d\t%d\t)",subs_pt[i],subs_pt[j]) ; 68 if( 0 == (index+1)%dims[0]) mexPrintf("\n"); 69 adv(dims, ndims, subs_pt) ; 70 } 71 } 72 73 for(index = 0 ; index < nel ; ++ index){ 74 mexPrintf("%d\t",acc_pt[index]) ; 75 if( 0 == (index+1)%dims[0]) mexPrintf("\n"); 76 } 77 78 /* integrate parameter */ 79 //對每個區域進行均值或者相關值積分,by frisch 80 for(i = 0 ; i < njoins ; ++i) { 81 idx_t index = joins_pt[i] ; 82 idx_t parent = forest_pt [ index ].parent ; 83 acc_pt[parent] += acc_pt[index] ; 84 } 85 86 /* save back to ellpises */ 87 //保存橢圓參數, 五個參數(包含橢圓的中心點,長短軸幅值,方向向量) by frisch 88 for(i = 0 ; i < ner ; ++i) { 89 idx_t region = regions_pt [i].maxstable ; 90 91 /* skip if not extremal region */ 92 if(region-- == 0) continue ; 93 ell_pt [d + gdl*region] = acc_pt [ regions_pt[i].index ] ; 94 } 95 96 /* next gdl */ 97 } 98 mxFree(acc_pt) ; 99 }
reference:
橢圓擬合部分參考《多通道圖像MSER局部不變特征》 國防科技大學,柳濤