基于膚色和眼睛定位的人臉檢測算法(MATLAB 實現)

jopen 9年前發布 | 69K 次閱讀 圖形/圖像處理 Matlab


本文提出了一種基于膚色信息和眼睛粗略定位的人臉檢測算法。該算法先對 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!

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!