http://blog.csdn.net/xiaowei_cqu/article/details/8216109
Haar特征/矩形特征
Haar特征本身並不復雜,就是用圖中黑色矩形所有像素值的和減去白色矩形所有像素值的和。
看過Rainer Lienhart文章的人知道,Rainer Lienhart在文章中給出了計算特定圖像面積內Haar特征個數公式。小女才拙,到最后也沒推出那個公式來,還望看明白的大牛留言指教~
Haar特征個數計算
Rainer Lienhart計算Haar特征個數的公式:
其中,為圖片大小,
為矩形特征大小,
表示矩形特征在水平和垂直方向的能放大的最大比例系數。
對於45°的rotated特征(如1(c)和1(d)),w,h表示如下圖所示:
其計算公式為:
*論文中沒有說明,個人認為此處除了Z,XY值也有變化:
下面是我理解的計算過程~
首先有兩點要清楚:
1、對於某特定大小的特征,在窗口內滑動計算。
也就是如圖1(a)特征大小為2*1,對於24*24的圖像。水平可滑動23步,垂直滑動24步,所以共有23*24個特征。
2、對於一個特征,特征本身沿水平、豎直方向分別縮放。
還看特征1(a),特征大小為2*1,則延水平方向可放大為:4*1,6*1,8*1,…,24*1;豎直方向可放大為:2*1,2*2,2*3,…,2*24。即每個特征有XY種放大方式。(!放大的矩形特征並限制保持2:1的比例!)
清楚這兩點,就很容易寫出計算特征個數的代碼:
- int getHaarCount(int W,int H,int w,int h){
- int X=W/w;
- int Y=H/h;
- int count=0;
- //放大Haar特征到 iw*jh
- for (int i=1;i<=X;i++)
- for(int j=1;j<=Y;j++)
- //滑動iw*jh矩形,遍歷圖像計算每個位置Haar特征
- for(int x=1;x<=W-i*w+1;x++)
- for(int y=1;y<=H-j*h+1;y++)
- count++;
- return count;
- }
對於45°特征,由於Rainer Lienhart定義的w,h與原矩陣含義不同(參見第一幅圖),即實際滑動的矩陣框為(h+w)*(w+h)。
所以只要用如下方式調用原函數:
- getHaarCount(W,H,h+w,w+h);
當然如果你喜歡寫代碼,也可以寫個新的函數:
- int getRotatedHaarCount(int W,int H,int w,int h){
- int X=W/(w+h);//計算新的X
- int Y=H/(w+h);//計算新的Y
- int count=0;
- for (int i=1;i<=X;i++)
- for(int j=1;j<=Y;j++)
- //注意這里滑動窗口邊界變化
- for(int x=1;x<=W-i*(w+h)+1;x++)
- for(int y=1;y<=H-j*(w+h)+1;y++)
- count++;
- return count;
- }
計算在24*24的圖片中,幾種特征的個數為:
可以看到和論文用公式計算得到的值是一致的~
另一種遞推計算方法:
特征個數雖然很大,但很有規律,不用程序用筆也很容易推出遞推公式。
如1(a)和1(b)特征遞推為:(12^2)*(1+2+...+24)=43,200