基于肤色和眼睛定位的人脸检测算法(MATLAB 实现)

jopen 9年前


本文提出了一种基于肤色信息和眼睛粗略定位的人脸检测算法。该算法先对 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!