由於能力有限,算法層面的東西自己去創新的很少,很多都是從現有的論文中學習,然后實踐的。
本文涉及的很多算法,在網絡上也有不少同類型的文章,但是肯定的一點就是,很多都是不配代碼的,或者所附帶的代碼都是象征性的,速度慢,不優雅,不具有實用價值,本文努力解決這些問題。
文中各算法出現的順序並不代表算法的優越性,僅僅是作者隨機排布的而已。
2、基於RGB顏色空間的簡單閾值膚色識別
在human skin color clustering for face detection一文中提出如下簡單的判別算式:
R>95 And G>40 And B>20 And R>G And R>B And Max(R,G,B)-Min(R,G,B)>15 And Abs(R-G)>15
算法非常之簡單,同樣主要把復雜的判斷條件放到后面去判斷,能有效的降低程序的執行時間,參考代碼:
for (Y = 0; Y < Height; Y++) { Pointer = Scan0 + Y * Stride; SkinP = SkinScan0 + Y * SkinStride; for (X = 0; X < Width; X++) { Blue = *Pointer; Green = *(Pointer + 1); Red = *(Pointer + 2); if (Red > 95 && Green > 40 && Blue > 20 && Red > Blue && Red > Green && Math.Abs(Red - Green) > 15) { if (Blue >= Green) { Max = Blue; Min = Green; } else { Max = Green; Min = Blue; } if (Red > Max) Max = Red; else if (Red < Min) Min = Red; if (Max - Min > 15) *SkinP = 255; } Pointer += 3; SkinP++; }
算法效果:
原圖 識別結果圖 原圖 識別結果圖
由上述結果似乎該算法得到了過多的皮膚區域,然后就是算法更喜歡美女一些(^_^)。
3、基於YCbCr顏色空間的簡單閾值膚色識別
該算法則更為簡單,將圖像轉換到YCbCr顏色空間,然后按下述計算式判斷是否屬於皮膚區域:
(Cb > 77 And Cb < 127) And (Cr > 133 And Cr < 173)
關於RGB和YCbCr顏色空間的轉換的優化算法,可參考本博客相關文章。
由於當初寫這方面的時候沒有注明該算法的出處,現在也沒從提起了。
代碼參考:
for (Y = 0; Y < Height; Y++) { Pointer = Scan0 + Y * Stride; SkinP = SkinScan0 + Y * SkinStride; for (X = 0; X < Width; X++) { Blue = *Pointer; Green = *(Pointer + 1); Red = *(Pointer + 2); Cb = (-176933 * Red - 347355 * Green + 524288 * Blue + 134217728) >> 20; if (Cb > 77 && Cb < 127) { Cr = (524288 * Red - 439026 * Green - 85262 * Blue + 134217728) >> 20; if (Cr > 133 && Cr < 173) *SkinP = 255; } Pointer += 3; SkinP++; } }
原圖 識別結果圖 原圖 識別結果圖
誤判的區域還是很大的。
還有一種是基於YUV顏色空間進行的膚色識別,似乎也不太准確,可參考http://www.doc88.com/p-97381067005.html。
***************************作者: laviewpbt 時間: 2013.8.17 聯系QQ: 33184777 轉載請保留本行信息*************************