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


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

一、肤色分析(skin.m)

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

  1. % Anil K.Jain提出的基于YCbCr颜色空间的肤色模型  
  2. % 根据当前点的Cb Cr值判断是否为肤色  
  3. function result = skin(Y,Cb,Cr)  
  4. % 参数  
  5. a = 25.39;  
  6. b = 14.03;  
  7. ecx = 1.60;  
  8. ecy = 2.41;  
  9. sita = 2.53;  
  10. cx = 109.38;  
  11. cy = 152.02;  
  12. xishu = [cos(sita) sin(sita);-sin(sita) cos(sita)];  
  13. % 如果亮度大于230,则将长短轴同时扩大为原来的1.1倍  
  14. if(Y > 230)  
  15.     a = 1.1*a;  
  16.     b = 1.1*b;  
  17. end  
  18. % 根据公式进行计算  
  19. Cb = double(Cb);  
  20. Cr = double(Cr);  
  21. t = [(Cb-cx);(Cr-cy)];  
  22. temp = xishu*t;  
  23. value = (temp(1) - ecx)^2/a^2 + (temp(2) - ecy)^2/b^2;  
  24. % 大于1则不是肤色,返回0;否则为肤色,返回1  
  25. if value > 1  
  26.     result = 0;  
  27. else  
  28.     result = 1;  
  29. end   

二、眼睛粗略定位(findeye.m)

  1. % 判断二值图像中是否含有可能是眼睛的块  
  2. %   bImage----二值图像  
  3. %   x---------矩形左上角顶点X坐标  
  4. %   y---------矩形左上角顶点Y坐标  
  5. %   w---------矩形宽度  
  6. %   h---------矩形长度  
  7. % 如果有则返回值eye等于1,否则为0  
  8. function eye = findeye(bImage,x,y,w,h)  
  9. % 根据矩形相关属性得到二值图像中矩形区域中的数据  
  10. % 存放矩形区域二值图像信息  
  11. part = zeros(h,w);  
  12. % 二值化  
  13. for i = y:(y+h)  
  14.     for j = x:(x+w)  
  15.         if bImage(i,j) == 0  
  16.             part(i-y+1,j-x+1) = 255;  
  17.         else  
  18.             part(i-y+1,j-x+1) = 0;  
  19.         end  
  20.     end  
  21. end  
  22. [L,num] = bwlabel(part,8);  
  23. % 如果区域中有两个以上的矩形则认为有眼睛  
  24. if num < 2  
  25.     eye = 0;  
  26. else  
  27.     eye = 1;  
  28. end   

三、人脸检测(facedetection.m)

  1. function facedetection(img_name)  
  2. % 读取RGB图像  
  3. I = imread(img_name);  
  4. % 转换为灰度图像  
  5. gray = rgb2gray(I);  
  6. % 将图像转化为YCbCr颜色空间  
  7. YCbCr = rgb2ycbcr(I);  
  8. % 获得图像宽度和高度  
  9. heigth = size(gray,1);  
  10. width = size(gray,2);  
  11. % 根据肤色模型将图像二值化  
  12. for i = 1:heigth  
  13.     for j = 1:width  
  14.         Y = YCbCr(i,j,1);  
  15.         Cb = YCbCr(i,j,2);  
  16.         Cr = YCbCr(i,j,3);  
  17.         if(Y < 80)  
  18.             gray(i,j) = 0;  
  19.         else  
  20.             if(skin(Y,Cb,Cr) == 1)  
  21.                 gray(i,j) = 255;  
  22.             else  
  23.                 gray(i,j) = 0;  
  24.             end  
  25.         end  
  26.     end  
  27. end  
  28. % 二值图像形态学处理  
  29. SE=strel('arbitrary',eye(5));    
  30. %gray = bwmorph(gray,'erode');  
  31. % imopen先腐蚀再膨胀  
  32. gray = imopen(gray,SE);  
  33. % imclose先膨胀再腐蚀  
  34. %gray = imclose(gray,SE);  
  35. imshow(gray);  
  36. % 取出图片中所有包含白色区域的最小矩形  
  37. [L,num] = bwlabel(gray,8);  
  38. STATS = regionprops(L,'BoundingBox');  
  39. % 存放经过筛选以后得到的所有矩形块  
  40. n = 1;  
  41. result = zeros(n,4);  
  42. figure,imshow(I);  
  43. hold on;  
  44. for i = 1:num  
  45.     box = STATS(i).BoundingBox;  
  46.     x = box(1);    %矩形坐标x  
  47.     y = box(2);    %矩形坐标y  
  48.     w = box(3);    %矩形宽度w  
  49.     h = box(4);    %矩形高度h  
  50.     % 宽度和高度的比例  
  51.     ratio = h/w;  
  52.     ux = uint8(x);  
  53.     uy = uint8(y);  
  54.     if ux > 1  
  55.         ux = ux - 1;  
  56.     end  
  57.     if uy > 1  
  58.         uy = uy - 1;  
  59.     end  
  60.     % 可能是人脸区域的矩形应满足以下条件:  
  61.     %   1、高度和宽度必须都大于20,且矩形面积大于400  
  62.     %   2、高度和宽度比率应该在范围(0.6,2)内  
  63.     %   3、函数findeye返回值为1  
  64.     if w < 20 || h < 20 || w*h < 400  
  65.         continue  
  66.     elseif ratio < 2 && ratio > 0.6 && findeye(gray,ux,uy,w,h) == 1  
  67.         % 记录可能为人脸的矩形区域  
  68.         result(n,:) = [ux uy w h];  
  69.         n = n+1;  
  70.     end  
  71. end  
  72. % 对可能是人脸的区域进行标记  
  73. if  size(result,1) == 1 && result(1,1) > 0  
  74.     rectangle('Position',[result(1,1),result(1,2),result(1,3),result(1,4)],'EdgeColor','r');  
  75. else  
  76.     % 如果满足条件的矩形区域大于1则再根据其他信息进行筛选  
  77.     for m = 1:size(result,1)  
  78.         m1 = result(m,1);  
  79.         m2 = result(m,2);  
  80.         m3 = result(m,3);  
  81.         m4 = result(m,4);  
  82.         % 标记最终的人脸区域  
  83.         if m1 + m3 < width && m2 + m4 < heigth  
  84.             rectangle('Position',[m1,m2,m3,m4],'EdgeColor','r');  
  85.         end  
  86.     end  
  87. end   

四、主函数(main.m)

  1. %清理窗口  
  2. close all  
  3. clear all  
  4. clc  
  5. % 输入图像名字  
  6. img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s');  
  7. % 当输入0时结束  
  8. while ~strcmp(img_name,'0')  
  9.     % 进行人脸识别  
  10.     facedetection(img_name);  
  11.     img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s');  
  12. end  

相关内容