人脸识别杂谈和肤色概率建模代码

本文内容出自于《人脸识别原理与实战》

人脸检测只是人脸识别的准备工作。要准确的识别人脸,不仅需要检测到人脸(检测到人脸可采用肤色概率的高斯分布建模方法),而且需要将检测到的人脸与数据存储器的人脸特征进行对比,并在此基础上快速地完成人脸匹配。因此,人脸识别算法的摸索不妨从特征脸建库开始,在人脸检测的基础上进行面部特征定位。眼睛、鼻子和嘴巴的特征是人最主要的三个面部轮廓特征,可作为面部特征定位的着手点。可以用haar-like特征实现面部关键部位检测,将这些关键部位的边缘特征、线性特征、中心特征和对角线特征进行组合,生成特征模板。

具体请参考该博客https://blog.csdn.net/lg1259156776/article/details/48677637#t3

在生成模板的基础上,我们可以借助主成分分析(PCA)建立人的面部模型,这就是特征脸建库了。将一批人脸图像转换成一个特征向量集即可。这些特征向量集被称为“Eigenfaces”,这就是“特征脸”的由来。

特征脸数据库是构建机器学习的基础数据库,主成分分析是一种经典算法,我们比较熟悉其模型原理。虽然从实战而言,我们都不太关注模型细节,但是鉴于特征脸建库的重要性,还是需了解基于主成分分析的人脸识别原理——总的来说就是先将检测到的所有人脸都投影到特征脸子空间,然后通过每张人脸投影点所在的位置及投影线的长度进行判定和识别。

进而初步理解PCA人脸识别算法的核心思想了。

附肤色概率提取人脸轮廓的MATLAB代码

clc
clear all
close all

x=imread('1.jpg');
y=rgb2ycbcr(x);
[a b c]=size(y);
cb=double(y(:,:,2));
cr=double(y(:,:,3));
%% 下面开始计算每个像素点的肤色概率
for i=1:a
    for j=1:b
        w=[cb(i,j) cr(i,j)];%色度矩阵
        m=[110.4516 150.5699];%肤色均值,可以理解成离散高斯分布的期望值
        %这个均值需要提前确定,这个是肤色概率模型的明显不足之处;大家换图片测试,会发现可能需要修改此参数
        n=[97.0916 23.37;23.37 137.9966];%协方差矩阵,对应此处离散高斯分布
        p(i,j)=exp((-0.5)*(w-m)*inv(n)*(w-m)');%计算肤色概率,即相似度
    end
end
z=p./max(max(p));%归一化结果
%下面开始阈值化
%figure
th=0.5;
for i=1:a
    for j=1:b
        if(z(i,j)>th)
            z(i,j)=1;
        else 
            z(i,j)=0;
        end
    end
end
figure;%一边处理一边出图!
subplot(2,2,1);
imshow(z);
title('Set threshold')%阈值化结果

%% 下面做数学形态学处理,先后进行开运算、闭运算、填洞、腐蚀及膨胀操作
se=strel('square',3);
f=imopen(z,se);%开运算
f=imclose(f,se);%闭运算
f=imfill(f,'holes');%填洞
sel=strel('square',8);
%构造结构元素(strel是Structuring element的简写)
f=imerode(f,sel);%腐蚀
f=imdilate(f,sel);%膨胀
%至此得到了一个较纯净的肤色区域

%% 下面尝试将人脸区域与其他肤色区域分割开来
[L,num]=bwlabel(f,4);
%返回一个和f大小相同的L矩阵,包含标记了f中每个连通区域的类别标签,这些标签的值为1,2,...,num(连通区域的个数)
for i=1:num
    [r,c]=find(L==i);%第i个连通区域
    len=max(r)-min(r)+1;%区域长度
    wid=max(c)-min(c)+1;%区域宽度
 	area_sq=len*wid;%区域面积
    area=size(r,1);%区域大小,即像素点的个数
    %开始判定第i个连通区域是不是人脸区域
    for j=1:size(r,1)
        if(len/wid<.8)|(len/wid>2.4)|size(r,1)<200|area/area_sq<0.55
            L(r(j),c(j))=0;%如果不是人脸区域,则通过赋值将其融入背景色
        else
            continue;
        end
    end
end

subplot(2,2,2);
imshow(L);
title('Face Region')%人脸区域显示

w=L&z;
%通过逻辑运算,检测面部特征点;代码开始设置的肤色均值,显然也会影响这个特征点的检测,大家从程序运行结果中也不难看出;请大家试着调整肤色均值,看看运行结果的变化
subplot(2,2,3);
imshow(w);
title('Features points')%人脸特征点显示

%% 开始标记人脸区域,这里用矩形标记,读者也可以尝试用
[r c]=find(L~=0);
r_min=min(r);
r_max=max(r);
c_min=min(c);
c_max=max(c);
subplot(2,2,4);
imshow(x); 
title('Detection result')
rectangle('Position',[c_min r_min c_max-c_min r_max-r_min],'EdgeColor','r');
%以矩形区域为人脸检测的结果


猜你喜欢

转载自blog.csdn.net/lamusique/article/details/79926642