matlab人脸和非人脸分割,人脸检测与分割

clear all

close all

clc

%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 读入待检测图像

x= imread('22.jpg');

xx=x;

figure,

imshow(x);

fR=xx(:,:,1);

fG=xx(:,:,2);

fB=xx(:,:,3);

f=1/9*ones(3);%低通滤波器,滤除高频噪声

filtered_fR=imfilter(fR,f);

filtered_fG=imfilter(fG,f);

filtered_fB=imfilter(fB,f);

x_filtered=cat(3,filtered_fR,filtered_fG,filtered_fB);

figure,

imshow(x_filtered);

I=rgb2ycbcr(x);        %颜色空间转换

gray=rgb2gray(x);

figure,

imshow(gray);

[a,b,c]=size(I); %得到图像的像素点个数

cb=double(I(:,:,2));

cr=double(I(:,:,3));

for i=1:a

for j=1:b

w=[cb(i,j),cr(i,j)];

m=[117.4316 148.5599];

n=[260.1301 12.1430;12.1430 150.4574];

p(i,j)=exp((-0.5)*(w-m)*inv(n)*(w-m)');%算某象素点的概率

if (p(i,j)<0.5)

p(i,j)=0;

else

p(i,j)=1;

end

end

end

fenge=p;

figure,

imshow(fenge);

SE = strel('square',3);

imf=imopen(p,SE);         %开运算(即先腐蚀再膨胀),消除杂散点

xingtai=imf;

figure,

imshow(xingtai);

%figure,imshow(Ibwopen);

%Ibwoc=imclose(Ibwopen,SE);      %闭运算,去掉由于开运算引入的许多缺口

%figure,imshow(Ibwoc);

%imf=imfill(Ibwoc,'holes');      %填充孔洞

%%%%%%%%%%%%%%%%%%%%%%%根据填充率去除手脚、胳膊等非人脸区域%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[L,num]=bwlabel(imf,8);     %连通区域标记

B=zeros(size(imf));

for i=1:num

Area(i)=bwarea(L==i);%计算每个皮肤区域的面积

end

for i=1:num

[r,c] = find(L==i) ;

left(i)=min(c);

right(i)=max(c);

up(i)=min(r);

down(i)=max(r);

end

for i=1:num

%计算各矩形区域面积

Rect_Area(i)=(down(i)-up(i))*(right(i)-left(i));

end

%计算各区域的填充率

Ratio=Area./Rect_Area;

for i=1:num

if Ratio(i)>=0.5%若相应区域的填充率大于0.5则保留该区域

[x,y]=find(L==i);%第i块区域的坐标值

B=B+bwselect(imf,y,x,8);%把填充率大于0.5皮肤区域叠加起来

end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%根据面积比来进一步除去一些较小的非人脸区域%%%%%%%%%%%%%%%%%%%%%%%%%%

[L1,num1]=bwlabel(B,8);     %连通区域标记

B1=zeros(size(B));

for i=1:num1

Area(i)=bwarea(L1==i);%计算每个皮肤区域的面积

end

maxarea=max(Area);%取最大值

q=Area/maxarea;%每块区域的面积与最大区域面积的比值

for i=1:num1

if q(i)>=0.3%若相应区域的面积比值大于0.3则保留该区域

[x,y]=find(L1==i);%第i块区域的坐标值

B1=B1+bwselect(B,y,x,8);%把面积比值大于0.3皮肤区域叠加起来

end

end

%%%%%%%%%%%%%%%%%%%%%%%%%%根据肤色区域的长宽比来除去一些非人脸区域%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[L2,num2]=bwlabel(B1,8);     %连通区域标记

B2=zeros(size(B1));

for i=1:num2

[r,c] = find(L2==i);

left(i)=min(c);

right(i)=max(c);

up(i)=min(r);

down(i)=max(r);

end

for i=1:num2

if ((down(i)-up(i))/(right(i)-left(i)))>0.8&((down(i)-up(i))/(right(i)-left(i)))<2

[x,y]=find(L2==i);

B2=B2+bwselect(B1,y,x,8);%%%把满足长宽比在0.8到2的区域留下

end

end

figure,

imshow(xx);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%把人脸框出来%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[L3 num3]=bwlabel(B2,8);     %连通区域标记

for i=1:num3

[r,c] = find(L3==i);

left(i)=min(c);

right(i)=max(c);

up(i)=min(r);

down(i)=max(r);

end

hold on;

for i=1:num3

if(down(i)>(up(i)+(right(i)-left(i))*1.2))     %人脸长宽比限制

down(i)=up(i)+(right(i)-left(i))*1.2;

end

x=[left(i);left(i);right(i);right(i);left(i)];

y=[up(i);down(i);down(i);up(i);up(i)];

plot(x,y);      %画框

end

hold off;

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值