简单的基于YCrCb颜色空间的人脸检测(肤色)
簡(jiǎn)單的基于YCrCb顏色空間的人臉檢測(cè)(膚色)
環(huán)境:Windows XP+MATLAB 2010b
基本思路:
1)將基于彩色空間的RGB模型轉(zhuǎn)換為YCbCr模型(考慮到人臉的生理特征,只采取了Cr分量作為輔助)
2)閾值分割,根據(jù)多次實(shí)驗(yàn)發(fā)現(xiàn),正常黃種人的Cr分量大約在140~·160之間
3)濾波,本實(shí)驗(yàn)采用性能較好的中值濾波
4)特征區(qū)域提取,利用matlab的bwlabel函數(shù)
5)對(duì)標(biāo)記的特征區(qū)域利用高寬度之比和面積兩個(gè)指數(shù)來(lái)進(jìn)一步簡(jiǎn)化特征區(qū)域
?
具體實(shí)驗(yàn)代碼及原理講解
1)rgb->ycbcr
%公式 Y = 0.2990*R + 0.5780*G + 0.1140*B + 0?
%公式 Cr = 0.5000*R - 0.4187*G - 0.0813*B + 128?
%公式 Cb = -0.1687*R - 0.3313*G + 0.5000*B + 128
(參見(jiàn)http://en.wikipedia.org/wiki/YCbCr)
本實(shí)驗(yàn)直接采用mtalab自帶函數(shù)rgb2ycbcr()轉(zhuǎn)換就OK了。
| I1=imread('blue_lg.jpg'); si=size(I1); m=si(1);n=si(2); img1=rgb2ycbcr(I1); cr1=img1(:,:,3);%大小為mxn的二維矩陣 |
2)閾值分割
| cr3=cr1; for?i=1:m for?j=1:n if(cr3(i,j)>140&&cr3(i,j)<160)%140~160為本人實(shí)驗(yàn)多次得到的合理值 ??????cr3(i,j)=255; else ??????cr3(i,j)=0; end end end |
3)中值濾波器(本實(shí)驗(yàn)采用的是5x5的子模板)
| c_r=cr3; for?i=3:m-2 ????for?j=3:n-2; ????????temp=cr3(i-2:i+2,j-2:j+2);%提取5x5區(qū)域 ????????temp1=sort(temp);%排序 ????????c_r(i,j)=temp1(13);%中值 ????end end |
4)利用bwlabel進(jìn)行特征區(qū)域提取
關(guān)于matlab函數(shù)bwlabel:[L, num] =?bwlabel(BW, n);
根據(jù)領(lǐng)域的鏈接性質(zhì),將整個(gè)區(qū)域分為num個(gè)子區(qū)域,L為一矩陣,其中每個(gè)子區(qū)域在此矩陣中的值為子區(qū)域的序號(hào)。值得注意的是,序號(hào)為0的情況(我理解為背景,直接棄之不用)。n指的是領(lǐng)域性質(zhì),4鄰域or8鄰域。
舉個(gè)例子,
BW = logical ([1 1 1 0 0 0 0 01 1 1 0 1 1 0 01 1 1 0 1 1 0 01 1 1 0 0 0 1 01 1 1 0 0 0 1 01 1 1 0 0 0 1 01 1 1 0 0 1 1 01 1 1 0 0 0 0 0]); 3種背景顏色分別表示3個(gè)子區(qū)域,剩下的即為區(qū)域0,理解為背景吧。 對(duì)應(yīng)生成的L矩陣即為 % L = bwlabel(BW,4);L =1 1 1 0 0 0 0 01 1 1 0 2 2 0 01 1 1 0 2 2 0 01 1 1 0 0 0 3 01 1 1 0 0 0 3 01 1 1 0 0 0 3 01 1 1 0 0 3 3 01 1 1 0 0 0 0 0 (參考mtlab自帶文檔)我的做法是在當(dāng)前路徑下重新定義了一個(gè)子函數(shù)findlimit()。
| function [l,kk]=findlimit(I) %l為已分類(lèi)有序矩陣 %kk為特征區(qū)域的序號(hào) tt=size(size(I)); if?tt(2)==3? %若I為3維矩陣,則需要轉(zhuǎn)換為灰度圖像 ????J=rgb2gray(I); else????????%I為3維矩陣 ????J=I; end %[m,n]=size(J); [l,num]=bwlabel(J,8); area=zeros(1,num+1);%面積 zhonghengbi=zeros(1,num+1);%比例 %re=zeros(num+1,4); re1=zeros(num+1,2); for?k=0:num ????[r,c]= find(l==k); ?????% re(k+1,1)=min(r);???? %垂直方向最小值(上) ?????% re(k+1,2)=max(r);??? %垂直方向最大值(下) ?????% re(k+1,3)=min(c);???? %水平方向最小值(左) ?????% re(k+1,4)=max(c);??? %水平方向最大值(右) ?????re1(k+1,1)=max(r)-min(r);%高度 ?????re1(k+1,2)=max(c)-min(c);%寬度 ?????zhonghengbi(k+1)=re1(k+1,1)/re1(k+1,2);%高寬比 ?????if(re1(k+1,2)==0) zhonghengbi(k+1)=0;end%防止出現(xiàn)單條垂直線的情況 ?????area(k+1)=re1(k+1,1)*re1(k+1,2); end j=1; for?i=1:num+1 ????if?zhonghengbi(i)>0.2&&zhonghengbi(i)<3.0&&area(i)>1000 %高寬比設(shè)置為0.2~3.0之間,面積認(rèn)為大于1000,注意面積為隨機(jī)項(xiàng),與圖片大小有很大的關(guān)系 ???????kk(j)=i-1; ???????j=j+1; ????end end |
5)把特征區(qū)域整個(gè)提取出來(lái)
在此之前定義了一個(gè)判斷序號(hào)是否在提取出的特征區(qū)域內(nèi)的isson()函數(shù),如下:
| function x=isson(y,I) x=0; z=size(I); for?i=1:z(2) ????if(y==I(i)) ????????x=1; ????????break; ????end end |
| [l,kk]=findlimit(c_r); J=l; for?i=1:m ????for?j=1:n ????if(l(i,j)~=0&&isson(l(i,j),kk)==1) ????????J(i,j)=255; ????else ????????J(i,j)=0; ????end ????end end figure;imshow(J,[]); |
然后就可以達(dá)到最后的人臉頭像了。
原始圖像:
處理后
?
2原始圖像
處理后:
?
到這里,本文即將完結(jié),但是可能大家都注意到,許多圖像之中,由于手臂的膚色與人臉一致,以及背景不可避免的顏色巧合,導(dǎo)致最終的效果不是特別理想。
這里主要討論手與臉的區(qū)分問(wèn)題(考慮使用類(lèi)圓相似度來(lái)解決,可能在下一篇中解決,當(dāng)然這是后話)。
?
轉(zhuǎn)載請(qǐng)標(biāo)明http://www.cnblogs.com/blue-lg/archive/2011/12/07/2279879.html
總結(jié)
以上是生活随笔為你收集整理的简单的基于YCrCb颜色空间的人脸检测(肤色)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一种改进的快速人脸检测算法
- 下一篇: 模式识别新研究:微软OCR两层优化提升自