基于眼睛和皮肤的定位


本文提出了一种基于肤色信息和眼睛粗略定位的人脸检测算法。该算法先对 Anil K.Jain 的 Cb 、 Cr 椭圆聚类方法进行了改进,用改进的算法进行肤色提取,经过肤色区域的分析,对人脸区域进行预检测,确定人脸可能区域,然后再根据眼睛的粗略定位进一步确定人脸区域。
一、肤色分析(skin.m)

Anil K.Jain提出的基于YCbCr颜色空间的肤色模型,根据当前点的Cb Cr值判断是否为肤色。

% Anil K.Jain提出的基于YCbCr颜色空间的肤色模型
% 根据当前点的Cb Cr值判断是否为肤色
function result = skin(Y,Cb,Cr)
% 参数
a = 25.39;
b = 14.03;
ecx = 1.60;
ecy = 2.41;
sita = 2.53;
cx = 109.38;
cy = 152.02;
xishu = [cos(sita) sin(sita);-sin(sita) cos(sita)];
% 如果亮度大于230,则将长短轴同时扩大为原来的1.1倍
if(Y > 230)
	a = 1.1*a;
	b = 1.1*b;
end
% 根据公式进行计算
Cb = double(Cb);
Cr = double(Cr);
t = [(Cb-cx);(Cr-cy)];
temp = xishu*t;
value = (temp(1) - ecx)^2/a^2 + (temp(2) - ecy)^2/b^2;
% 大于1则不是肤色,返回0;否则为肤色,返回1
if value > 1
	result = 0;
else
	result = 1;
end
二、眼睛粗略定位(findeye.m)
% 判断二值图像中是否含有可能是眼睛的块
%   bImage----二值图像
%   x---------矩形左上角顶点X坐标
%   y---------矩形左上角顶点Y坐标
%   w---------矩形宽度
%   h---------矩形长度
% 如果有则返回值eye等于1,否则为0
function eye = findeye(bImage,x,y,w,h)
% 根据矩形相关属性得到二值图像中矩形区域中的数据
% 存放矩形区域二值图像信息
part = zeros(h,w);
% 二值化
for i = y:(y+h)
	for j = x:(x+w)
		if bImage(i,j) == 0
			part(i-y+1,j-x+1) = 255;
		else
			part(i-y+1,j-x+1) = 0;
		end
	end
end
[L,num] = bwlabel(part,8);
% 如果区域中有两个以上的矩形则认为有眼睛
if num < 2
	eye = 0;
else
	eye = 1;
end
三、人脸检测(facedetection.m)
function facedetection(img_name)
% 读取RGB图像
I = imread(img_name);
% 转换为灰度图像
gray = rgb2gray(I);
% 将图像转化为YCbCr颜色空间
YCbCr = rgb2ycbcr(I);
% 获得图像宽度和高度
heigth = size(gray,1);
width = size(gray,2);
% 根据肤色模型将图像二值化
for i = 1:heigth
	for j = 1:width
		Y = YCbCr(i,j,1);
		Cb = YCbCr(i,j,2);
		Cr = YCbCr(i,j,3);
		if(Y < 80)
			gray(i,j) = 0;
		else
			if(skin(Y,Cb,Cr) == 1)
				gray(i,j) = 255;
			else
				gray(i,j) = 0;
			end
		end
	end
end
% 二值图像形态学处理
SE=strel('arbitrary',eye(5));  
%gray = bwmorph(gray,'erode');
% imopen先腐蚀再膨胀
gray = imopen(gray,SE);
% imclose先膨胀再腐蚀
%gray = imclose(gray,SE);
imshow(gray);
% 取出图片中所有包含白色区域的最小矩形
[L,num] = bwlabel(gray,8);
STATS = regionprops(L,'BoundingBox');
% 存放经过筛选以后得到的所有矩形块
n = 1;
result = zeros(n,4);
figure,imshow(I);
hold on;
for i = 1:num
	box = STATS(i).BoundingBox;
	x = box(1);	%矩形坐标x
	y = box(2);	%矩形坐标y
	w = box(3);	%矩形宽度w
	h = box(4);	%矩形高度h
	% 宽度和高度的比例
	ratio = h/w;
	ux = uint8(x);
	uy = uint8(y);
	if ux > 1
		ux = ux - 1;
	end
	if uy > 1
		uy = uy - 1;
	end
	% 可能是人脸区域的矩形应满足以下条件:
	%   1、高度和宽度必须都大于20,且矩形面积大于400
	%   2、高度和宽度比率应该在范围(0.6,2)内
	%   3、函数findeye返回值为1
	if w < 20 || h < 20 || w*h < 400
		continue
	elseif ratio < 2 && ratio > 0.6 && findeye(gray,ux,uy,w,h) == 1
		% 记录可能为人脸的矩形区域
		result(n,:) = [ux uy w h];
		n = n+1;
	end
end
% 对可能是人脸的区域进行标记
if  size(result,1) == 1 && result(1,1) > 0
	rectangle('Position',[result(1,1),result(1,2),result(1,3),result(1,4)],'EdgeColor','r');
else
	% 如果满足条件的矩形区域大于1则再根据其他信息进行筛选
	for m = 1:size(result,1)
		m1 = result(m,1);
		m2 = result(m,2);
		m3 = result(m,3);
		m4 = result(m,4);
		% 标记最终的人脸区域
		if m1 + m3 < width && m2 + m4 < heigth
			rectangle('Position',[m1,m2,m3,m4],'EdgeColor','r');
		end
	end
end
四、主函数(main.m)
%清理窗口
close all
clear all
clc
% 输入图像名字
img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s');
% 当输入0时结束
while ~strcmp(img_name,'0')
    % 进行人脸识别
    facedetection(img_name);
    img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s');
end

PS:这篇文章是在之前的Blog中写的,最近又用到MatLab,所以将它挪到了这里。。

Over!
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值