效果圖
閑扯:公司鼓勵創(chuàng)新找田,做了個皮膚檢測器墩衙,本來的想法是用手機外接wifi攝像頭甲抖,用攝像頭來拍攝皮膚圖像的准谚,后來找了幾個wifi攝像頭的廠家氛魁,因價格沒談攏秀存,就不用wifi攝像頭了,只用手機自帶的相機來獲取圖像惫恼。
下面我寫了個 demo 測試祈纯,如下圖
目前實現(xiàn)了皺紋腕窥,油份簇爆,水份的檢測算法入蛆,以后還想實現(xiàn)更多功能哨毁,比如痘痘數(shù)量扼褪,色斑檢測,年齡預測等等举畸。
人臉檢測原理
人臉檢測就是要判斷一張圖像是不是人臉抄沮,以及人臉的位置叛买。
一張大圖像由他的一張很小的子圖像窗口率挣,以一定的倍數(shù)擴大(比如每次擴大 1.2 倍)暴力搜索椒功,最終能確定位置动漾。
判斷一張圖像是不是人臉旱眯,先提取圖像的 haar-like 特征值,交給 adaboost 算法共虑,它能判斷是不是人臉妈拌。
提取圖片的 haar 特征
為什么要提取 haar 特征供炎?
因為要用 adaboost 做分類,整張圖塞進去計算量太大雪位,提取一些主要的特征雹洗,能區(qū)分人臉非人臉就行时肿。怎么提取 haar 特征螃成?
有大牛已經(jīng)給出方法了寸宏,看下面的模板氮凝,把模板放在圖像上望忆,用 白色區(qū)域的灰度和 減去 黑色區(qū)域的灰度和启摄,得到的數(shù)值就是其中一個 haar 特征鞋仍,把模板在圖像上滑動,能計算出一組數(shù)值谎懦,例如(123, 234, -134, ...),這就是圖像的 haar 特征了溃斋。
- 拓展:
圖像區(qū)域快速求和界拦,用積分圖,對原圖像進行一次積分梗劫,就能在O(1)時間算出區(qū)域像素和享甸,大概寫一下。
假設積分圖是 F(x, y)梳侨,求 Rect(x, y, w, h) 區(qū)域和蛉威。
sum = F(x+w, y+h) - F(x+w, y) - F(x, y+h) + F(x, y)
// F(x, y) 表示 Rect(0, 0, x, y) 的區(qū)域和走哺,f(x, y) 表示 (x, y) 灰度級
// 后面加上 + F(x, y) 是因為發(fā)現(xiàn) - F(x+w, y) - F(x, y+h) 減多了重疊的區(qū)域蚯嫌,所以就加回來。
// 生成積分圖的狀態(tài)轉移方程:
F(x, y) = f(x, y) + F(x-1, y) + F(x, y-1) - F(x-1, y-1)
AdaBoost 算法
先來一個感性的認識丙躏。
每來一張圖片择示,提取其特征值 X,用 AdaBoost 算法能判斷出 X 是不是人臉晒旅。
AdaBoost 里面有很多個分類器對特征值 X 進行打分栅盲,分數(shù)有正有負,每個分類器還有個權值废恋,最終把多個分類器給出的分數(shù)乘上他們自身的權值谈秫,全部累加起來,得到一個數(shù)值拴签,如果是正數(shù)孝常,表示屬于 1 類,負數(shù)表示屬于 -1 類蚓哩。
假設 1 類是人臉類构灸,-1 類是非人臉類,就能分出一張圖是不是人臉了岸梨。
分類器可以理解為一個函數(shù) G(x)喜颁,輸入特征值 x,返回數(shù)值 G(x)
AdaBoost 里面有多個弱分類器 (假設3個)曹阔,組合成一個強分類器半开,像這樣
每個弱分類器有權重
再來個sign(n)函數(shù),sign 返回 n 前面的正負號赃份,0和正數(shù)返回 1寂拆,負數(shù)返回 -1
拓展到 n奢米,最終的判斷公式為
輸入一個圖像的特征值 x,看看返回是 1 還是 -1纠永,就可以判斷出是人臉還是非人臉鬓长。
其他:w1, w2, w3 一開始不知道是多少,需要訓練數(shù)據(jù)進行多輪的迭代后算出尝江,訓練過程就是調整權值的過程涉波。訓練完了后,就用這些權值組成的模型炭序,對未知的圖像進行分類啤覆。
具體的例子
有8組包含各種情況的特征值,作為訓練數(shù)據(jù)惭聂。
特征值 x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
類別 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 |
1.初始化 n 組訓練數(shù)據(jù)的權值為 D(i) = 1 / n
所以 1 到 8 的權值為 1 / 8 = 0.125
D = (0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125)
2.多輪迭代
看訓練數(shù)據(jù)
1, 2 屬于 1 類
3, 4, 5 屬于 -1 類
6, 7, 8 屬于 1 類
2 到 3 的時候窗声,由 1 變?yōu)?-1,是一個變化的地方彼妻,設定 x = 2.5嫌佑,意思是在 2.5 的地方切一刀。
5 到 6 由 -1 變?yōu)?1侨歉,又是一個變化點,設定 x = 5.5
下面對 2.5揩魂,5.5 進行迭代
規(guī)則:有一個常數(shù) c幽邓,先認為 x <= c 的元素為 1 類,x > c 的為 -1 類火脉,然后計算有多少個數(shù)據(jù)被分錯的牵舵。
誤差率 e = 分錯的元素的權值和。
如果誤差率 e > 0.5倦挂,則反過來畸颅,認為 x <= c 的為 -1,x > c 的為 1方援。
誤差率寫成公式有點晦澀了没炒,用文字描述比較直觀,就是把被分類器分錯的元素的和權值全部加起來犯戏,就是誤差率了送火。
- 第一輪迭代
x = 2.5 時,先認為 x <= 2.5 為 1 類先匪,x > 2.5 的為 -1 類
那么 6, 7, 8 三個元素被分錯了种吸,每個元素的權值為 0.125。
誤差率為 6, 7, 8 的權值和:0.125 + 0,125 + 0.125 = 0.375呀非。
x = 5.5 時坚俗,先認為 x <= 5.5 為 1镜盯,x > 5.5 為 -1
那么 3, 4, 5, 6, 7, 8 六個元素被分錯。
誤差率為 6 乘 0.125 = 0.75 大于 0.5 了猖败。
那么反過來 x <= 5.5 為 -1速缆,x > 5.5 為 1,此時只有 1, 2 被分錯辙浑。
誤差率為 1, 2 的權值和:0.125 + 0.125 = 0.25激涤。
選個誤差小的 0.25,得出第一個分類器 G1
計算 G1 權重公式:(e 是誤差率)
該函數(shù)圖像:
由圖像可知誤差率 e 越小判呕,w 權值越大倦踢。
G1 的誤差率 e1 = 2 / 8 = 0.25
G1 權重 w1 = 1 / 2 * log (0.75 / 0.25) = 0.23856
w1 就描述了 G1 的重要程度,或者說對一個特征值被分成哪一類的話語權的大小侠草。
接下來要更新以下元素權重:
第一輪:D = (0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125, 0.125)
假設第一輪的 D = (d1, d2, d3, ..., dn)辱挥,是已知的
下一輪的 D = (k1, k2, k3, ..., kn),是要計算的
權重更新公式:
其中常數(shù) Z 是
ki 本輪要計算的元素的權重
di 上一輪已經(jīng)計算出的權重
w 上一輪分類器的權重
G(xi) 上一輪分類器對第 i 個特征的分類結果
yi 第 i 個元素的類別边涕,1 或者 -1
e 自然常數(shù)晤碘,約 2.71828
Z 歸一化用的常數(shù)
按照上面方式,算出新的權重為
D = (0.174721, 0.174721, 0.108426, 0.108426, 0.108426, 0.108426, 0.108426, 0.108426)
可以看出 1, 2 被分錯后功蜓,它的權值增大了园爷,那么如果后面的分類器再把 1, 2 分錯,產生的誤差率會更大式撼,因為誤差率根據(jù)權值和算出的童社,所以權值大的,會被重點考慮著隆。
- 第二輪迭代
x = 2.5 時扰楼,誤差率為 6, 7, 8 權值和:0.325278
x = 5.5 時,誤差率為 1, 2 的權值和:0.349442
選個誤差率小的美浦,即 0.325278弦赖,x = 2.5 的,得出第二個分類器 G2
G2 的誤差率 e2 = 0.325278
G2 權重 w2 = 0.15844
此時浦辨,已經(jīng)得到兩個弱分類器蹬竖,代入 adaboost 算法的公式中
得到模型:
- 測試該模型
特征值 x | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
類別 | 1 | 1 | -1 | -1 | -1 | 1 | 1 | 1 |
G(x) | -1 | -1 | -1 | -1 | -1 | 1 | 1 | 1 |
分析 G(x) 得出的結果,發(fā)現(xiàn) 1荤牍,2 被分錯了案腺,還是有誤差,說明本例子迭代兩次是不夠的康吵,還需要更多輪的迭代劈榨,減小誤差,直到模型 G(x) 在訓練數(shù)據(jù)上的誤差為0晦嵌,再繼續(xù)迭代下去誤差會收斂于一個常數(shù)同辣。(詳見最后的參考文獻)
訓練好了一個誤差很小的模型 G(x)拷姿,就可以用該模型去對未知的圖像進行分類,分為人臉類和非人臉類旱函,即可檢測出一張圖像是不是人臉响巢。
推薦一個在線公式編輯,在線函數(shù)繪圖棒妨。